Merge remote-tracking branch 'origin/master' into feature/directory-listing-tool
Master had advanced 392 commits. Every conflict was a derived artifact both
sides had regenerated — `docs/tool-catalog.md`, four recorded headless
session logs, and one TUI terminal expectation — so each was resolved by
taking master's version and re-running the generator and the keyless
snapshot refresh on the merged tree. No source file conflicted.
The new `examples/jsonrpc-agent` fixtures keep master's scrubbed
`{{system}}` / `{{tools}}` headers: that suite scrubs request headers, so a
new tool changes nothing there and the refresh output was discarded.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
README.md: 8fd261e624771dc568582b6d22e9985072a06715
|
||||
README.zh.md: 2ff0d0bef382435588fce01c23aa7b74e1a149b5
|
||||
# pnpm run verify-translation-pairing --write examples/README.md
|
||||
README.md: 7f12178d1b67f1ebfac6f4f0e31403c54106e98f
|
||||
README.zh.md: 72ab92602d0a53cabdbfa8bc34838061df25d1c7
|
||||
|
||||
@@ -22,9 +22,9 @@ An unattended coding agent driven through the Python SDK: JSON-RPC stdio, foregr
|
||||
|
||||
## cordis-agent
|
||||
|
||||
The **self-referential** demo: the coding spine plus [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis), whose three tools (`cordis_inspect` / `cordis_mount` / `cordis_unmount`) let the agent inspect the live cordis runtime it runs inside, mount model-written plugins into it (an event listener, a brand-new tool for itself, or a service another mount injects), and dispose them again — all dynamic mounts grouped under one `cordis-dynamic` fiber subtree. The `ctx.fs`/`ctx.web` services ride along provider-only, as the capabilities those plugins build on.
|
||||
The **self-referential** demo: the coding spine plus [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis), whose three tools (`cordis_inspect` / `cordis_mount` / `cordis_unmount`) let the agent inspect the current DSH process, mount model-written temporary Plugins (an event listener, a brand-new tool, or a service another temporary Plugin injects), and unmount them again. These Plugins exist only in memory and share one internal `cordis-dynamic` fiber subtree; `ctx.fs`/`ctx.web` ride along provider-only as capabilities they can use.
|
||||
|
||||
Run with: `pnpm run demo:cordis` (needs `DEEPSEEK_API_KEY`). See [cordis-agent/README.md](cordis-agent/README.md) for the staged demo script and [the toolset Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) for the design and sandbox caveats.
|
||||
Run the TUI with `pnpm run demo:cordis`, the browser UI at `http://127.0.0.1:3081` with `pnpm run demo:cordis web`, or the ACP server with `pnpm run demo:cordis acp` (all need `DEEPSEEK_API_KEY`). See [cordis-agent/README.md](cordis-agent/README.md) for the staged demo script and [the toolset Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) for the design and sandbox caveats.
|
||||
|
||||
## acp-agent
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
## cordis-agent
|
||||
|
||||
**自指** 演示:编码主干加 [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis),其三个工具(`cordis_inspect`/`cordis_mount`/`cordis_unmount`)使 agent 可以检查自身所在的实时 cordis 运行时,将模型编写的插件挂载到其中(事件监听器、一个专为自身创建的全新工具,或一个供另一挂载项注入的服务),并再次释放它们。所有动态挂载都归入同一 `cordis-dynamic` fiber 子树。`ctx.fs`/`ctx.web` 服务仅作为提供方随行,是这些插件构建所依赖的能力。
|
||||
**自指** 演示:编码主干加 [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis),其三个工具(`cordis_inspect`/`cordis_mount`/`cordis_unmount`)使 agent 可以检查当前 DSH 进程、挂载模型编写的临时 Plugin(事件监听器、一个全新工具,或一个供另一临时 Plugin 注入的服务),并再次卸载它们。这些 Plugin 只存在于内存中,共享一个内部 `cordis-dynamic` fiber 子树;`ctx.fs`/`ctx.web` 仅作为它们可用的能力提供方。
|
||||
|
||||
运行:`pnpm run demo:cordis`(需要 `DEEPSEEK_API_KEY`)。分阶段演示脚本详见 [cordis-agent/README.md](cordis-agent/README.md),设计与沙箱注意事项详见[工具集 Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
使用 `pnpm run demo:cordis` 运行 TUI,使用 `pnpm run demo:cordis web` 在 `http://127.0.0.1:3081` 启动浏览器 UI,或使用 `pnpm run demo:cordis acp` 启动 ACP 服务器(三者均需 `DEEPSEEK_API_KEY`)。分阶段演示脚本详见 [cordis-agent/README.md](cordis-agent/README.md),设计与沙箱注意事项详见[工具集 Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
|
||||
## acp-agent
|
||||
|
||||
|
||||
10
examples/acp-agent/cordis-tools.cordis.yml
Normal file
10
examples/acp-agent/cordis-tools.cordis.yml
Normal file
@@ -0,0 +1,10 @@
|
||||
# Add the self-referential Cordis tools without changing the base ACP tool
|
||||
# presentation mode.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- insert:
|
||||
- id: tool-cordis
|
||||
name: '@deepseek-ai/dsh-tool-cordis'
|
||||
@@ -14,6 +14,7 @@
|
||||
pollIntervalMs: 10
|
||||
exactProbeAfterMs: 20
|
||||
idleSilenceMs: 250
|
||||
handoffGraceMs: 250
|
||||
timeoutMs: 2000
|
||||
disposeGraceMs: 500
|
||||
- id: tool-pty
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# Keyless replay for the retry overlay: disable the key-requiring DeepSeek
|
||||
# adapter, insert `llm-replay`, and restate the app config with the same
|
||||
# deterministic 1 ms zero-jitter retry policy as the live sibling. A config
|
||||
# patch replaces the whole app config, so the base fields are restated
|
||||
# verbatim (raw JSONL persistence so the harness can harvest the log).
|
||||
# adapter, insert `llm-replay`, and give its provider the same deterministic
|
||||
# 1 ms zero-jitter retry policy as the live sibling. The app patch still
|
||||
# restates its whole config for raw JSONL persistence and the recorded model.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
@@ -20,11 +19,6 @@
|
||||
persistenceCompression: none
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
llmRetry:
|
||||
maxTransientRetries: 2
|
||||
initialDelayMs: 1
|
||||
maxDelayMs: 1
|
||||
jitterRatio: 0
|
||||
persona: |
|
||||
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
|
||||
|
||||
@@ -36,6 +30,13 @@
|
||||
providers:
|
||||
- id: deepseek
|
||||
name: DeepSeek
|
||||
retryPolicy:
|
||||
mode: normal
|
||||
maxRetries: 2
|
||||
backoff:
|
||||
initialDelayMs: 1
|
||||
maxDelayMs: 1
|
||||
jitterRatio: 0
|
||||
models:
|
||||
- id: deepseek-v4-flash
|
||||
- id: deepseek-v4-pro
|
||||
|
||||
@@ -2,14 +2,32 @@
|
||||
# deterministic 1 ms zero-jitter delay so the durable `llm/retry` event
|
||||
# (`delayMs`) and replay wall time stay reproducible. The overlay changes no
|
||||
# tool or prompt composition, so its scenarios share the default header class.
|
||||
# A config patch replaces the whole app config, so the base fields are restated
|
||||
# verbatim; the model is re-pinned to `deepseek-v4-flash` like the other
|
||||
# snapshot overlays because the recorded corpus was captured on flash.
|
||||
# Config patches replace whole plugin configs: the provider patch restates its
|
||||
# adapter fields around `retryPolicy`, while the app patch re-pins the recorded
|
||||
# flash model and restates its base fields.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
config:
|
||||
apiKey: !!js process.env.DEEPSEEK_API_KEY
|
||||
baseURL: !!js process.env.DEEPSEEK_BASE_URL
|
||||
thinking: enabled
|
||||
reasoningEffort: max
|
||||
defaultContextWindow: 256000
|
||||
retryPolicy:
|
||||
mode: normal
|
||||
maxRetries: 2
|
||||
backoff:
|
||||
initialDelayMs: 1
|
||||
maxDelayMs: 1
|
||||
jitterRatio: 0
|
||||
models:
|
||||
- id: deepseek-v4-flash
|
||||
- id: deepseek-v4-pro
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
@@ -19,11 +37,6 @@
|
||||
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
llmRetry:
|
||||
maxTransientRetries: 2
|
||||
initialDelayMs: 1
|
||||
maxDelayMs: 1
|
||||
jitterRatio: 0
|
||||
persona: |
|
||||
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
|
||||
|
||||
|
||||
@@ -135,10 +135,10 @@ const SCENARIOS: Scenario[] = [
|
||||
{ name: 'error-finish', hasModelTurn: true, recorded: false, overridden: true },
|
||||
// Keyless, authored (like error-finish): a live provider cannot be coaxed
|
||||
// into a degenerate empty completion, so the fixture scripts the adapters'
|
||||
// EMPTY_RESPONSE error finish (step 1) followed by the recovered reply
|
||||
// (step 2), proving the default retry policy end to end: the durable
|
||||
// EMPTY_RESPONSE error finish in turn 1 followed by the recovered reply
|
||||
// in retry turn 2, proving the default retry policy end to end: the durable
|
||||
// llm/retry event, no ACP output for the discarded attempt, the recovered
|
||||
// reply, and a clean completed turn. Its overlay only pins a deterministic
|
||||
// reply, and a clean completed retry turn. Its overlay only pins a deterministic
|
||||
// 1 ms zero-jitter delay, so it shares the default header class.
|
||||
{ name: 'empty-response-retry', hasModelTurn: true, recorded: false, configPath: RETRY_CONFIG },
|
||||
// Keyless, authored (like error-finish/cancel): deterministically forcing a
|
||||
@@ -199,10 +199,10 @@ const SCENARIOS: Scenario[] = [
|
||||
headerClass: 'advanced',
|
||||
configPath: ADVANCED_CONFIG,
|
||||
},
|
||||
// Prompt-submit blocks are authored keylessly: they persist a rejected turn
|
||||
// and hook events without starting a model step, so their logs still compare.
|
||||
{ name: 'hook-cc-promptsubmit-block', hasModelTurn: false, comparesLog: true, recorded: false },
|
||||
{ name: 'hook-codex-promptsubmit-block', hasModelTurn: false, comparesLog: true, recorded: false },
|
||||
// Prompt-submit blocks are authored keylessly. Admission rejects before a
|
||||
// turn opens, so only the ACP stop reason is observable and no log is harvested.
|
||||
{ name: 'hook-cc-promptsubmit-block', hasModelTurn: false, recorded: false },
|
||||
{ name: 'hook-codex-promptsubmit-block', hasModelTurn: false, recorded: false },
|
||||
// The mid-turn seams fire during a real model turn, so each is recorded with its hook active
|
||||
// (the model's reaction to a deny/block/force-continue is part of the captured transcript).
|
||||
// SessionStart/SubagentStart are excluded because detached injection races log
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"waitForText": "GOAL ROUND ONE"
|
||||
},
|
||||
{ "op": "waitForTurnStart", "minimumTurn": 3 },
|
||||
{ "op": "cancel", "waitForFile": { "path": ".dsh-snapshot-goal-cancel-ready" } }
|
||||
{ "op": "cancel", "waitForFile": { "path": ".dsh-snapshot-goal-cancel-ready" } },
|
||||
{ "op": "waitForTurnEnd" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
{"type":"assistant/message","seq":10,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":20,"outputTokens":8}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}}
|
||||
{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":2},\"activation\":\"armed\"}"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":13,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"active\",\"maxGoalRounds\":2},\"roundsStarted\":0,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":0},"meta":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the ACP goal-session snapshot proof","phase":"active","maxGoalRounds":2},"roundsStarted":0,"createdAt":0,"updatedAt":0}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":13,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"active\",\"maxGoalRounds\":2},\"roundsStarted\":0,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":0,"change":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the ACP goal-session snapshot proof","phase":"active","maxGoalRounds":2},"roundsStarted":0,"createdAt":0,"updatedAt":0}}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":14,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":15,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
@@ -49,6 +49,6 @@
|
||||
{"type":"step/start","seq":47,"time":0,"data":{"turn":3,"step":1}}
|
||||
{"type":"assistant/chunk","seq":48,"time":0,"data":{"turn":3,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":49,"time":0,"data":{"turn":3,"step":1,"chunk":{"type":"text-delta","index":0,"text":"partial"}}}
|
||||
{"type":"user/message","seq":50,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":2,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"paused\",\"maxGoalRounds\":2},\"roundsStarted\":2,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":2,"round":0},"meta":{"kind":"goal/change","version":1,"operation":"pause","goal":{"id":"goal-{{sessionId}}","revision":2,"objective":"Finish the ACP goal-session snapshot proof","phase":"paused","maxGoalRounds":2},"roundsStarted":2,"createdAt":0,"updatedAt":0}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":51,"time":0,"data":{"turn":3,"step":1}}
|
||||
{"type":"turn/end","seq":52,"time":0,"data":{"turn":3,"reason":{"kind":"aborted"}}}
|
||||
{"type":"step/end","seq":50,"time":0,"data":{"turn":3,"step":1}}
|
||||
{"type":"turn/end","seq":51,"time":0,"data":{"turn":3,"reason":{"kind":"aborted"}}}
|
||||
{"type":"user/message","seq":52,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":2,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"paused\",\"maxGoalRounds\":2},\"roundsStarted\":2,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":2,"round":0,"change":{"kind":"goal/change","version":1,"operation":"pause","goal":{"id":"goal-{{sessionId}}","revision":2,"objective":"Finish the ACP goal-session snapshot proof","phase":"paused","maxGoalRounds":2},"roundsStarted":2,"createdAt":0,"updatedAt":0}}},"surfaceOp":"append"}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"steps": [
|
||||
{ "op": "initialize" },
|
||||
{ "op": "newSession" },
|
||||
{ "op": "prompt", "text": "Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then reply with exactly ADVANCED_ACP_OK." }
|
||||
{ "op": "prompt", "text": "Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK." }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{"type":"session","version":0,"id":"11111111-1111-4111-8111-111111111111","createdAt":1783950000000,"cwd":"/tmp/advanced-acp","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1783957884479,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1783957884479,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":1,"time":1783957884479,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1783957884479,"data":{"title":"Run this advanced flow exactly","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1783957884486,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
@@ -11,19 +11,19 @@
|
||||
{"type":"assistant/chunk","seq":9,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":10,"time":1783957884487,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":11,"time":1783957884487,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}
|
||||
{"type":"tool/result","seq":12,"time":1783957884488,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"mounted dyn-1 (plugin \"snapshot-marker\", state: active)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":12,"time":1783957884488,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":13,"time":1783957884489,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":14,"time":1783957884489,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":15,"time":1783950000015,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1783950000016,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1783950000016,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1783950000018,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":20,"time":1783957884490,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[15,16,17,18,19],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":21,"time":1783957884490,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}
|
||||
{"type":"tool/code-dispatch-start","seq":22,"time":1785036891166,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"dynamic"}}}
|
||||
{"type":"tool/code-dispatch","seq":23,"time":1785036891167,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"dynamic"},"isError":false,"content":[{"type":"text","text":"## dynamic\n- dyn-1: snapshot-marker [active]"}]}}
|
||||
{"type":"tool/result","seq":24,"time":1785036891170,"data":{"turn":1,"step":2,"callId":"advanced-code","content":[{"type":"text","text":"## dynamic\n- dyn-1: snapshot-marker [active]"}],"isError":false},"sourceEventSeqs":[21],"surfaceOp":"append"}
|
||||
{"type":"assistant/message","seq":20,"time":1783957884490,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[15,16,17,18,19],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":21,"time":1783957884490,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}
|
||||
{"type":"tool/code-dispatch-start","seq":22,"time":1785036891166,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"}}}
|
||||
{"type":"tool/code-dispatch","seq":23,"time":1785036891167,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}]}}
|
||||
{"type":"tool/result","seq":24,"time":1785036891170,"data":{"turn":1,"step":2,"callId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false},"sourceEventSeqs":[21],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":25,"time":1785036891171,"data":{"turn":1,"step":2}}
|
||||
{"type":"step/start","seq":26,"time":1785036891175,"data":{"turn":1,"step":3}}
|
||||
{"type":"assistant/chunk","seq":27,"time":1783950000027,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
@@ -53,7 +53,7 @@
|
||||
{"type":"assistant/chunk","seq":51,"time":1785036891795,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":52,"time":1785036891796,"data":{"turn":1,"step":5,"content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[47,48,49,50,51],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":53,"time":1785036891796,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}
|
||||
{"type":"tool/result","seq":54,"time":1785036891798,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"unmounted dyn-1 (plugin \"snapshot-marker\")"}],"isError":false},"sourceEventSeqs":[53],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":54,"time":1785036891798,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false},"sourceEventSeqs":[53],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":55,"time":1785036891799,"data":{"turn":1,"step":5}}
|
||||
{"type":"step/start","seq":56,"time":1785036891801,"data":{"turn":1,"step":6}}
|
||||
{"type":"assistant/chunk","seq":57,"time":1783957884720,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
|
||||
@@ -58,21 +58,21 @@ interface ToolArgsMap {
|
||||
/** Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access. */
|
||||
justification?: string;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Inspect the live cordis runtime that is running THIS agent. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (a flat list of the loaded plugins with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `dynamic` (plugins you mounted via cordis_mount: id, name, state, provided services, awaited services), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Omit `what` to get all six sections. With `what:"api"` or `what:"events"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */
|
||||
/** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:"api"` or `what:"events"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */
|
||||
cordis_inspect: {
|
||||
/** Limit the report to one section. Omit for all sections. */
|
||||
what?: "services" | "plugins" | "tools" | "dynamic" | "api" | "events";
|
||||
what?: "services" | "plugins" | "tools" | "temporary" | "api" | "events";
|
||||
/** Exact service key or event name whose original JSDoc to include; valid only with what:"api" or what:"events". */
|
||||
name?: string;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Mount a NEW cordis plugin into the live runtime that is running THIS agent (self-modification). `code` runs as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Mounts can COMPOSE: one plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically on unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned on unmount) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` VETOES the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */
|
||||
/** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` VETOES the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */
|
||||
cordis_mount: {
|
||||
/** Body of an async JS function; must `return` the plugin to mount. */
|
||||
/** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */
|
||||
code: string;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Dispose a plugin previously mounted with cordis_mount, by id. All its registrations (event listeners, tools, services) are cleaned up through the cordis effect lifecycle. Returns only after disposal has fully completed (quiescence, not just a request to stop). */
|
||||
/** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */
|
||||
cordis_unmount: {
|
||||
/** The dynamic mount id returned by cordis_mount (e.g. "dyn-1"). */
|
||||
/** The temporary Plugin id returned by cordis_mount (for example "dyn-1"); valid only in this process and invalid after unmount or restart. */
|
||||
id: string;
|
||||
} & Record<string, JsonValue>;
|
||||
/** Create one persisted same-session completion goal when the current direct human request is a long-running objective that should continue across autonomous goal rounds. You may infer that intent without requiring the user to say "create a goal". Do not use this for trivial single-turn work. Execution rejects non-human and subagent authority. */
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
{
|
||||
"name": "cordis_inspect",
|
||||
"description": "Inspect the live cordis runtime that is running THIS agent. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (a flat list of the loaded plugins with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `dynamic` (plugins you mounted via cordis_mount: id, name, state, provided services, awaited services), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.",
|
||||
"description": "Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -58,7 +58,7 @@
|
||||
"services",
|
||||
"plugins",
|
||||
"tools",
|
||||
"dynamic",
|
||||
"temporary",
|
||||
"api",
|
||||
"events"
|
||||
]
|
||||
@@ -72,13 +72,13 @@
|
||||
},
|
||||
{
|
||||
"name": "cordis_mount",
|
||||
"description": "Mount a NEW cordis plugin into the live runtime that is running THIS agent (self-modification). `code` runs as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Mounts can COMPOSE: one plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically on unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned on unmount) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` VETOES the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.",
|
||||
"description": "Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement a normal local, project, or repository Plugin through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` VETOES the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"description": "Body of an async JS function; must `return` the plugin to mount."
|
||||
"description": "JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -88,13 +88,13 @@
|
||||
},
|
||||
{
|
||||
"name": "cordis_unmount",
|
||||
"description": "Dispose a plugin previously mounted with cordis_mount, by id. All its registrations (event listeners, tools, services) are cleaned up through the cordis effect lifecycle. Returns only after disposal has fully completed (quiescence, not just a request to stop).",
|
||||
"description": "Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "The dynamic mount id returned by cordis_mount (e.g. \"dyn-1\")."
|
||||
"description": "The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":10,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_spill","name":"bash","arguments":"{\"command\":\"node -e \\\"process.stdout.write('SPILL_START-' + 'x'.repeat(2000) + '-SPILL_END')\\\"\",\"description\":\"Print large deterministic output\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","name":"bash","arguments":"{\"command\":\"node -e \\\"process.stdout.write('SPILL_START-' + 'x'.repeat(2000) + '-SPILL_END')\\\"\",\"description\":\"Print large deterministic output\"}"}}
|
||||
{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","content":[{"type":"text","text":"SPILL_START-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-SPILL_END\n\n(Omitted 1417 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-ee77dff02/session-5747fa727e10/57c2f8c3fbf2-bash.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_spill","content":[{"type":"text","text":"SPILL_START-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-SPILL_END\n\n(Omitted 1417 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-ee77dff02/session-5e53dc8acfe4/2ce9d7a31a38-bash.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":13,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":14,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
{"type":"turn/start","seq":0,"time":1785014475014,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785014475015,"data":{"content":[{"type":"text","text":"Using ONE run_code program, call tools.read on nested/task.txt. After the program finishes, answer the workspace handshake question using the newly discovered instructions: What is the Code Mode workspace handshake?"}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785014475022,"data":{"title":"Using ONE run_code program, call","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1785014475034,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1785014475035,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}","messagePrefix":[{"role":"user","content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nWorkspace snapshot root instruction.\n\n</system-reminder>"}]}]},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1785014475456,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":6,"time0":1785014475457,"data":{"turn":1,"step":1,"index":0,"dt":[139,42,1,0,0,0,40,1,0,0,0,43,0,0,0,39,43,1,0,0,0,40,1,40,0,0,1,42,0,1,0,0,40,0,0,1,0,0,44,0,1,39,0,1,0],"texts":["The"," user"," wants"," me"," to"," read"," the"," file"," `","n","ested","/t","ask",".txt","`"," using"," a"," `","run","_code","`"," program",","," and"," then"," answer"," the"," question"," \"","What"," is"," the"," Code"," Mode"," workspace"," hand","shake","?\""," based"," on"," the"," contents"," of"," that"," file","."]}}
|
||||
{"type":"assistant/chunk","seq":52,"time":1785014476183,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":53,"time0":1785014476183,"data":{"turn":1,"step":1,"index":1,"dt":[41,1,0,0,41,0,0,1,41,1,0,0,40,0,42,0,0,0,1,0,40,1,0,0,0,0,41,0,0,42,1,0,41,1,0,0,42,0,0,0,0,41],"id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","args":["","{","\"","code","\"",": ","\"","\\n","const"," result"," ="," await"," tools",".read","({"," file","_path",":"," \\\"","n","ested","/t","ask",".txt","\\\""," });\\n","return"," result",";\\n","\"",", ","\"","description","\"",": ","\"","Read"," nested","/t","ask",".txt","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":96,"time":1785014476731,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to read the file `nested/task.txt` using a `run_code` program, and then answer the question \"What is the Code Mode workspace handshake?\" based on the contents of that file."}}}}
|
||||
{"type":"assistant/chunk","seq":97,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":98,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":6200,"outputTokens":130,"cacheReadTokens":0,"reasoningTokens":46}}}}
|
||||
{"type":"assistant/chunk","seq":99,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":100,"time":1785014476736,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to read the file `nested/task.txt` using a `run_code` program, and then answer the question \"What is the Code Mode workspace handshake?\" based on the contents of that file."},{"type":"tool-call","id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":6200,"outputTokens":130,"cacheReadTokens":0,"reasoningTokens":46}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":101,"time":1785014476737,"data":{"turn":1,"step":1,"callId":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}}
|
||||
{"type":"tool/code-dispatch-start","seq":102,"time":1785014476837,"data":{"parentCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264","subCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264:code:1","name":"read","arguments":{"file_path":"nested/task.txt"}}}
|
||||
{"type":"tool/code-dispatch","seq":103,"time":1785014476842,"data":{"parentCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264","subCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264:code:1","name":"read","arguments":{"file_path":"nested/task.txt"},"isError":false,"content":[{"type":"text","text":"<path>/tmp/acp-snap-cwd-muJYhO/nested/task.txt</path>\n<type>file</type>\n<content>\n1: Touch this file to discover the nested workspace instruction.\n\n(End of file - total 1 lines)\n</content>"}]}}
|
||||
{"type":"tool/result","seq":104,"time":1785014476847,"data":{"turn":1,"step":1,"callId":"call_00_hD8d0VcXXFVMtn64GSoC9264","content":[{"type":"text","text":"{\n \"path\": \"/tmp/acp-snap-cwd-muJYhO/nested/task.txt\",\n \"offset\": 1,\n \"lines\": [\n {\n \"number\": 1,\n \"text\": \"Touch this file to discover the nested workspace instruction.\"\n }\n ],\n \"totalLines\": 1\n}"}],"isError":false},"sourceEventSeqs":[101],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":105,"time":1785014476847,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"plugin","plugin":"workspace-context"},"meta":{"kind":"workspace-instructions","version":1,"changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":106,"time":1785014476850,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":107,"time":1785014476854,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":108,"time":1785014477311,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":109,"time0":1785014477311,"data":{"turn":1,"step":2,"index":0,"dt":[108,56,1,0,26,0,0,42,0,43,1,42,1,0,0,0,0,42,0,0,0,1,0,40,0,0,1,0,0,43],"texts":["The"," nested","/","AG","ENTS",".md"," file"," provides"," the"," instruction",":"," when"," asked"," for"," the"," Code"," Mode"," workspace"," hand","shake",","," answer"," exactly"," `","CODE","_M","ODE","_CONT","EXT","_OK","`."]}}
|
||||
{"type":"assistant/chunk","seq":140,"time":1785014477799,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":141,"time0":1785014477799,"data":{"turn":1,"step":2,"index":1,"dt":[43,40,0,0,0,1,42,0,0,1,0,0,41,0],"texts":["**","Code"," Mode"," workspace"," hand","shake",":**"," `","CODE","_M","ODE","_CONT","EXT","_OK","`"]}}
|
||||
{"type":"assistant/chunk","seq":156,"time":1785014477967,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The nested/AGENTS.md file provides the instruction: when asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK`."}}}}
|
||||
{"type":"assistant/chunk","seq":157,"time":1785014477967,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}}}}
|
||||
{"type":"assistant/chunk","seq":158,"time":1785014477968,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":226,"outputTokens":47,"cacheReadTokens":6272,"reasoningTokens":31}}}}
|
||||
{"type":"assistant/chunk","seq":159,"time":1785014477968,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":160,"time":1785014477968,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The nested/AGENTS.md file provides the instruction: when asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK`."},{"type":"text","text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":226,"outputTokens":47,"cacheReadTokens":6272,"reasoningTokens":31}},"sourceEventSeqs":[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":161,"time":1785014477972,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":162,"time":1785014477972,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"user/message","seq":3,"time":1785122256262,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nWorkspace snapshot root instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","baseline":true,"changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2119a7072358cc727f8d9c4cb7388e905b075fe6"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":4,"time":1785122256264,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1785122256265,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1785014475457,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":7,"time0":1785014475596,"data":{"turn":1,"step":1,"index":0,"dt":[42,1,0,0,0,40,1,0,0,0,43,0,0,0,39,43,1,0,0,0,40,1,40,0,0,1,42,0,1,0,0,40,0,0,1,0,0,44,0,1,39,0,1,0,126],"texts":["The"," user"," wants"," me"," to"," read"," the"," file"," `","n","ested","/t","ask",".txt","`"," using"," a"," `","run","_code","`"," program",","," and"," then"," answer"," the"," question"," \"","What"," is"," the"," Code"," Mode"," workspace"," hand","shake","?\""," based"," on"," the"," contents"," of"," that"," file","."]}}
|
||||
{"type":"assistant/chunk","seq":53,"time":1785014476183,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":54,"time0":1785014476224,"data":{"turn":1,"step":1,"index":1,"dt":[1,0,0,41,0,0,1,41,1,0,0,40,0,42,0,0,0,1,0,40,1,0,0,0,0,41,0,0,42,1,0,41,1,0,0,42,0,0,0,0,41,89],"id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","args":["","{","\"","code","\"",": ","\"","\\n","const"," result"," ="," await"," tools",".read","({"," file","_path",":"," \\\"","n","ested","/t","ask",".txt","\\\""," });\\n","return"," result",";\\n","\"",", ","\"","description","\"",": ","\"","Read"," nested","/t","ask",".txt","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":97,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to read the file `nested/task.txt` using a `run_code` program, and then answer the question \"What is the Code Mode workspace handshake?\" based on the contents of that file."}}}}
|
||||
{"type":"assistant/chunk","seq":98,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":99,"time":1785014476732,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":6200,"outputTokens":130,"cacheReadTokens":0,"reasoningTokens":46}}}}
|
||||
{"type":"assistant/chunk","seq":100,"time":1785122256269,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":101,"time":1785122256269,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to read the file `nested/task.txt` using a `run_code` program, and then answer the question \"What is the Code Mode workspace handshake?\" based on the contents of that file."},{"type":"tool-call","id":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":6200,"outputTokens":130,"cacheReadTokens":0,"reasoningTokens":46}},"sourceEventSeqs":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":102,"time":1785122256269,"data":{"turn":1,"step":1,"callId":"call_00_hD8d0VcXXFVMtn64GSoC9264","name":"run_code","arguments":"{\"code\": \"\\nconst result = await tools.read({ file_path: \\\"nested/task.txt\\\" });\\nreturn result;\\n\", \"description\": \"Read nested/task.txt\"}"}}
|
||||
{"type":"tool/code-dispatch-start","seq":103,"time":1785122256332,"data":{"parentCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264","subCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264:code:1","name":"read","arguments":{"file_path":"nested/task.txt"}}}
|
||||
{"type":"tool/code-dispatch","seq":104,"time":1785122256336,"data":{"parentCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264","subCallId":"call_00_hD8d0VcXXFVMtn64GSoC9264:code:1","name":"read","arguments":{"file_path":"nested/task.txt"},"isError":false,"content":[{"type":"text","text":"<path>/tmp/acp-snap-cwd-muJYhO/nested/task.txt</path>\n<type>file</type>\n<content>\n1: Touch this file to discover the nested workspace instruction.\n\n(End of file - total 1 lines)\n</content>"}]}}
|
||||
{"type":"tool/result","seq":105,"time":1785122256338,"data":{"turn":1,"step":1,"callId":"call_00_hD8d0VcXXFVMtn64GSoC9264","content":[{"type":"text","text":"{\n \"path\": \"/tmp/acp-snap-cwd-muJYhO/nested/task.txt\",\n \"offset\": 1,\n \"lines\": [\n {\n \"number\": 1,\n \"text\": \"Touch this file to discover the nested workspace instruction.\"\n }\n ],\n \"totalLines\": 1\n}"}],"isError":false},"sourceEventSeqs":[102],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":106,"time":1785122256338,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":107,"time":1785122256338,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":108,"time":1785122256347,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":109,"time":1785014477311,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":110,"time0":1785014477419,"data":{"turn":1,"step":2,"index":0,"dt":[56,1,0,26,0,0,42,0,43,1,42,1,0,0,0,0,42,0,0,0,1,0,40,0,0,1,0,0,43,41],"texts":["The"," nested","/","AG","ENTS",".md"," file"," provides"," the"," instruction",":"," when"," asked"," for"," the"," Code"," Mode"," workspace"," hand","shake",","," answer"," exactly"," `","CODE","_M","ODE","_CONT","EXT","_OK","`."]}}
|
||||
{"type":"assistant/chunk","seq":141,"time":1785014477799,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":142,"time0":1785014477842,"data":{"turn":1,"step":2,"index":1,"dt":[40,0,0,0,1,42,0,0,1,0,0,41,0,0],"texts":["**","Code"," Mode"," workspace"," hand","shake",":**"," `","CODE","_M","ODE","_CONT","EXT","_OK","`"]}}
|
||||
{"type":"assistant/chunk","seq":157,"time":1785014477967,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The nested/AGENTS.md file provides the instruction: when asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK`."}}}}
|
||||
{"type":"assistant/chunk","seq":158,"time":1785014477968,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}}}}
|
||||
{"type":"assistant/chunk","seq":159,"time":1785014477968,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":226,"outputTokens":47,"cacheReadTokens":6272,"reasoningTokens":31}}}}
|
||||
{"type":"assistant/chunk","seq":160,"time":1785122256351,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":161,"time":1785122256351,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The nested/AGENTS.md file provides the instruction: when asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK`."},{"type":"text","text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":226,"outputTokens":47,"cacheReadTokens":6272,"reasoningTokens":31}},"sourceEventSeqs":[109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":162,"time":1785122256351,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":163,"time":1785122256351,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -7,13 +7,15 @@
|
||||
{"type":"assistant/chunk","seq":5,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":0,"outputTokens":0}}}}
|
||||
{"type":"assistant/chunk","seq":6,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"model returned a completed response with no content","code":"EMPTY_RESPONSE"}}}}}
|
||||
{"type":"step/end","seq":7,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"llm/retry","seq":8,"time":0,"data":{"turn":1,"step":1,"retry":1,"maxRetries":2,"delayMs":1,"failure":{"message":"model returned a completed response with no content","code":"EMPTY_RESPONSE"}}}
|
||||
{"type":"step/start","seq":9,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"Recovered."}}}
|
||||
{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"Recovered."}}}}
|
||||
{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":12,"outputTokens":3}}}}
|
||||
{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":15,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"text","text":"Recovered."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":12,"outputTokens":3}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":16,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":17,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"llm/retry","seq":8,"time":0,"data":{"turn":1,"step":1,"provider":"deepseek","mode":"normal","policyKey":"[\"normal\",2,[\"EMPTY_RESPONSE\",\"RATE_LIMIT\",\"SERVER\",\"TIMEOUT\",\"TRANSPORT\"],1,1,0]","retry":1,"maxRetries":2,"delayMs":1,"failure":{"message":"model returned a completed response with no content","code":"EMPTY_RESPONSE"}}}
|
||||
{"type":"turn/end","seq":9,"time":1785047244285,"data":{"turn":1,"reason":{"kind":"error","step":1,"failure":{"message":"model returned a completed response with no content","code":"EMPTY_RESPONSE"}}}}
|
||||
{"type":"turn/start","seq":10,"time":1785047244285,"data":{"turn":2,"trigger":{"kind":"retry"}}}
|
||||
{"type":"step/start","seq":11,"time":1785047244289,"data":{"turn":2,"step":1}}
|
||||
{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"text-delta","index":0,"text":"Recovered."}}}
|
||||
{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"Recovered."}}}}
|
||||
{"type":"assistant/chunk","seq":15,"time":1785047244294,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":12,"outputTokens":3}}}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1785047244294,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":17,"time":1785047244294,"data":{"turn":2,"step":1,"content":[{"type":"text","text":"Recovered."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":12,"outputTokens":3}},"sourceEventSeqs":[12,13,14,15,16],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":18,"time":1785047244294,"data":{"turn":2,"step":1}}
|
||||
{"type":"turn/end","seq":19,"time":1785047244294,"data":{"turn":2,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
{"type":"assistant/chunk","seq":127,"time":1783860677493,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":128,"time":1784821261753,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a command with sandbox_permissions set to danger-full-access, no prior run needed, justified as instructed."},{"type":"tool-call","id":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1501,"outputTokens":174,"cacheReadTokens":0,"reasoningTokens":28}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":129,"time":1784821261754,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write file outside workspace and verify\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
|
||||
{"type":"approval/asked","seq":130,"time":1784821261758,"data":{"id":"8e278621-09a9-4c76-a785-74aea76cc120","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":131,"time":1784821261759,"data":{"id":"8e278621-09a9-4c76-a785-74aea76cc120","outcome":"allowed-once"}}
|
||||
{"type":"approval/asked","seq":130,"time":1784821261758,"data":{"id":"2c0f15e6-3b6e-45b8-b5df-440ea83ebee9","toolName":"bash","callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":131,"time":1784821261759,"data":{"id":"2c0f15e6-3b6e-45b8-b5df-440ea83ebee9","outcome":"allowed-once"}}
|
||||
{"type":"tool/result","seq":132,"time":1784821261775,"data":{"turn":1,"step":1,"callId":"call_00_d0sAHpJ9mYOJi0z7KNy30441","content":[{"type":"text","text":"escalated\n"}],"isError":false},"sourceEventSeqs":[129],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":133,"time":1784821261781,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":134,"time":1784821261782,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
{"type":"assistant/chunk","seq":151,"time":1783860681967,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":152,"time":1784821263293,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a specific command with `sandbox_permissions` set to `danger-full-access` and a specific justification. They explicitly said NOT to run it without sandbox_permissions first. Let me do exactly that."},{"type":"tool-call","id":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1509,"outputTokens":198,"cacheReadTokens":0,"reasoningTokens":48}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":153,"time":1784821263294,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","name":"bash","arguments":"{\"command\": \"printf 'escalated\\\\n' > /tmp/dsh-escalated.txt && cat /tmp/dsh-escalated.txt && rm /tmp/dsh-escalated.txt\", \"description\": \"Write to /tmp and verify, then clean up\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to write a file outside the workspace\"}"}}
|
||||
{"type":"approval/asked","seq":154,"time":1784821263300,"data":{"id":"f55fc10d-f2f1-435f-8c85-076bafaa5f85","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":155,"time":1784821263301,"data":{"id":"f55fc10d-f2f1-435f-8c85-076bafaa5f85","outcome":"rejected"}}
|
||||
{"type":"approval/asked","seq":154,"time":1784821263300,"data":{"id":"8547967e-97b5-4b73-a553-0d82b1ec6652","toolName":"bash","callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","reason":"escalate sandbox to danger-full-access: the user asked to write a file outside the workspace"}}
|
||||
{"type":"approval/decided","seq":155,"time":1784821263301,"data":{"id":"8547967e-97b5-4b73-a553-0d82b1ec6652","outcome":"rejected"}}
|
||||
{"type":"tool/result","seq":156,"time":1784821263302,"data":{"turn":1,"step":1,"callId":"call_00_WB1vnPomi8yr6MlcFKTj7912","content":[{"type":"text","text":"Error: the user rejected escalating this command to \"danger-full-access\""}],"isError":true},"sourceEventSeqs":[153],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":157,"time":1784821263307,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":158,"time":1784821263307,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
{"type":"assistant/chunk","seq":85,"time":1784045703749,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":86,"time":1784821264893,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to create a file using the write tool with sandbox_permissions. Let me do that."},{"type":"tool-call","id":"call_00_Fnymmavpr4klMDy4Fdej3227","name":"write","arguments":"{\"file_path\": \"escalated.md\", \"content\": \"escalated\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to escalate this write\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3871,"outputTokens":132,"cacheReadTokens":0,"reasoningTokens":23}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":87,"time":1784821264893,"data":{"turn":1,"step":1,"callId":"call_00_Fnymmavpr4klMDy4Fdej3227","name":"write","arguments":"{\"file_path\": \"escalated.md\", \"content\": \"escalated\", \"sandbox_permissions\": \"danger-full-access\", \"justification\": \"the user asked to escalate this write\"}"}}
|
||||
{"type":"approval/asked","seq":88,"time":1784821264898,"data":{"id":"d1a35247-af6d-4df7-9c62-e53d1be0a3e7","toolName":"write","callId":"call_00_Fnymmavpr4klMDy4Fdej3227","reason":"escalate sandbox to danger-full-access: the user asked to escalate this write"}}
|
||||
{"type":"approval/decided","seq":89,"time":1784821264898,"data":{"id":"d1a35247-af6d-4df7-9c62-e53d1be0a3e7","outcome":"allowed-once"}}
|
||||
{"type":"tool/result","seq":90,"time":1784821264906,"data":{"turn":1,"step":1,"callId":"call_00_Fnymmavpr4klMDy4Fdej3227","content":[{"type":"text","text":"<path>/var/folders/2g/b32ct0qn1d728l_v6tdkjytr0000gn/T/acp-snap-cwd-vmEGzd/escalated.md</path>\n<type>file</type>\n<content>\nCreated file\n</content>"}],"isError":false,"meta":{"diffs":[]}},"sourceEventSeqs":[87],"surfaceOp":"append"}
|
||||
{"type":"approval/asked","seq":88,"time":1784821264898,"data":{"id":"aecaceb0-23b7-4cd5-b7a1-17bc431dc35a","toolName":"write","callId":"call_00_Fnymmavpr4klMDy4Fdej3227","reason":"escalate sandbox to danger-full-access: the user asked to escalate this write"}}
|
||||
{"type":"approval/decided","seq":89,"time":1784821264898,"data":{"id":"aecaceb0-23b7-4cd5-b7a1-17bc431dc35a","outcome":"allowed-once"}}
|
||||
{"type":"tool/result","seq":90,"time":1784821264906,"data":{"turn":1,"step":1,"callId":"call_00_Fnymmavpr4klMDy4Fdej3227","content":[{"type":"text","text":"<path>/private/var/folders/2g/b32ct0qn1d728l_v6tdkjytr0000gn/T/acp-snap-cwd-vmEGzd/escalated.md</path>\n<type>file</type>\n<content>\nCreated file\n</content>"}],"isError":false,"meta":{"diffs":[]}},"sourceEventSeqs":[87],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":91,"time":1784821264911,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":92,"time":1784821264912,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":93,"time":1784821264916,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
{"type":"tool/call","seq":54,"time":1783352172557,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO\"}"}}
|
||||
{"type":"hook/invoked","seq":55,"time":1783352172558,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
|
||||
{"type":"hook/result","seq":56,"time":1783352172573,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"ask","exitCode":0,"durationMs":14.113374999999905}}
|
||||
{"type":"approval/asked","seq":57,"time":1783962235813,"data":{"id":"8a5510f4-93b7-4e70-b082-20d13dec386d","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
|
||||
{"type":"approval/decided","seq":58,"time":1783962235813,"data":{"id":"8a5510f4-93b7-4e70-b082-20d13dec386d","outcome":"rejected"}}
|
||||
{"type":"approval/asked","seq":57,"time":1783962235813,"data":{"id":"f54e812d-1b78-4813-93d6-91dd384905f7","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
|
||||
{"type":"approval/decided","seq":58,"time":1783962235813,"data":{"id":"f54e812d-1b78-4813-93d6-91dd384905f7","outcome":"rejected"}}
|
||||
{"type":"tool/result","seq":59,"time":1783962235814,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","content":[{"type":"text","text":"Error: the user rejected tool \"bash\""}],"isError":true},"sourceEventSeqs":[54],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":60,"time":1783962235814,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":61,"time":1783962235814,"data":{"turn":1,"step":2}}
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
{"type":"session","version":0,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"hook/invoked","seq":1,"time":0,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"claude","handlerId":"claude:UserPromptSubmit:1"}}
|
||||
{"type":"hook/result","seq":2,"time":0,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"claude:UserPromptSubmit:1","decision":"block","exitCode":2,"stderrSummary":"blocked by policy hook","durationMs":0}}
|
||||
{"type":"prompt/blocked","seq":3,"time":0,"data":{"content":[{"type":"text","text":"Delete everything in the repo."}],"source":{"kind":"user"},"reason":"blocked by policy hook"}}
|
||||
{"type":"turn/end","seq":4,"time":0,"data":{"turn":1,"reason":{"kind":"rejected","reason":"blocked by policy hook"}}}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
{"type":"session","version":0,"id":"d03c3a83-1238-4e2e-ad9a-b86a61840a40","createdAt":1783352160541,"cwd":"/tmp/acp-snap-cwd-QUDqlk","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1783352160545,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"hook/invoked","seq":1,"time":1783352160546,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"claude","handlerId":"claude:UserPromptSubmit:1"}}
|
||||
{"type":"hook/result","seq":2,"time":1783352160564,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"claude:UserPromptSubmit:1","decision":"pass","exitCode":0,"durationMs":17.45639600000004}}
|
||||
{"type":"user/message","seq":3,"time":1783352160564,"data":{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":4,"time":1783352160564,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-claude"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":5,"time":1783352160564,"data":{"title":"What is my favorite color?","messageSeqs":[3],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":6,"time":1783352160565,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":7,"time":1783352160566,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783352161228,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":9,"time0":1783352161229,"data":{"turn":1,"step":1,"index":0,"dt":[106,28,0,29,0,0,1,0,27,1,0,0,28,0,0,28,1,0],"texts":["The"," user","'s"," favorite"," color"," is"," te","al",","," as"," stated"," in"," the"," context"," provided"," by"," the"," plugin","."]}}
|
||||
{"type":"assistant/chunk","seq":28,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":29,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"te"}}}
|
||||
{"type":"assistant/chunk","seq":30,"time":1783352161511,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"al"}}}
|
||||
{"type":"assistant/chunk","seq":31,"time":1783352161512,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user's favorite color is teal, as stated in the context provided by the plugin."}}}}
|
||||
{"type":"assistant/chunk","seq":32,"time":1783352161512,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"teal"}}}}
|
||||
{"type":"assistant/chunk","seq":33,"time":1783352161512,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":2892,"outputTokens":22,"cacheReadTokens":0,"reasoningTokens":19}}}}
|
||||
{"type":"assistant/chunk","seq":34,"time":1783352161512,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":35,"time":1783352161515,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user's favorite color is teal, as stated in the context provided by the plugin."},{"type":"text","text":"teal"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":2892,"outputTokens":22,"cacheReadTokens":0,"reasoningTokens":19}},"sourceEventSeqs":[8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":36,"time":1783352161516,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":37,"time":1783352161516,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"user/message","seq":1,"time":1785122243327,"data":{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":2,"time":1785122243327,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-claude"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":3,"time":1785122243327,"data":{"title":"What is my favorite color?","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":4,"time":1785122243354,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1785122243354,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1785122243359,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":7,"time0":1783352160565,"data":{"turn":1,"step":1,"index":0,"dt":[1,662,1,106,28,0,29,0,0,1,0,27,1,0,0,28,0,0],"texts":["The"," user","'s"," favorite"," color"," is"," te","al",","," as"," stated"," in"," the"," context"," provided"," by"," the"," plugin","."]}}
|
||||
{"type":"assistant/chunk","seq":26,"time":1783352161477,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":27,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"te"}}}
|
||||
{"type":"assistant/chunk","seq":28,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"al"}}}
|
||||
{"type":"assistant/chunk","seq":29,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user's favorite color is teal, as stated in the context provided by the plugin."}}}}
|
||||
{"type":"assistant/chunk","seq":30,"time":1783352161478,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"teal"}}}}
|
||||
{"type":"assistant/chunk","seq":31,"time":1783352161511,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":2892,"outputTokens":22,"cacheReadTokens":0,"reasoningTokens":19}}}}
|
||||
{"type":"assistant/chunk","seq":32,"time":1783352161512,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":33,"time":1785122243360,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user's favorite color is teal, as stated in the context provided by the plugin."},{"type":"text","text":"teal"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":2892,"outputTokens":22,"cacheReadTokens":0,"reasoningTokens":19}},"sourceEventSeqs":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":34,"time":1785122243360,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":35,"time":1785122243360,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
{"type":"session","version":0,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"hook/invoked","seq":1,"time":0,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"codex","handlerId":"codex:UserPromptSubmit:1"}}
|
||||
{"type":"hook/result","seq":2,"time":0,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"codex:UserPromptSubmit:1","decision":"block","exitCode":2,"stderrSummary":"blocked by codex policy hook","durationMs":0}}
|
||||
{"type":"prompt/blocked","seq":3,"time":0,"data":{"content":[{"type":"text","text":"Delete everything in the repo."}],"source":{"kind":"user"},"reason":"blocked by codex policy hook"}}
|
||||
{"type":"turn/end","seq":4,"time":0,"data":{"turn":1,"reason":{"kind":"rejected","reason":"blocked by codex policy hook"}}}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
{"type":"session","version":0,"id":"0bebc0f4-a089-4fde-9b6e-db9532cfd4de","createdAt":1783352209682,"cwd":"/tmp/acp-snap-cwd-aopaZV","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1783352209686,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"hook/invoked","seq":1,"time":1783352209687,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"codex","handlerId":"codex:UserPromptSubmit:1"}}
|
||||
{"type":"hook/result","seq":2,"time":1783352209706,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"codex:UserPromptSubmit:1","decision":"pass","exitCode":0,"durationMs":19.49695100000008}}
|
||||
{"type":"user/message","seq":3,"time":1783352209707,"data":{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":4,"time":1783352209707,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-codex"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":5,"time":1783352209707,"data":{"title":"What is my favorite color?","messageSeqs":[3],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":6,"time":1783352209709,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":7,"time":1783352209710,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783352210353,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":9,"time0":1783352210353,"data":{"turn":1,"step":1,"index":0,"dt":[117,31,26,28,1,0,0,0,29,0,0,27,1,0,27,1,27,0,1,0,0,28,0,0,0,29,0,0,1,0,0,27,0,0,0,0,1],"texts":["The"," user"," asked"," about"," their"," favorite"," color",","," and"," the"," context"," tells"," me"," they"," previously"," stated"," it","'s"," te","al","."," They"," asked"," me"," to"," reply"," with"," just"," the"," color"," and"," stop",","," without"," using"," any"," tools","."]}}
|
||||
{"type":"assistant/chunk","seq":47,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":48,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"te"}}}
|
||||
{"type":"assistant/chunk","seq":49,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"al"}}}
|
||||
{"type":"assistant/chunk","seq":50,"time":1783352210788,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked about their favorite color, and the context tells me they previously stated it's teal. They asked me to reply with just the color and stop, without using any tools."}}}}
|
||||
{"type":"assistant/chunk","seq":51,"time":1783352210788,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"teal"}}}}
|
||||
{"type":"assistant/chunk","seq":52,"time":1783352210788,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":2891,"outputTokens":41,"cacheReadTokens":0,"reasoningTokens":38}}}}
|
||||
{"type":"assistant/chunk","seq":53,"time":1783352210788,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":54,"time":1783352210790,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user asked about their favorite color, and the context tells me they previously stated it's teal. They asked me to reply with just the color and stop, without using any tools."},{"type":"text","text":"teal"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":2891,"outputTokens":41,"cacheReadTokens":0,"reasoningTokens":38}},"sourceEventSeqs":[8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":55,"time":1783352210790,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":56,"time":1783352210790,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"user/message","seq":1,"time":1785122250005,"data":{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":2,"time":1785122250006,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-codex"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":3,"time":1785122250006,"data":{"title":"What is my favorite color?","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":4,"time":1785122250036,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1785122250036,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1785122250040,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":7,"time0":1783352209709,"data":{"turn":1,"step":1,"index":0,"dt":[1,643,0,117,31,26,28,1,0,0,0,29,0,0,27,1,0,27,1,27,0,1,0,0,28,0,0,0,29,0,0,1,0,0,27,0,0],"texts":["The"," user"," asked"," about"," their"," favorite"," color",","," and"," the"," context"," tells"," me"," they"," previously"," stated"," it","'s"," te","al","."," They"," asked"," me"," to"," reply"," with"," just"," the"," color"," and"," stop",","," without"," using"," any"," tools","."]}}
|
||||
{"type":"assistant/chunk","seq":45,"time":1783352210754,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":46,"time":1783352210754,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"te"}}}
|
||||
{"type":"assistant/chunk","seq":47,"time":1783352210755,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"al"}}}
|
||||
{"type":"assistant/chunk","seq":48,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked about their favorite color, and the context tells me they previously stated it's teal. They asked me to reply with just the color and stop, without using any tools."}}}}
|
||||
{"type":"assistant/chunk","seq":49,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"teal"}}}}
|
||||
{"type":"assistant/chunk","seq":50,"time":1783352210787,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":2891,"outputTokens":41,"cacheReadTokens":0,"reasoningTokens":38}}}}
|
||||
{"type":"assistant/chunk","seq":51,"time":1783352210788,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":52,"time":1785122250042,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user asked about their favorite color, and the context tells me they previously stated it's teal. They asked me to reply with just the color and stop, without using any tools."},{"type":"text","text":"teal"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":2891,"outputTokens":41,"cacheReadTokens":0,"reasoningTokens":38}},"sourceEventSeqs":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":53,"time":1785122250043,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":54,"time":1785122250043,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":10,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_session_query_spill","name":"session_event_read","arguments":"{\"seq\":4}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","name":"session_event_read","arguments":"{\"seq\":4}"}}
|
||||
{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","content":[{"type":"text","text":"Session {{sessionId}} — Read request event 4 with\nTarget event seq 4:\n```json\n{\n \"type\": \"request/header\",\n \"seq\": 4,\n \"time\": 1784876318672,\n \"data\": {\n \"header\": {\n \"config\": {\n \"provider\": \"deepseek\",\n \"model\": \"deepseek-v4-flash\"\n },\n rmissions: one sentence for the user explaining why this exact file operation needs the wider access.\"\n }\n },\n \"required\": [\n \"file_path\",\n \"content\"\n ]\n }\n }\n ]\n },\n \"reason\": \"initial\"\n }\n}\n```\n\n(Omitted 36006 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-035d1d054/session-ac29d2afe494/505bce11df84-session_event_read.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","content":[{"type":"text","text":"Session {{sessionId}} — Read request event 4 with\nTarget event seq 4:\n```json\n{\n \"type\": \"request/header\",\n \"seq\": 4,\n \"time\": 1785167612540,\n \"data\": {\n \"header\": {\n \"config\": {\n \"provider\": \"deepseek\",\n \"model\": \"deepseek-v4-flash\"\n },\n rmissions: one sentence for the user explaining why this exact file operation needs the wider access.\"\n }\n },\n \"required\": [\n \"file_path\",\n \"content\"\n ]\n }\n }\n ]\n },\n \"reason\": \"initial\"\n }\n}\n```\n\n(Omitted 36007 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-035d1d054/session-0a508d3a5c8b/adedf3ca051a-session_event_read.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":13,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":14,"time":0,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
|
||||
@@ -2,29 +2,30 @@
|
||||
{"type":"turn/start","seq":0,"time":1783654655602,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1783654655603,"data":{"content":[{"type":"text","text":"Load the snapshot-skill skill with the skill tool, then reply DONE."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1783654655603,"data":{"title":"Load the snapshot-skill skill with","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1783654655608,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1783654655608,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}","messagePrefix":[{"role":"user","content":[{"type":"text","text":"<system-reminder>\nA skill is a reusable set of task-specific instructions. The following skills are available in this session:\n\n<available_skills>\n- `snapshot-skill`: Exercise project skill discovery and loading in snapshot tests.\n</available_skills>\n\nIf the user names a skill, or the task clearly matches a skill's description, call the `skill` tool with the exact skill name before taking task actions. Load all applicable skills, then follow their full instructions. This catalog contains summaries only; do not infer or follow a skill's instructions until it has been loaded.\n</system-reminder>"}]}]},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"Load the requested skill."}}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_skill_load","name":"skill","argumentsDelta":"{\"name\":\"snapshot-skill\"}"}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Load the requested skill."}}}}
|
||||
{"type":"assistant/chunk","seq":10,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":11,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":12,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":13,"time":1783654655609,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"Load the requested skill."},{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}},"sourceEventSeqs":[5,6,7,8,9,10,11,12],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":14,"time":1783654655609,"data":{"turn":1,"step":1,"callId":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}}
|
||||
{"type":"tool/result","seq":15,"time":1783654655610,"data":{"turn":1,"step":1,"callId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"snapshot-skill\">\n<skill_resources>\nBase directory for this skill: /var/folders/_g/59jgff8x2gqd39f5vy1wnbfc0000gn/T/acp-snap-cwd-DhYwNW/.dsh/skills/snapshot-skill\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\nFollow these snapshot-only instructions.\nResolve referenced resources relative to this skill directory.\n</skill_instructions>\n</skill_content>"}],"isError":false},"sourceEventSeqs":[14],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":16,"time":1783654655610,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":17,"time":1783654655610,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"The skill is loaded."}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":21,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"DONE"}}}
|
||||
{"type":"assistant/chunk","seq":22,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The skill is loaded."}}}}
|
||||
{"type":"assistant/chunk","seq":23,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"DONE"}}}}
|
||||
{"type":"assistant/chunk","seq":24,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}}}}
|
||||
{"type":"assistant/chunk","seq":25,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":26,"time":1783654655611,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The skill is loaded."},{"type":"text","text":"DONE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}},"sourceEventSeqs":[18,19,20,21,22,23,24,25],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":27,"time":1783654655611,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":28,"time":1783654655611,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"user/message","seq":3,"time":1784903324926,"data":{"content":[{"type":"text","text":"<system-reminder>\nA skill is a reusable set of task-specific instructions. The following skills are available in this session:\n\n<available_skills>\n- `snapshot-skill`: Exercise project skill discovery and loading in snapshot tests.\n</available_skills>\n\nIf the user names a skill, or the task clearly matches a skill's description, call the `skill` tool with the exact skill name before taking task actions. Load all applicable skills, then follow their full instructions. This catalog contains summaries only; do not infer or follow a skill's instructions until it has been loaded.\n</system-reminder>"}],"source":{"kind":"plugin","plugin":"dsh-tool-skill"}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":4,"time":1784903324927,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1784903324928,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"Load the requested skill."}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_skill_load","name":"skill","argumentsDelta":"{\"name\":\"snapshot-skill\"}"}}}
|
||||
{"type":"assistant/chunk","seq":10,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"Load the requested skill."}}}}
|
||||
{"type":"assistant/chunk","seq":11,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":12,"time":1783654655609,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":13,"time":1784903324935,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":14,"time":1784903324935,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"Load the requested skill."},{"type":"tool-call","id":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":100,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":5}},"sourceEventSeqs":[6,7,8,9,10,11,12,13],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":15,"time":1784903324936,"data":{"turn":1,"step":1,"callId":"call_skill_load","name":"skill","arguments":"{\"name\":\"snapshot-skill\"}"}}
|
||||
{"type":"tool/result","seq":16,"time":1784903324944,"data":{"turn":1,"step":1,"callId":"call_skill_load","content":[{"type":"text","text":"<skill_content name=\"snapshot-skill\">\n<skill_resources>\nBase directory for this skill: /var/folders/_g/59jgff8x2gqd39f5vy1wnbfc0000gn/T/acp-snap-cwd-DhYwNW/.dsh/skills/snapshot-skill\nResolve relative paths mentioned by this skill against the base directory before using them. Load referenced resources only as needed.\n</skill_resources>\n\n<skill_instructions>\nFollow these snapshot-only instructions.\nResolve referenced resources relative to this skill directory.\n</skill_instructions>\n</skill_content>"}],"isError":false},"sourceEventSeqs":[15],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":17,"time":1784903324944,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":18,"time":1784903324952,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"The skill is loaded."}}}
|
||||
{"type":"assistant/chunk","seq":21,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":22,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"DONE"}}}
|
||||
{"type":"assistant/chunk","seq":23,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The skill is loaded."}}}}
|
||||
{"type":"assistant/chunk","seq":24,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"DONE"}}}}
|
||||
{"type":"assistant/chunk","seq":25,"time":1783654655611,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}}}}
|
||||
{"type":"assistant/chunk","seq":26,"time":1784903324956,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":27,"time":1784903324956,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The skill is loaded."},{"type":"text","text":"DONE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":180,"outputTokens":10,"cacheReadTokens":0,"reasoningTokens":4}},"sourceEventSeqs":[19,20,21,22,23,24,25,26],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":28,"time":1784903324956,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":29,"time":1784903324956,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{"type":"turn/start","seq":38,"time":1783352137162,"data":{"turn":2,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":39,"time":1783352137163,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":40,"time":1783352137163,"data":{"turn":2,"step":1}}
|
||||
{"type":"request/header","seq":41,"time":1783352137163,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}}
|
||||
{"type":"request/header","seq":41,"time":1785142305260,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}}
|
||||
{"type":"assistant/chunk","seq":42,"time":1783352137783,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":43,"time0":1783352137783,"data":{"turn":2,"step":1,"index":0,"dt":[178,28,31,26,0,0,0,28,1,0,0,0,0,28,0,0,0,0,28,28,1,0,0,28,0,0,29,0,0,28,1,28,1],"texts":["The"," user"," asked"," me"," to"," remember"," the"," project"," cod","ew","ord"," \"","M","ARM","AL","ADE","\""," and"," now"," they","'re"," asking"," what"," it"," is","."," I"," should"," just"," reply"," with"," that"," word","."]}}
|
||||
{"type":"assistant/chunk","seq":77,"time":1783352138275,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
@@ -26,7 +26,7 @@
|
||||
{"type":"assistant/chunk","seq":82,"time":1783352138307,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."}}}}
|
||||
{"type":"assistant/chunk","seq":83,"time":1783352138307,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"MARMALADE"}}}}
|
||||
{"type":"assistant/chunk","seq":84,"time":1783352138307,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}}}}
|
||||
{"type":"assistant/chunk","seq":85,"time":1783352138307,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":86,"time":1783352138308,"data":{"turn":2,"step":1,"content":[{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."},{"type":"text","text":"MARMALADE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}},"sourceEventSeqs":[42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":87,"time":1783352138308,"data":{"turn":2,"step":1}}
|
||||
{"type":"turn/end","seq":88,"time":1783352138308,"data":{"turn":2,"reason":{"kind":"completed"}}}
|
||||
{"type":"assistant/chunk","seq":85,"time":1785142305270,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":86,"time":1785142305270,"data":{"turn":2,"step":1,"content":[{"type":"reasoning","text":"The user asked me to remember the project codeword \"MARMALADE\" and now they're asking what it is. I should just reply with that word."},{"type":"text","text":"MARMALADE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":97,"outputTokens":39,"cacheReadTokens":2816,"reasoningTokens":34}},"sourceEventSeqs":[42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":87,"time":1785142305270,"data":{"turn":2,"step":1}}
|
||||
{"type":"turn/end","seq":88,"time":1785142305270,"data":{"turn":2,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{"type":"turn/start","seq":32,"time":1783352147508,"data":{"turn":2,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":33,"time":1783352147509,"data":{"content":[{"type":"text","text":"What is the project codeword mentioned earlier in this conversation? Reply with exactly that one word and nothing else."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":34,"time":1783352147509,"data":{"turn":2,"step":1}}
|
||||
{"type":"request/header","seq":35,"time":1783352147509,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}}
|
||||
{"type":"request/header","seq":35,"time":1785142306299,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"resume"}}
|
||||
{"type":"assistant/chunk","seq":36,"time":1783352147925,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":37,"time0":1783352147925,"data":{"turn":2,"step":1,"index":0,"dt":[94,29,1,0,27,0,1,0,0,0,29,0,0,0,35,0,0,0,0,26,29,31,0,30,0,0,27,1,27,0],"texts":["The"," user"," is"," asking"," me"," to"," recall"," the"," project"," cod","ew","ord"," that"," was"," mentioned"," earlier"," in"," the"," conversation","."," I"," was"," told"," to"," remember"," it",":"," SA","FF","RON","."]}}
|
||||
{"type":"assistant/chunk","seq":68,"time":1783352148313,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
@@ -26,7 +26,7 @@
|
||||
{"type":"assistant/chunk","seq":72,"time":1783352148345,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."}}}}
|
||||
{"type":"assistant/chunk","seq":73,"time":1783352148345,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"SAFFRON"}}}}
|
||||
{"type":"assistant/chunk","seq":74,"time":1783352148345,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}}}}
|
||||
{"type":"assistant/chunk","seq":75,"time":1783352148345,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":76,"time":1783352148345,"data":{"turn":2,"step":1,"content":[{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."},{"type":"text","text":"SAFFRON"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}},"sourceEventSeqs":[36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":77,"time":1783352148345,"data":{"turn":2,"step":1}}
|
||||
{"type":"turn/end","seq":78,"time":1783352148345,"data":{"turn":2,"reason":{"kind":"completed"}}}
|
||||
{"type":"assistant/chunk","seq":75,"time":1785142306309,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":76,"time":1785142306309,"data":{"turn":2,"step":1,"content":[{"type":"reasoning","text":"The user is asking me to recall the project codeword that was mentioned earlier in the conversation. I was told to remember it: SAFFRON."},{"type":"text","text":"SAFFRON"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":95,"outputTokens":35,"cacheReadTokens":2816,"reasoningTokens":31}},"sourceEventSeqs":[36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":77,"time":1785142306309,"data":{"turn":2,"step":1}}
|
||||
{"type":"turn/end","seq":78,"time":1785142306309,"data":{"turn":2,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -2,24 +2,25 @@
|
||||
{"type":"turn/start","seq":0,"time":1783778297065,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1783778297066,"data":{"content":[{"type":"text","text":"Read nested/task.txt with the read tool, then reply DONE."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1783778297066,"data":{"title":"Read nested/task.txt with the read","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1783778297069,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1783778297070,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}","messagePrefix":[{"role":"user","content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"}]}]},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_workspace_read","name":"read","argumentsDelta":"{\"file_path\":\"nested/task.txt\"}"}}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":10,"time":1783778297070,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":11,"time":1783778297070,"data":{"turn":1,"step":1,"callId":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}}
|
||||
{"type":"tool/result","seq":12,"time":1783778297072,"data":{"turn":1,"step":1,"callId":"call_workspace_read","content":[{"type":"text","text":"<path>{{cwd}}/nested/task.txt</path>\n<type>file</type>\n<content>\n1: snapshot task\n\n(End of file - total 1 lines)\n</content>"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":13,"time":1783778297072,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"plugin","plugin":"workspace-context"},"meta":{"kind":"workspace-instructions","version":1,"changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":14,"time":1783778297072,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":15,"time":1783778297072,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DONE"}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":21,"time":1783778297073,"data":{"turn":1,"step":2,"content":[{"type":"text","text":"DONE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[16,17,18,19,20],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":22,"time":1783778297073,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":23,"time":1783778297073,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
{"type":"user/message","seq":3,"time":1784903339799,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","baseline":true,"changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":4,"time":1784903339799,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1784903339800,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":6,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_workspace_read","name":"read","argumentsDelta":"{\"file_path\":\"nested/task.txt\"}"}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1783778297070,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":10,"time":1784903339801,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":11,"time":1784903339801,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[6,7,8,9,10],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":12,"time":1784903339802,"data":{"turn":1,"step":1,"callId":"call_workspace_read","name":"read","arguments":"{\"file_path\":\"nested/task.txt\"}"}}
|
||||
{"type":"tool/result","seq":13,"time":1784903339813,"data":{"turn":1,"step":1,"callId":"call_workspace_read","content":[{"type":"text","text":"<path>{{cwd}}/nested/task.txt</path>\n<type>file</type>\n<content>\n1: snapshot task\n\n(End of file - total 1 lines)\n</content>"}],"isError":false},"sourceEventSeqs":[12],"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":14,"time":1784903339813,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]}},"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":15,"time":1784903339813,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":16,"time":1784903339820,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"DONE"}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1783778297073,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":2}}}}
|
||||
{"type":"assistant/chunk","seq":21,"time":1784903339821,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":22,"time":1784903339821,"data":{"turn":1,"step":2,"content":[{"type":"text","text":"DONE"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":2}},"sourceEventSeqs":[17,18,19,20,21],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":23,"time":1784903339821,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":24,"time":1784903339822,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
README.md: 1309fe9b2935d3224f097ceb2e80501c8075a933
|
||||
README.zh.md: 2e3e7d7206d0d676ae7d9c9b3a2c2f8be26aafe7
|
||||
# pnpm run verify-translation-pairing --write examples/cordis-agent/README.md
|
||||
README.md: 55970e932bc16d8361932daa9ea55af83ef73d33
|
||||
README.zh.md: c2873b6de96a8b47ad8ea4fb2cf03a7501406300
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The self-referential harness demo: the DeepSeek V4 coding spine on the full-screen TUI plus [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md), which hands the model three tools over the **live cordis runtime it is running inside** — inspect it, mount new plugins into it, and dispose them again. The `ctx.fs` and `ctx.web` services are mounted (provider-only, no model-facing file/web tools) so the plugins the agent writes have real capabilities to build on; Node built-ins are trapped in the sandbox and redirect to those services. The design (sandbox semantics, mount lifecycle, cross-mount composition, caveats) lives in [the toolset Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
|
||||
The self-referential harness demo: the DeepSeek V4 coding spine on the full-screen TUI plus [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md), which lets the model inspect the current DSH process, mount in-memory temporary Plugins, and unmount them. Temporary Plugins remain active across turns but disappear on unmount, toolset unload, or DSH restart; they create no files or configuration and may affect other sessions in the process. The `ctx.fs` and `ctx.web` services are provider-only capabilities available to those Plugins. The design lives in [the toolset Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md).
|
||||
|
||||
## Run it
|
||||
|
||||
@@ -10,26 +10,28 @@ The self-referential harness demo: the DeepSeek V4 coding spine on the full-scre
|
||||
# repo root .env (gitignored) or exported env:
|
||||
# DEEPSEEK_API_KEY=sk-…
|
||||
# DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API
|
||||
pnpm run demo:cordis
|
||||
pnpm run demo:cordis # TUI (default)
|
||||
pnpm run demo:cordis web # browser UI at http://127.0.0.1:3081
|
||||
pnpm run demo:cordis acp # ACP server
|
||||
```
|
||||
|
||||
The intended demo is staged — verify the listener link first, then let the agent extend itself:
|
||||
|
||||
```
|
||||
> Mount a plugin that listens to the 'agent/status' event and logs every status change, then run `echo hi` with bash.
|
||||
> Mount a temporary Plugin that listens to the 'agent/status' event and logs every status change, then run `echo hi` with bash.
|
||||
[tool call] cordis_mount({"code": "return { name: 'status-logger', apply(ctx) { ctx.on('agent/status', (agent, status) => console.log('status →', status)) } }"})
|
||||
[tool result] mounted dyn-1 (plugin "status-logger", state: active)
|
||||
[tool result] Temporary Plugin dyn-1 is running (plugin "status-logger"; available until unmounted or DSH restarts).
|
||||
[tool call] bash({"command": "echo hi"})
|
||||
[cordis:dyn-1] status → … ← the mounted listener firing, live
|
||||
[cordis:dyn-1] status → … ← the temporary listener firing, live
|
||||
> Now give yourself a reverse_text tool and use it on "harness".
|
||||
[tool call] cordis_mount({"code": "return { name: 'reverse-text', inject: ['tools'], apply(ctx) { ctx.tools.register(harness.defineTool({ name: 'reverse_text', … })) } }"})
|
||||
[tool call] reverse_text({"text": "harness"}) ← a tool the agent built for itself, one step earlier
|
||||
> Unmount both.
|
||||
> Unmount both temporary Plugins.
|
||||
[tool call] cordis_unmount({"id": "dyn-1"})
|
||||
```
|
||||
|
||||
Ask for `cordis_inspect` with `what: "api"` or `what: "events"` to see the generated service/event reference the agent writes plugin code against, and try two cooperating mounts (`ctx.provide` in one, `inject` in the other) to watch cordis park and revive the consumer.
|
||||
Ask for `cordis_inspect` with `what: "api"` or `what: "events"` to see the generated service/event reference used to write Plugin code, and mount two cooperating temporary Plugins (`ctx.provide` in one, `inject` in the other) to watch Cordis park and revive the consumer.
|
||||
|
||||
## End-to-end tests
|
||||
|
||||
`tests/keyless-smoke.e2e.ts` boots the real `cordis.yml` through the Loader with a dummy key and asserts the banner, package-name resolution, and clean EOF exit. `tests/cordis-tools.e2e.ts` is the with-key smoke: a real model mounts a status listener and the test verifies its tagged console line, creates and uses a `reverse_text` tool, and composes two mounts through provide/inject. [`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) carries the unit coverage under the per-file 100% gate.
|
||||
`tests/keyless-smoke.e2e.ts` boots the real `cordis.yml` through the Loader with a dummy key and asserts the banner, package-name resolution, and clean EOF exit. `tests/cordis-tools.e2e.ts` is the with-key smoke: a real model mounts a temporary status listener and the test verifies its tagged console line, creates and uses a `reverse_text` tool, and composes two temporary Plugins through provide/inject. [`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) carries the unit coverage under the per-file 100% gate.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
自指 harness 演示:在全屏 TUI 上运行 DeepSeek V4 编码主干,并加载 [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md)。后者通过 agent(智能体)所在的 **实时 cordis 运行时** 向模型提供三个工具:检查运行时、将新插件挂载到其中,以及再次释放它们。`ctx.fs` 和 `ctx.web` 服务也会挂载(仅作为提供方,不包含面向模型的文件/Web 工具),使 agent 编写的插件可以构建于真实能力之上;Node 内置模块在沙箱中被截获并重定向到这些服务。设计(沙箱语义、挂载生命周期、跨挂载组合、注意事项)详见[工具集 Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
自指 harness 演示:在全屏 TUI 上运行 DeepSeek V4 编码主干,并加载 [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md)。后者让模型检查当前 DSH 进程、挂载仅存于内存的临时 Plugin,并再次卸载它们。临时 Plugin 可跨 turn 保持活跃,但会在卸载、工具集卸载或 DSH 重启后消失;它们不创建文件或配置,也可能影响同一进程中的其他 session。`ctx.fs` 和 `ctx.web` 是这些 Plugin 可用的 provider-only 能力。设计详见[工具集 Agent Note](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
|
||||
## 运行
|
||||
|
||||
@@ -10,26 +10,28 @@
|
||||
# repo root .env (gitignored) or exported env:
|
||||
# DEEPSEEK_API_KEY=sk-…
|
||||
# DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API
|
||||
pnpm run demo:cordis
|
||||
pnpm run demo:cordis # TUI (default)
|
||||
pnpm run demo:cordis web # browser UI at http://127.0.0.1:3081
|
||||
pnpm run demo:cordis acp # ACP server
|
||||
```
|
||||
|
||||
预期演示分阶段进行:先验证监听器链接,再让 agent 扩展自身:
|
||||
|
||||
```
|
||||
> Mount a plugin that listens to the 'agent/status' event and logs every status change, then run `echo hi` with bash.
|
||||
> Mount a temporary Plugin that listens to the 'agent/status' event and logs every status change, then run `echo hi` with bash.
|
||||
[tool call] cordis_mount({"code": "return { name: 'status-logger', apply(ctx) { ctx.on('agent/status', (agent, status) => console.log('status →', status)) } }"})
|
||||
[tool result] mounted dyn-1 (plugin "status-logger", state: active)
|
||||
[tool result] Temporary Plugin dyn-1 is running (plugin "status-logger"; available until unmounted or DSH restarts).
|
||||
[tool call] bash({"command": "echo hi"})
|
||||
[cordis:dyn-1] status → … ← the mounted listener firing, live
|
||||
[cordis:dyn-1] status → … ← the temporary listener firing, live
|
||||
> Now give yourself a reverse_text tool and use it on "harness".
|
||||
[tool call] cordis_mount({"code": "return { name: 'reverse-text', inject: ['tools'], apply(ctx) { ctx.tools.register(harness.defineTool({ name: 'reverse_text', … })) } }"})
|
||||
[tool call] reverse_text({"text": "harness"}) ← a tool the agent built for itself, one step earlier
|
||||
> Unmount both.
|
||||
> Unmount both temporary Plugins.
|
||||
[tool call] cordis_unmount({"id": "dyn-1"})
|
||||
```
|
||||
|
||||
请求 `cordis_inspect` 并使用 `what: "api"` 或 `what: "events"`,即可查看为 agent 生成、供其编写插件时参考的服务/事件资料。还可尝试两个协作挂载(一个中调用 `ctx.provide`,另一个中使用 `inject`),观察 cordis 如何暂停并恢复消费方。
|
||||
请求 `cordis_inspect` 并使用 `what: "api"` 或 `what: "events"`,即可查看编写 Plugin 代码所用的生成服务/事件资料。还可挂载两个协作临时 Plugin(一个中调用 `ctx.provide`,另一个中使用 `inject`),观察 Cordis 如何暂停并恢复消费方。
|
||||
|
||||
## 端到端测试
|
||||
|
||||
`tests/keyless-smoke.e2e.ts` 使用虚拟密钥通过 Loader 启动真实 `cordis.yml`,并断言横幅、包名解析和 EOF 后干净退出。`tests/cordis-tools.e2e.ts` 是带密钥的冒烟测试:真实模型挂载状态监听器,测试验证其带标记的 console 行;然后创建并使用 `reverse_text` 工具,再通过 provide/inject 组合两个挂载。[`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) 在每文件 100% 覆盖率门禁下承载单元覆盖。
|
||||
`tests/keyless-smoke.e2e.ts` 使用虚拟密钥通过 Loader 启动真实 `cordis.yml`,并断言横幅、包名解析和 EOF 后干净退出。`tests/cordis-tools.e2e.ts` 是带密钥的冒烟测试:真实模型挂载一个临时状态 listener,测试验证其带标记的 console 行;然后创建并使用 `reverse_text` 工具,再通过 provide/inject 组合两个临时 Plugin。[`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) 在每文件 100% 覆盖率门禁下承载单元覆盖。
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
# Cordis Agent App Composition
|
||||
|
||||
The self-referential demo puts @deepseek-ai/dsh-tool-cordis on the coding spine, letting the agent inspect its own runtime and mount/unmount plugins into it.
|
||||
The self-referential demo puts @deepseek-ai/dsh-tool-cordis on the coding spine, letting the agent inspect its current-process runtime and mount or unmount in-memory temporary Plugins.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Self-referential TUI demo: the coding spine plus tools to inspect the live
|
||||
# service/plugin/tool/mount/API/event state, mount a model-written plugin under
|
||||
# `cordis-dynamic`, and quiescently unmount it. The app bin loads the gitignored
|
||||
# service/plugin/tool/temporary/API/event state, mount a model-written temporary
|
||||
# Plugin, and quiescently unmount it. The app bin loads the gitignored
|
||||
# root `.env` before reading the required DeepSeek key and optional base URL.
|
||||
# Trust stance: the vm and context façade limit accidental global/framework
|
||||
# access but are not a security boundary; mounted code can reach live capabilities
|
||||
# access but are not a security boundary; temporary Plugin code reaches live capabilities
|
||||
# such as `ctx.bash`. Grant this toolset like bash access. See
|
||||
# ../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md.
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
persistenceRoot: './.sessions'
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
welcome: 'cordis-agent ready. Ask it to inspect its runtime, mount a listener, or invent a tool for itself.'
|
||||
welcome: 'cordis-agent ready. Ask it to inspect its runtime, mount a temporary listener, or invent a temporary tool for itself.'
|
||||
persona: |
|
||||
You are cordis-agent, a self-referential harness demo powered by the
|
||||
{{model}} model.
|
||||
@@ -72,9 +72,11 @@
|
||||
You run INSIDE a cordis plugin runtime, and your cordis_* tools operate
|
||||
on that live runtime: cordis_inspect to look around (its `api` and
|
||||
`events` sections document the service methods, type shapes, and events
|
||||
your plugin code can use), cordis_mount to add a plugin (an event
|
||||
listener, a brand-new tool for yourself, or a service other mounts
|
||||
inject), cordis_unmount to clean one up. In mounted code, NEVER use Node
|
||||
your Plugin code can use), cordis_mount to mount an in-memory temporary
|
||||
Plugin (an event listener, a brand-new tool for yourself, or a service
|
||||
another temporary Plugin injects), cordis_unmount to clean one up. These
|
||||
Plugins remain across turns but disappear on unmount, toolset unload, or
|
||||
DSH restart and may affect other sessions in this process. In Plugin code, NEVER use Node
|
||||
built-ins (require/setTimeout/fetch) — use the runtime's cordis services
|
||||
via inject: fs, web, bash, and timer (ctx.setTimeout). Prefer small
|
||||
single-purpose plugins, prefer plain notification events over waterfall
|
||||
|
||||
@@ -37,16 +37,16 @@ function resultText(result: { content: { type: string; text?: string }[] }): str
|
||||
}
|
||||
|
||||
describe.skipIf(!process.env.DEEPSEEK_API_KEY)('cordis tools: a real model modifies its own runtime', () => {
|
||||
it('mounts a status listener whose tagged output actually fires, then unmounts it', async () => {
|
||||
it('mounts a temporary status listener whose tagged output actually fires, then unmounts it', async () => {
|
||||
ctx = await cordisHarness()
|
||||
const log = vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
const agent = ctx.agentLoop.create(SessionId('cordis-e2e-listener'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Use cordis_mount to mount a plugin that listens to the \'agent/status\' '
|
||||
+ 'cordis event and logs every change with console.log. Reply "mounted" once done.',
|
||||
}])
|
||||
text: 'Use cordis_mount to create a temporary Plugin that listens to the \'agent/status\' '
|
||||
+ 'Cordis event and logs every change with console.log. Reply "running" once done.',
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
// The WORLD check: the turn's own running→idle transition must have driven
|
||||
@@ -54,32 +54,32 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('cordis tools: a real model modif
|
||||
expect(taggedCalls(log).length).toBeGreaterThan(0)
|
||||
const mid = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('verify-mounted'), name: 'cordis_inspect', arguments: { what: 'dynamic' },
|
||||
callId: CallId('verify-mounted'), name: 'cordis_inspect', arguments: { what: 'temporary' },
|
||||
})
|
||||
expect(resultText(mid)).toContain('dyn-')
|
||||
|
||||
agent.followup([{ type: 'text', text: 'Now unmount the plugin you just mounted.' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'Now unmount the temporary Plugin you just mounted.' }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
const after = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('verify-unmounted'), name: 'cordis_inspect', arguments: { what: 'dynamic' },
|
||||
callId: CallId('verify-unmounted'), name: 'cordis_inspect', arguments: { what: 'temporary' },
|
||||
})
|
||||
expect(resultText(after)).toContain('(no dynamic plugins mounted)')
|
||||
expect(resultText(after)).toContain('No temporary Plugins are running.')
|
||||
}, 120_000)
|
||||
|
||||
it('builds itself a reverse_text tool and actually calls it', async () => {
|
||||
ctx = await cordisHarness()
|
||||
const agent = ctx.agentLoop.create(SessionId('cordis-e2e-selftool'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Give yourself a new tool: use cordis_mount to mount a plugin with '
|
||||
text: 'Give yourself a new tool: use cordis_mount to create a temporary Plugin with '
|
||||
+ 'inject ["tools"] that calls harness.registerTool(ctx, harness.defineTool({...})) '
|
||||
+ 'to register a tool named reverse_text with one required string parameter '
|
||||
+ '"text", returning the text reversed. Then CALL reverse_text with the '
|
||||
+ 'exact text "harness" and report its exact output.',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
// World checks: the tool exists in the registry, was invoked as a real tool call, and its
|
||||
@@ -115,19 +115,19 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('cordis tools: a real model modif
|
||||
).toBe(true)
|
||||
}, 120_000)
|
||||
|
||||
it('composes two mounts through provide/inject, and unmounting the provider parks the consumer', async () => {
|
||||
it('composes two temporary Plugins through provide/inject, and unmounting the provider parks the consumer', async () => {
|
||||
ctx = await cordisHarness()
|
||||
const agent = ctx.agentLoop.create(SessionId('cordis-e2e-compose'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Mount TWO separate plugins with cordis_mount. First a provider: apply calls '
|
||||
text: 'Mount TWO separate temporary Plugins with cordis_mount. First a provider: apply calls '
|
||||
+ 'ctx.provide(\'shouter\', { shout: (s) => s.toUpperCase() }). Second a consumer with '
|
||||
+ 'inject ["shouter", "tools"] that registers (via harness.registerTool + harness.defineTool) '
|
||||
+ 'a tool named shout_text with one required string parameter "text" whose execute returns '
|
||||
+ 'ctx.shouter.shout(args.text) as a text content block. Then CALL shout_text with "quiet" '
|
||||
+ 'and report the exact output.',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
// World checks: the service is really in the store, the tool really ran.
|
||||
@@ -144,16 +144,16 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('cordis tools: a real model modif
|
||||
.flatMap(event => event.data.content.filter(block => block.type === 'text').map(block => block.text))
|
||||
expect(shoutResults.some(text => text.includes('QUIET'))).toBe(true)
|
||||
|
||||
agent.followup([{ type: 'text', text: 'Now unmount ONLY the provider plugin (the one that provided shouter).' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'Now unmount ONLY the provider temporary Plugin (the one that provided shouter).' }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
// The consumer must have been parked by cordis itself: service gone,
|
||||
// dependent tool unregistered, dynamic table naming the missing service.
|
||||
// dependent tool unregistered, temporary section naming the missing service.
|
||||
expect(ctx.get('shouter')).toBeUndefined()
|
||||
expect(ctx.tools.get('shout_text')).toBeUndefined()
|
||||
const after = await ctx.tools.execute({
|
||||
signal: testToolSignal,
|
||||
callId: CallId('verify-parked'), name: 'cordis_inspect', arguments: { what: 'dynamic' },
|
||||
callId: CallId('verify-parked'), name: 'cordis_inspect', arguments: { what: 'temporary' },
|
||||
})
|
||||
expect(resultText(after)).toContain('waiting for: shouter')
|
||||
}, 120_000)
|
||||
|
||||
@@ -15,8 +15,8 @@ import * as ToolCordis from '@deepseek-ai/dsh-tool-cordis'
|
||||
|
||||
const PERSONA = 'You are cordis-agent, a self-referential harness demo. '
|
||||
+ 'Your cordis_* tools operate on the live cordis runtime you run inside: '
|
||||
+ 'cordis_inspect to look around, cordis_mount to add a plugin, cordis_unmount '
|
||||
+ 'to clean one up. Follow the tool descriptions exactly and report results briefly.'
|
||||
+ 'cordis_inspect to look around, cordis_mount to mount a temporary Plugin, cordis_unmount '
|
||||
+ 'to unmount one. Follow the tool descriptions exactly and report results briefly.'
|
||||
|
||||
export async function cordisHarness(): Promise<Context> {
|
||||
const ctx = new Context()
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
# Replay counterpart to goal.cordis.yml; only the live model is replaced.
|
||||
# Replay counterpart to goal.cordis.yml. It includes cordis.yml directly because
|
||||
# a config patch cannot target an entry behind a nested include, then restates
|
||||
# the goal overlay while replacing the live model with keyless replay.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./goal.cordis.yml
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- insert:
|
||||
- id: goal
|
||||
name: '@deepseek-ai/dsh-goal'
|
||||
- id: tool-goal
|
||||
name: '@deepseek-ai/dsh-tool-goal'
|
||||
- id: llm-replay
|
||||
name: '@deepseek-ai/dsh-llm-replay'
|
||||
|
||||
12
examples/headless-agent/retry.cordis.snapshot.yml
Normal file
12
examples/headless-agent/retry.cordis.snapshot.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
# Keyless provider-retry composition for the headless stream-json snapshot.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- insert:
|
||||
- id: retry-snapshot-backend
|
||||
name: './tests/fixtures/retry-snapshot-backend.mjs'
|
||||
@@ -251,7 +251,7 @@ describe('Code Mode typed values: keyless real-worker contracts', () => {
|
||||
expect(ctx.tasks.list()).toEqual([])
|
||||
}, 15_000)
|
||||
|
||||
it('uses cordis_mount DTO ids directly for active and pending mounts, then confirms removal', async () => {
|
||||
it('uses cordis_mount DTO ids directly for running and pending temporary Plugins, then confirms removal', async () => {
|
||||
ctx = await typedCodeModeHarness()
|
||||
await ctx.plugin(ToolCordis)
|
||||
|
||||
@@ -262,14 +262,14 @@ describe('Code Mode typed values: keyless real-worker contracts', () => {
|
||||
const pending = await tools.cordis_mount({
|
||||
code: "return { name: 'pending-code-mode-plugin', inject: ['missing-code-mode-service'], apply(ctx) {} }",
|
||||
});
|
||||
const before = await tools.cordis_inspect({ what: 'dynamic' });
|
||||
const unmounted = await tools.cordis_unmount({ id: active.id });
|
||||
const after = await tools.cordis_inspect({ what: 'dynamic' });
|
||||
const before = await tools.cordis_inspect({ what: 'temporary' });
|
||||
const stopped = await tools.cordis_unmount({ id: active.id });
|
||||
const after = await tools.cordis_inspect({ what: 'temporary' });
|
||||
await tools.cordis_unmount({ id: pending.id });
|
||||
return {
|
||||
active,
|
||||
pending,
|
||||
unmounted,
|
||||
stopped,
|
||||
beforeContainsId: before.includes(active.id),
|
||||
afterContainsId: after.includes(active.id),
|
||||
};
|
||||
@@ -290,7 +290,7 @@ describe('Code Mode typed values: keyless real-worker contracts', () => {
|
||||
provides: [],
|
||||
waitingFor: ['missing-code-mode-service'],
|
||||
},
|
||||
unmounted: { id: 'dyn-1', pluginName: 'active-code-mode-plugin' },
|
||||
stopped: { id: 'dyn-1', pluginName: 'active-code-mode-plugin' },
|
||||
beforeContainsId: true,
|
||||
afterContainsId: false,
|
||||
})
|
||||
@@ -314,12 +314,12 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('Code Mode: real model writes a p
|
||||
ctx = await codeModeHarness(workdir)
|
||||
const agent = ctx.agentLoop.create(SessionId('e2e-code-mode'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Using one run_code program: run `echo alpha-7` with the bash tool, run `echo beta-9` with the bash tool, '
|
||||
+ 'then write both outputs joined by a plus sign into combined.txt (bash heredoc or redirect), '
|
||||
+ 'and return only the joined string.',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
const events: SessionEvent[] = [...agent.session.events]
|
||||
|
||||
@@ -366,21 +366,17 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('Code Mode: real model writes a p
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek-v4-flash' },
|
||||
})
|
||||
|
||||
handle.agent.followup([{
|
||||
handle.agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Use one run_code program to call tools.read on pkg/deep/task.txt. After it finishes, answer: Code Mode workspace handshake?',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, handle.agent)
|
||||
|
||||
const events: SessionEvent[] = [...handle.agent.session.events]
|
||||
const dispatch = events.find(event => event.type === 'tool/code-dispatch' && event.data.name === 'read')
|
||||
const outerResult = events.find(event => event.type === 'tool/result')
|
||||
const workspaceContext = events.find(event => event.type === 'user/message'
|
||||
&& event.data.source.kind === 'plugin'
|
||||
&& typeof event.data.meta === 'object'
|
||||
&& event.data.meta !== null
|
||||
&& !Array.isArray(event.data.meta)
|
||||
&& event.data.meta.kind === 'workspace-instructions')
|
||||
&& event.data.source.kind === 'workspace-instructions')
|
||||
expect(dispatch).toBeDefined()
|
||||
expect(outerResult).toBeDefined()
|
||||
expect(workspaceContext).toBeDefined()
|
||||
|
||||
@@ -56,12 +56,12 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('coding task: fix a failing test
|
||||
ctx = await codingHarness(workdir, { persona: SYSTEM_PROMPT })
|
||||
const agent = ctx.agentLoop.create(SessionId('e2e-task'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'In the current directory, `node add.test.js` fails because add.js has a bug. '
|
||||
+ 'Fix add.js so the test passes, run `node add.test.js` to verify, and report the result. '
|
||||
+ 'Do not modify add.test.js.',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
// The agent claims success…
|
||||
|
||||
@@ -46,12 +46,12 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('compaction: a long session compa
|
||||
})
|
||||
const agent = ctx.agentLoop.create(SessionId('e2e-compaction'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{
|
||||
agent.followup({ content: [{
|
||||
type: 'text',
|
||||
text: 'Read file1.txt, file2.txt, file3.txt, and file4.txt one at a '
|
||||
+ 'time using cat (a separate bash command for each). After reading all four, tell me how '
|
||||
+ 'many files you read and the number mentioned in file1.txt.',
|
||||
}])
|
||||
}], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
const events = [...agent.session.events]
|
||||
|
||||
@@ -59,7 +59,7 @@ export const inject = ['llm']
|
||||
/** Register the keyless `cli-mock` adapter. */
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.llm.registerAdapter(['cli-mock'], new CliMockAdapter())
|
||||
ctx.on('agent/request', async (_agent, _turn, step, _config, _signal, next) => {
|
||||
ctx.on('agent/request', async (_agent, _turn, step, _signal, next) => {
|
||||
const config = await next()
|
||||
return step === 2 ? { ...config, reasoningEffort: OFF } : config
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ export const name = 'seed-goal'
|
||||
export const inject = ['goals']
|
||||
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.on('agent/pre-step', (agent) => {
|
||||
ctx.on('agent/step', (agent) => {
|
||||
if (ctx.goals.get(agent) !== undefined) return
|
||||
ctx.goals.create(agent, {
|
||||
objective: 'Prove the composed goal survives in the session log',
|
||||
|
||||
53
examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs
vendored
Normal file
53
examples/headless-agent/tests/fixtures/retry-snapshot-backend.mjs
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/** Deterministic provider adapter for the headless retry-policy snapshot. */
|
||||
|
||||
import {
|
||||
LlmAdapter,
|
||||
LlmError,
|
||||
resolveRetryPolicy,
|
||||
} from '@deepseek-ai/dsh-llm'
|
||||
|
||||
class RetrySnapshotAdapter extends LlmAdapter {
|
||||
requests = 0
|
||||
firstMessages
|
||||
policy = resolveRetryPolicy({
|
||||
mode: 'normal',
|
||||
maxRetries: 1,
|
||||
retryableCodes: ['RATE_LIMIT'],
|
||||
backoff: { initialDelayMs: 1, maxDelayMs: 1, jitterRatio: 0 },
|
||||
}, 'retry-snapshot-backend.retryPolicy')
|
||||
|
||||
providerRetryPolicy() {
|
||||
return this.policy
|
||||
}
|
||||
|
||||
async * stream(options) {
|
||||
const messages = JSON.stringify(options.messages)
|
||||
this.requests++
|
||||
if (this.requests === 1) {
|
||||
this.firstMessages = messages
|
||||
throw new LlmError('snapshot transient failure', 'RATE_LIMIT', { status: 429 })
|
||||
}
|
||||
if (this.requests === 2 && messages !== this.firstMessages) {
|
||||
throw new Error('retry snapshot changed the model-visible messages')
|
||||
}
|
||||
const text = 'RETRY_OK'
|
||||
yield { type: 'block-start', index: 0, blockType: 'text' }
|
||||
yield { type: 'text-delta', index: 0, text }
|
||||
yield { type: 'block-end', index: 0, block: { type: 'text', text } }
|
||||
yield { type: 'usage', usage: { inputTokens: 4, outputTokens: 2 } }
|
||||
yield { type: 'finish', reason: { kind: 'stop' } }
|
||||
}
|
||||
}
|
||||
|
||||
/** Cordis plugin name. */
|
||||
export const name = 'retry-snapshot-backend'
|
||||
/** Required LLM registry service. */
|
||||
export const inject = ['llm']
|
||||
|
||||
/**
|
||||
* Register the deterministic provider adapter.
|
||||
* @param {import('cordis').Context} ctx - plugin context carrying the LLM service.
|
||||
*/
|
||||
export function apply(ctx) {
|
||||
ctx.llm.registerAdapter(['deepseek'], new RetrySnapshotAdapter())
|
||||
}
|
||||
43
examples/headless-agent/tests/fixtures/telemetry-otel-driver.ts
vendored
Normal file
43
examples/headless-agent/tests/fixtures/telemetry-otel-driver.ts
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Test driver: start a mock OTLP/HTTP collector, boot the telemetry Loader
|
||||
* composition against it, run one turn whose prompt carries a fixture
|
||||
* credential, then persist everything the collector captured to
|
||||
* `./otlp-captures.json` for the e2e's inspect step.
|
||||
*/
|
||||
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import { createServer } from 'node:http'
|
||||
import { once } from 'node:events'
|
||||
import { boot, resolveConfigPath } from '@deepseek-ai/dsh-app-boot'
|
||||
import { runOneShot } from '@deepseek-ai/dsh-cli-demo/src/cli.ts'
|
||||
|
||||
const configPath = process.argv[2]
|
||||
if (configPath === undefined) throw new Error('telemetry-otel driver requires a config path')
|
||||
|
||||
const captures: unknown[] = []
|
||||
const server = createServer((request, response) => {
|
||||
const chunks: Buffer[] = []
|
||||
request.on('data', chunk => chunks.push(chunk as Buffer))
|
||||
request.on('end', () => {
|
||||
captures.push(JSON.parse(Buffer.concat(chunks).toString()))
|
||||
response.writeHead(200, { 'content-type': 'application/json' }).end('{}')
|
||||
})
|
||||
})
|
||||
server.listen(0, '127.0.0.1')
|
||||
await once(server, 'listening')
|
||||
const address = server.address()
|
||||
if (address === null || typeof address === 'string') throw new Error('collector has no port')
|
||||
process.env.DSH_TELEMETRY_E2E_URL = `http://127.0.0.1:${address.port}/v1/logs`
|
||||
|
||||
const ctx = await boot('telemetry-otel-e2e', resolveConfigPath(configPath, undefined))
|
||||
try {
|
||||
// The fixture credential rides the model-visible user message; the exported
|
||||
// copy must scrub it while the canonical log keeps the original bytes.
|
||||
await runOneShot(ctx, { task: 'prove telemetry with key sk-e2efixture1234567890' })
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
}
|
||||
await writeFile('./otlp-captures.json', JSON.stringify(captures))
|
||||
server.close()
|
||||
server.closeAllConnections()
|
||||
28
examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml
vendored
Normal file
28
examples/headless-agent/tests/fixtures/telemetry-otel.cordis.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Test-only composition: session-telemetry-otel through the real Loader/app
|
||||
# path, exporting to the mock OTLP collector the driver starts (url via env).
|
||||
# The redact-rule entry models a deployment mounting its own scrub rule on the
|
||||
# telemetry/record waterfall — the seam itself ships no rules.
|
||||
- id: cli-mock-llm
|
||||
name: './cli-mock-llm.ts'
|
||||
|
||||
- id: telemetry-redact-rule
|
||||
name: './telemetry-redact-rule.ts'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-bash-local'
|
||||
|
||||
- id: telemetry-otel
|
||||
name: '@deepseek-ai/dsh-session-telemetry-otel'
|
||||
config:
|
||||
exporter:
|
||||
url: !!js process.env.DSH_TELEMETRY_E2E_URL
|
||||
|
||||
- id: cli-agent
|
||||
name: '@deepseek-ai/dsh-cli-demo'
|
||||
config:
|
||||
provider: cli-mock
|
||||
model: cli-mock
|
||||
persona: 'Test the session-telemetry-otel plugin.'
|
||||
persistenceRoot: './.sessions'
|
||||
persistenceCompression: 'none'
|
||||
workspaceContext: false
|
||||
29
examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts
vendored
Normal file
29
examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { Context } from 'cordis'
|
||||
|
||||
/**
|
||||
* Deployment-style redaction rule for the telemetry e2e: scrubs the fixture
|
||||
* credential from body strings, exactly as a real deployment would mount its
|
||||
* own rules on the `telemetry/record` waterfall.
|
||||
*/
|
||||
|
||||
const SECRET = /sk-e2efixture[0-9]+/g
|
||||
const PLACEHOLDER = '[E2E-REDACTED]'
|
||||
|
||||
function scrub(value: unknown): unknown {
|
||||
if (typeof value === 'string') return value.replace(SECRET, PLACEHOLDER)
|
||||
if (Array.isArray(value)) return value.map(scrub)
|
||||
if (value !== null && typeof value === 'object') {
|
||||
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, scrub(entry)]))
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export const name = 'telemetry-redact-rule'
|
||||
|
||||
/** Mount the fixture scrub rule onto the redact waterfall. */
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.on('telemetry/record', (_record, next) => {
|
||||
const record = next()
|
||||
return { ...record, body: scrub(record.body) }
|
||||
})
|
||||
}
|
||||
@@ -30,7 +30,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('full loop: real model + real bas
|
||||
ctx = await codingHarness(workdir, { persona: SYSTEM_PROMPT })
|
||||
const agent = ctx.agentLoop.create(SessionId('e2e-loop'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{ type: 'text', text: 'Run `echo e2e-ok` with the bash tool and tell me its exact output.' }])
|
||||
agent.followup({ content: [{ type: 'text', text: 'Run `echo e2e-ok` with the bash tool and tell me its exact output.' }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
const events = [...agent.session.events]
|
||||
|
||||
@@ -24,6 +24,8 @@ const ptyStreamExpected = join(ptyScenarioDir, 'stream-json.expected.jsonl')
|
||||
const ptyConfigPath = fileURLToPath(new URL('../pty.cordis.snapshot.yml', import.meta.url))
|
||||
const goalScenarioDir = join(snapshotsDir, 'goal-tools')
|
||||
const goalConfigPath = fileURLToPath(new URL('../goal.cordis.snapshot.yml', import.meta.url))
|
||||
const retryScenarioDir = join(snapshotsDir, 'provider-retry')
|
||||
const retryConfigPath = fileURLToPath(new URL('../retry.cordis.snapshot.yml', import.meta.url))
|
||||
const ralphScenarioDir = join(snapshotsDir, 'ralph-loop')
|
||||
const ralphConfigPath = fileURLToPath(new URL('../ralph.cordis.snapshot.yml', import.meta.url))
|
||||
const binScript = fileURLToPath(new URL('../../../packages/examples/cli-demo/src/bin.ts', import.meta.url))
|
||||
@@ -125,6 +127,46 @@ async function persistedLogs(cwd: string): Promise<PersistedLog[]> {
|
||||
}
|
||||
|
||||
describe('headless stream-json snapshots', () => {
|
||||
it('retries a transient provider failure through the one-shot app', async () => {
|
||||
const prompt = await scenarioPrompt(retryScenarioDir, 'provider-retry')
|
||||
const streamExpected = join(retryScenarioDir, 'stream-json.expected.jsonl')
|
||||
let runCwd = ''
|
||||
const result = await runLoaderSmoke({
|
||||
label: 'provider retry headless stream-json snapshot',
|
||||
tempDirPrefix: 'headless-snapshot-provider-retry-',
|
||||
binScript,
|
||||
configPath: retryConfigPath,
|
||||
binArgs: ['--config', retryConfigPath, '--output-format', 'stream-json', prompt],
|
||||
tsconfigPath,
|
||||
env: {
|
||||
DSH_SNAPSHOT: 'replay',
|
||||
NODE_OPTIONS: [process.env.NODE_OPTIONS, '--disable-warning=ExperimentalWarning'].filter(Boolean).join(' '),
|
||||
},
|
||||
prepare: (cwd) => { runCwd = cwd },
|
||||
inspect: async (cwd) => {
|
||||
const logs = await persistedLogs(cwd)
|
||||
expect(logs).toHaveLength(1)
|
||||
const records = parseJsonl(logs[0]?.content ?? '')
|
||||
const retries = records.filter(record => record.type === 'llm/retry')
|
||||
expect(retries).toHaveLength(1)
|
||||
expect(retries[0]?.data).toMatchObject({
|
||||
provider: 'deepseek',
|
||||
mode: 'normal',
|
||||
policyKey: '["normal",1,["RATE_LIMIT"],1,1,0]',
|
||||
retry: 1,
|
||||
maxRetries: 1,
|
||||
delayMs: 1,
|
||||
failure: { message: 'snapshot transient failure', code: 'RATE_LIMIT', status: 429 },
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.stderr).toBe('')
|
||||
const normalized = normalizeHeadlessStream(result.stdout, runCwd)
|
||||
if (refreshing) await writeFile(streamExpected, normalized)
|
||||
expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
it('logs the model default and a dynamic next-step reasoning effort', async () => {
|
||||
const result = await runLoaderSmoke({
|
||||
label: 'reasoning effort headless stream-json snapshot',
|
||||
@@ -201,6 +243,7 @@ describe('headless stream-json snapshots', () => {
|
||||
const children = logs.filter(log => typeof log.header.parentSession === 'string')
|
||||
.sort((left, right) => Number(left.header.createdAt) - Number(right.header.createdAt))
|
||||
const actualSessions = [parent, ...children]
|
||||
const actualContext = contextFromLogs(actualSessions.map(log => log.content))
|
||||
if (refreshing) {
|
||||
const harvested = actualSessions.map((log): HarvestedLog => ({
|
||||
id: String(log.header.id),
|
||||
@@ -217,12 +260,11 @@ describe('headless stream-json snapshots', () => {
|
||||
if (existing === undefined || file === undefined) {
|
||||
throw new Error(`headless snapshot has no fixture for persisted log ${index}`)
|
||||
}
|
||||
const stable = stabilizeRefreshLog(actual.content, existing, replacements)
|
||||
const stable = stabilizeRefreshLog(actual.content, existing, replacements, actualContext)
|
||||
await writeFile(file, stable)
|
||||
return stable
|
||||
}))
|
||||
}
|
||||
const actualContext = contextFromLogs(actualSessions.map(log => log.content))
|
||||
const expectedContext = contextFromLogs(expectedSessions)
|
||||
for (const [index, actual] of actualSessions.entries()) {
|
||||
const expected = expectedSessions[index]
|
||||
@@ -272,14 +314,16 @@ describe('headless stream-json snapshots', () => {
|
||||
const goalChanges = records.filter((record) => {
|
||||
if (record.type !== 'user/message') return false
|
||||
const data = record.data as JsonObject | undefined
|
||||
const meta = data?.meta as JsonObject | undefined
|
||||
return meta?.kind === 'goal/change'
|
||||
const source = data?.source as JsonObject | undefined
|
||||
const change = source?.change as JsonObject | undefined
|
||||
return source?.kind === 'goal' && change?.kind === 'goal/change'
|
||||
})
|
||||
expect(goalChanges).toHaveLength(1)
|
||||
const data = goalChanges[0]?.data as JsonObject | undefined
|
||||
const meta = data?.meta as JsonObject | undefined
|
||||
const goal = meta?.goal as JsonObject | undefined
|
||||
expect(meta?.operation).toBe('create')
|
||||
const source = data?.source as JsonObject | undefined
|
||||
const change = source?.change as JsonObject | undefined
|
||||
const goal = change?.goal as JsonObject | undefined
|
||||
expect(change?.operation).toBe('create')
|
||||
expect(goal).toMatchObject({
|
||||
objective: 'Finish the headless goal-tool snapshot proof',
|
||||
phase: 'active',
|
||||
@@ -395,6 +439,7 @@ describe('headless stream-json snapshots', () => {
|
||||
expect(logs).toHaveLength(1)
|
||||
const actual = logs[0]
|
||||
if (actual === undefined) throw new Error('headless PTY snapshot did not persist its session')
|
||||
const actualContext = contextFromLogs([actual.content])
|
||||
if (refreshing) {
|
||||
const harvested: HarvestedLog = {
|
||||
id: String(actual.header.id),
|
||||
@@ -402,10 +447,9 @@ describe('headless stream-json snapshots', () => {
|
||||
content: actual.content,
|
||||
}
|
||||
const replacements = refreshFixtureReplacements([harvested], [expectedSession])
|
||||
expectedSession = stabilizeRefreshLog(actual.content, expectedSession, replacements)
|
||||
expectedSession = stabilizeRefreshLog(actual.content, expectedSession, replacements, actualContext)
|
||||
await writeFile(ptySessionFixture, expectedSession)
|
||||
}
|
||||
const actualContext = contextFromLogs([actual.content])
|
||||
const expectedContext = contextFromLogs([expectedSession])
|
||||
expect(scrubRequestHeaders(normalizeSessionLog(actual.content, actualContext)))
|
||||
.toBe(scrubRequestHeaders(normalizeSessionLog(expectedSession, expectedContext)))
|
||||
|
||||
@@ -41,7 +41,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('resume: continue a persisted ses
|
||||
sessionId: SESSION_ID,
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek-v4-flash' },
|
||||
})).agent
|
||||
first.followup([{ type: 'text', text: `Remember this code for later: ${SECRET}. Just acknowledge it.` }])
|
||||
first.followup({ content: [{ type: 'text', text: `Remember this code for later: ${SECRET}. Just acknowledge it.` }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, first)
|
||||
await ctx.fiber.dispose()
|
||||
ctx = undefined
|
||||
@@ -58,7 +58,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('resume: continue a persisted ses
|
||||
// The prior user turn is in the rehydrated log before the model is asked.
|
||||
expect(JSON.stringify(resumed.session.deriveMessages())).toContain(SECRET)
|
||||
|
||||
resumed.followup([{ type: 'text', text: 'What was the code I asked you to remember? Reply with just the code.' }])
|
||||
resumed.followup({ content: [{ type: 'text', text: 'What was the code I asked you to remember? Reply with just the code.' }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, resumed)
|
||||
|
||||
// The model recalls it — only possible from the resumed history.
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
"steps": [
|
||||
{ "op": "initialize" },
|
||||
{ "op": "newSession" },
|
||||
{ "op": "prompt", "text": "Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then reply with exactly ADVANCED_HEADLESS_OK." }
|
||||
{ "op": "prompt", "text": "Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK." }
|
||||
]
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_HEADLESS_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"Run this advanced flow exactly","messageSeqs":[1],"source":{"kind":"fallback"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}
|
||||
@@ -10,19 +10,19 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":10,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"mounted dyn-1 (plugin \"snapshot-marker\", state: active)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":13,"time":0,"data":{"turn":1,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":14,"time":0,"data":{"turn":1,"step":2}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":20,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[15,16,17,18,19],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":21,"time":0,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Run the scripted inspection program\"}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/code-dispatch-start","seq":22,"time":0,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"dynamic"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/code-dispatch","seq":23,"time":0,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"dynamic"},"isError":false,"content":[{"type":"text","text":"## dynamic\n- dyn-1: snapshot-marker [active]"}]}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":24,"time":0,"data":{"turn":1,"step":2,"callId":"advanced-code","content":[{"type":"text","text":"## dynamic\n- dyn-1: snapshot-marker [active]"}],"isError":false},"sourceEventSeqs":[21],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":20,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[15,16,17,18,19],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":21,"time":0,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/code-dispatch-start","seq":22,"time":0,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/code-dispatch","seq":23,"time":0,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}]}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":24,"time":0,"data":{"turn":1,"step":2,"callId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false},"sourceEventSeqs":[21],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":25,"time":0,"data":{"turn":1,"step":2}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":26,"time":0,"data":{"turn":1,"step":3}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}}
|
||||
@@ -52,7 +52,7 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":51,"time":0,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":52,"time":0,"data":{"turn":1,"step":5,"content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[47,48,49,50,51],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":53,"time":0,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":54,"time":0,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"unmounted dyn-1 (plugin \"snapshot-marker\")"}],"isError":false},"sourceEventSeqs":[53],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":54,"time":0,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false},"sourceEventSeqs":[53],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":55,"time":0,"data":{"turn":1,"step":5}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":56,"time":0,"data":{"turn":1,"step":6}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":57,"time":0,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":20,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":20,"outputTokens":8}},"sourceEventSeqs":[15,16,17,18,19],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":21,"time":0,"data":{"turn":1,"step":2,"callId":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the headless goal-tool snapshot proof\",\"max_goal_rounds\":7}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":22,"time":0,"data":{"turn":1,"step":2,"callId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":7},\"activation\":\"armed\"}"}],"isError":false},"sourceEventSeqs":[21],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":23,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"maxGoalRounds\":7},\"roundsStarted\":0,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":0},"meta":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the headless goal-tool snapshot proof","phase":"active","maxGoalRounds":7},"roundsStarted":0,"createdAt":0,"updatedAt":0}},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":23,"time":0,"data":{"content":[{"type":"text","text":"<goal_state>{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the headless goal-tool snapshot proof\",\"phase\":\"active\",\"maxGoalRounds\":7},\"roundsStarted\":0,\"createdAt\":0,\"updatedAt\":0}</goal_state>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":0,"change":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the headless goal-tool snapshot proof","phase":"active","maxGoalRounds":7},"roundsStarted":0,"createdAt":0,"updatedAt":0}}},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":24,"time":0,"data":{"turn":1,"step":2}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":25,"time":0,"data":{"turn":1,"step":3}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"steps": [
|
||||
{
|
||||
"op": "prompt",
|
||||
"text": "retry the transient provider failure"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"retry the transient provider failure"}],"source":{"kind":"user"}},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"retry the transient provider failure","messageSeqs":[1],"source":{"kind":"fallback"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":5,"time":0,"data":{"turn":1,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"llm/retry","seq":6,"time":0,"data":{"turn":1,"step":1,"provider":"deepseek","mode":"normal","policyKey":"[\"normal\",1,[\"RATE_LIMIT\"],1,1,0]","retry":1,"maxRetries":1,"delayMs":1,"failure":{"message":"snapshot transient failure","code":"RATE_LIMIT","status":429}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":7,"time":0,"data":{"turn":1,"reason":{"kind":"error","step":1,"failure":{"message":"snapshot transient failure","code":"RATE_LIMIT","status":429}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":8,"time":0,"data":{"turn":2,"trigger":{"kind":"retry"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":9,"time":0,"data":{"turn":2,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"text-delta","index":0,"text":"RETRY_OK"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RETRY_OK"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":4,"outputTokens":2}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":15,"time":0,"data":{"turn":2,"step":1,"content":[{"type":"text","text":"RETRY_OK"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":4,"outputTokens":2}},"sourceEventSeqs":[10,11,12,13,14],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":16,"time":0,"data":{"turn":2,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":17,"time":0,"data":{"turn":2,"reason":{"kind":"completed"}}}}
|
||||
{"type":"result","success":true,"sessionId":"{{sessionId}}","turn":2,"result":"RETRY_OK","reason":{"kind":"completed"},"usage":{"inputTokens":4,"outputTokens":2}}
|
||||
File diff suppressed because one or more lines are too long
@@ -28,10 +28,10 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('todo_write: real model records a
|
||||
ctx = await codingHarness(workdir, { persona: TODO_SYSTEM_PROMPT })
|
||||
const agent = ctx.agentLoop.create(SessionId('e2e-todo'), { provider: 'deepseek', model: 'deepseek-v4-flash' })
|
||||
|
||||
agent.followup([{ type: 'text', text:
|
||||
agent.followup({ content: [{ type: 'text', text:
|
||||
'Use the todo_write tool to record a plan of exactly two steps: first '
|
||||
+ '"inspect the failing test" (in_progress), then "apply the fix" (pending). '
|
||||
+ 'Send both in one todo_write call, then reply with the single word DONE.' }])
|
||||
+ 'Send both in one todo_write call, then reply with the single word DONE.' }], source: { kind: 'user' } })
|
||||
await waitForIdle(ctx, agent)
|
||||
|
||||
const events = [...agent.session.events]
|
||||
|
||||
28
examples/jsonrpc-agent/cordis.snapshot.yml
Normal file
28
examples/jsonrpc-agent/cordis.snapshot.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
# Keyless replay includes the live `cordis.yml`, disables the key-requiring
|
||||
# DeepSeek adapter, and inserts `llm-replay` to serve recorded JSONL without a
|
||||
# key or network; every other entry remains shared. The replay provider
|
||||
# catalog claims the `deepseek` provider so the SDK server's `initialize`
|
||||
# finds it owned and never mounts the real-adapter fallback. The SDK snapshot
|
||||
# suite passes this path explicitly through `DSH_CORDIS_CONFIG` (the
|
||||
# jsonrpc-demo bin performs no DSH_SNAPSHOT config swap of its own), and
|
||||
# `llm-replay` reads `DSH_SNAPSHOT_FILE` / `DSH_SNAPSHOT_CHILD_FILES` from the
|
||||
# harness. Stdout remains reserved for JSON-RPC frames.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
# `name` asserts the target: a mismatch skips the patch and warns only
|
||||
# when a logger exists.
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- insert:
|
||||
- id: llm-replay
|
||||
name: '@deepseek-ai/dsh-llm-replay'
|
||||
config:
|
||||
providers:
|
||||
- id: deepseek
|
||||
name: DeepSeek
|
||||
models:
|
||||
- id: deepseek-v4-flash
|
||||
@@ -42,6 +42,8 @@
|
||||
name: '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
config:
|
||||
root: !!js process.env.DSH_SESSION_ROOT ?? './.sessions'
|
||||
# Snapshot runs read the raw JSONL back; production keeps zstd frames.
|
||||
compression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
|
||||
|
||||
- id: session-checkpoints
|
||||
name: '@deepseek-ai/dsh-session-checkpoint-policy'
|
||||
|
||||
32
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts
vendored
Normal file
32
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child-mock-llm.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import type { Context } from 'cordis'
|
||||
import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
|
||||
import { LlmAdapter } from '@deepseek-ai/dsh-llm'
|
||||
|
||||
/**
|
||||
* Scripted model for the CHILD runtime: answers every request with its own
|
||||
* process cwd, so the driving e2e can prove the parent session's workspace
|
||||
* reached the child process across the SDK wire. `options` carries the
|
||||
* request; the reply depends only on process state.
|
||||
*/
|
||||
class CwdEchoAdapter extends LlmAdapter {
|
||||
async * stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
|
||||
void options
|
||||
const reply = `child cwd: ${process.cwd()}`
|
||||
yield { type: 'block-start', index: 0, blockType: 'text' }
|
||||
yield { type: 'text-delta', index: 0, text: reply }
|
||||
yield { type: 'block-end', index: 0, block: { type: 'text', text: reply } }
|
||||
yield { type: 'usage', usage: { inputTokens: 3, outputTokens: reply.length } }
|
||||
yield { type: 'finish', reason: { kind: 'stop' } }
|
||||
}
|
||||
}
|
||||
|
||||
export const name = 'child-mock-llm'
|
||||
export const inject = ['llm']
|
||||
|
||||
/**
|
||||
* Register the cwd-echo adapter under the `mock` provider.
|
||||
* @param ctx - the plugin context supplying `ctx.llm`.
|
||||
*/
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.llm.registerAdapter(['mock'], new CwdEchoAdapter())
|
||||
}
|
||||
40
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child.cordis.yml
vendored
Normal file
40
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/child.cordis.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# The CHILD runtime for the SDK subagent composition test: a complete
|
||||
# stdio JSON-RPC harness whose scripted model echoes its process cwd. The
|
||||
# parent's subagent-sdk backend spawns this composition per run; stdout is
|
||||
# reserved for JSON-RPC frames.
|
||||
- id: jsonrpc
|
||||
name: '@deepseek-ai/dsh-jsonrpc'
|
||||
|
||||
- id: child-mock-llm
|
||||
name: './child-mock-llm.ts'
|
||||
|
||||
- id: agent-core
|
||||
name: '@deepseek-ai/dsh-agent-spine-demo'
|
||||
config:
|
||||
persona: 'Echo where you run.'
|
||||
workspaceContext: false
|
||||
skills:
|
||||
enabled: false
|
||||
toolBash:
|
||||
enableRunInBackground: false
|
||||
toolTasks: false
|
||||
|
||||
# The child persists its own session log beside the parent's (distinct root),
|
||||
# so the driving e2e can inspect both transcripts after the run.
|
||||
- id: sessions
|
||||
name: '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
config:
|
||||
root: !!js process.env.DSH_SESSION_ROOT ?? './.child-sessions'
|
||||
compression: none
|
||||
|
||||
- id: session-checkpoints
|
||||
name: '@deepseek-ai/dsh-session-checkpoint-policy'
|
||||
|
||||
# bash-local executes through the subprocess seam.
|
||||
- id: subprocess
|
||||
name: '@deepseek-ai/dsh-subprocess-local'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-bash-local'
|
||||
config:
|
||||
cwd: !!js process.env.DSH_CWD ?? process.cwd()
|
||||
43
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/cordis.yml
vendored
Normal file
43
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/cordis.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Test-only composition: the SDK subagent backend on the real Loader/app path.
|
||||
# The scripted model delegates once; the child — a COMPLETE second harness
|
||||
# runtime speaking stdio JSON-RPC — echoes its process cwd, so parent-session
|
||||
# cwd inheritance is asserted keylessly end to end across the SDK wire.
|
||||
# `cwd` is deliberately omitted — the inheritance branch under test. The child
|
||||
# launch is machine-absolute, so the driving e2e supplies it via
|
||||
# DSH_TEST_CHILD_COMMAND / DSH_TEST_CHILD_ARGS / DSH_TEST_CHILD_ENV (resolved
|
||||
# through the shared example-launch resolver, per testing policy).
|
||||
- id: mock-llm
|
||||
name: './mock-delegating-llm.ts'
|
||||
|
||||
- id: subagent
|
||||
name: '@deepseek-ai/dsh-subagent'
|
||||
|
||||
# providerName is omitted: the composition exercises the shipped default
|
||||
# (`dsh-sdk`) through the real Loader.
|
||||
- id: subagent-dsh-sdk
|
||||
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
|
||||
config:
|
||||
command: !!js process.env.DSH_TEST_CHILD_COMMAND
|
||||
args: !!js JSON.parse(process.env.DSH_TEST_CHILD_ARGS ?? '[]')
|
||||
provider: mock
|
||||
model: mock-echo
|
||||
env: !!js JSON.parse(process.env.DSH_TEST_CHILD_ENV ?? '{}')
|
||||
|
||||
- id: tool-subagent
|
||||
name: '@deepseek-ai/dsh-tool-subagent'
|
||||
config:
|
||||
provider: dsh-sdk
|
||||
toolName: subagent
|
||||
# The SDK backend advertises no depthLimit: the child harness owns its own
|
||||
# recursion budget, so the local numeric default cannot apply here.
|
||||
maxDepth: 'provider-managed'
|
||||
|
||||
- id: cli-agent
|
||||
name: '@deepseek-ai/dsh-cli-demo'
|
||||
config:
|
||||
provider: mock
|
||||
model: mock-delegate
|
||||
persona: 'Test SDK subagent cwd inheritance.'
|
||||
persistenceRoot: './.sessions'
|
||||
persistenceCompression: 'none'
|
||||
workspaceContext: false
|
||||
15
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/driver.ts
vendored
Normal file
15
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/driver.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
/** Test driver: one delegation turn through a headless Loader composition. */
|
||||
|
||||
import { boot, resolveConfigPath } from '@deepseek-ai/dsh-app-boot'
|
||||
import { runOneShot } from '@deepseek-ai/dsh-cli-demo/src/cli.ts'
|
||||
|
||||
const configPath = process.argv[2]
|
||||
if (configPath === undefined) throw new Error('sdk-subagent cwd driver requires a config path')
|
||||
|
||||
const ctx = await boot('sdk-subagent-cwd-e2e', resolveConfigPath(configPath, undefined))
|
||||
try {
|
||||
await runOneShot(ctx, { task: 'delegate' })
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
}
|
||||
48
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts
vendored
Normal file
48
examples/jsonrpc-agent/tests/fixtures/subagent/subagent-dsh-sdk/mock-delegating-llm.ts
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { Context } from 'cordis'
|
||||
import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
|
||||
import { CallId, LlmAdapter } from '@deepseek-ai/dsh-llm'
|
||||
|
||||
/**
|
||||
* Test adapter for the `mock-delegate` model: the first request calls the
|
||||
* `subagent` tool once, and the follow-up streams the tool result text back
|
||||
* verbatim — so the SDK child runtime's answer (the scripted child model's
|
||||
* cwd echo) reaches the parent session log for the driving e2e to assert.
|
||||
*/
|
||||
class MockDelegatingAdapter extends LlmAdapter {
|
||||
async * stream(options: GenerateOptions): AsyncIterable<StreamChunk> {
|
||||
const toolResultText = options.messages.at(-1)?.content
|
||||
.filter(block => block.type === 'tool-result')
|
||||
.flatMap(block => block.content)
|
||||
.filter(block => block.type === 'text')
|
||||
.map(block => block.text)
|
||||
.join('') ?? ''
|
||||
|
||||
if (toolResultText.length === 0) {
|
||||
const args = JSON.stringify({ description: 'cwd probe', prompt: 'report your workspace' })
|
||||
yield { type: 'block-start', index: 0, blockType: 'tool-call' }
|
||||
yield { type: 'tool-call-delta', index: 0, id: CallId('call-delegate'), name: 'subagent', argumentsDelta: args }
|
||||
yield { type: 'block-end', index: 0, block: { type: 'tool-call', id: CallId('call-delegate'), name: 'subagent', arguments: args } }
|
||||
yield { type: 'usage', usage: { inputTokens: 10, outputTokens: 5 } }
|
||||
yield { type: 'finish', reason: { kind: 'tool-calls' } }
|
||||
return
|
||||
}
|
||||
|
||||
const reply = `child reported:\n${toolResultText}`
|
||||
yield { type: 'block-start', index: 0, blockType: 'text' }
|
||||
yield { type: 'text-delta', index: 0, text: reply }
|
||||
yield { type: 'block-end', index: 0, block: { type: 'text', text: reply } }
|
||||
yield { type: 'usage', usage: { inputTokens: 10, outputTokens: reply.length } }
|
||||
yield { type: 'finish', reason: { kind: 'stop' } }
|
||||
}
|
||||
}
|
||||
|
||||
export const name = 'mock-llm'
|
||||
export const inject = ['llm']
|
||||
|
||||
/**
|
||||
* Register the delegating mock adapter under the `mock` provider.
|
||||
* @param ctx - the plugin context supplying `ctx.llm`.
|
||||
*/
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.llm.registerAdapter(['mock'], new MockDelegatingAdapter())
|
||||
}
|
||||
294
examples/jsonrpc-agent/tests/sdk.snapshot.ts
Normal file
294
examples/jsonrpc-agent/tests/sdk.snapshot.ts
Normal file
@@ -0,0 +1,294 @@
|
||||
/**
|
||||
* Keyless snapshot coverage for the TypeScript SDK path: each scenario spawns
|
||||
* the REAL `dsh-jsonrpc-agent` runtime (per `DSH_EXAMPLE_MODE`) through the
|
||||
* REAL `@deepseek-ai/dsh-sdk-client`, drives one turn over stdio JSON-RPC,
|
||||
* and pins three surfaces — the SDK `TurnResult`, the complete notification
|
||||
* stream, and the persisted session logs. Replay serves recorded model
|
||||
* responses via `llm-replay` (`cordis.snapshot.yml`); `DSH_SNAPSHOT=record`
|
||||
* re-records against the live API; `DSH_SNAPSHOT=refresh` replays committed
|
||||
* fixtures and rewrites expected outputs.
|
||||
*/
|
||||
|
||||
import { mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { delimiter, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
normalizeSessionLog,
|
||||
normalizeStdout,
|
||||
refreshFixtureReplacements,
|
||||
scrubRequestHeaders,
|
||||
stabilizeRefreshLog,
|
||||
type HarvestedLog,
|
||||
type NormalizeContext,
|
||||
} from '@deepseek-ai/dsh-acp-snapshot'
|
||||
import { resolveExampleLaunch } from '@deepseek-ai/dsh-loader-smoke'
|
||||
import { DeepSeekHarness, type HarnessNotification, type TurnResult } from '@deepseek-ai/dsh-sdk-client'
|
||||
|
||||
const testsDir = dirOf(import.meta.url)
|
||||
const snapshotsDir = join(testsDir, 'snapshots')
|
||||
const liveConfig = join(testsDir, '..', 'cordis.yml')
|
||||
const replayConfig = join(testsDir, '..', 'cordis.snapshot.yml')
|
||||
const runtimeBin = fileURLToPath(new URL('../../../packages/examples/jsonrpc-demo/src/bin.ts', import.meta.url))
|
||||
const repoTsconfig = fileURLToPath(new URL('../../../tsconfig.json', import.meta.url))
|
||||
|
||||
const mode = process.env.DSH_SNAPSHOT ?? 'replay'
|
||||
const recording = mode === 'record'
|
||||
const refreshing = mode === 'refresh'
|
||||
|
||||
function dirOf(url: string): string {
|
||||
return fileURLToPath(new URL('.', url))
|
||||
}
|
||||
|
||||
interface SdkScenario {
|
||||
/** Scenario name; the snapshots/<name> fixture directory. */
|
||||
name: string
|
||||
/** The user prompt for the single SDK turn. */
|
||||
prompt: string
|
||||
/** Fixed SDK session id, so fixtures and replay binding stay stable. */
|
||||
sessionId: string
|
||||
/** How many child sessions the turn persists (subagent scenarios). */
|
||||
children: number
|
||||
}
|
||||
|
||||
const SCENARIOS: SdkScenario[] = [
|
||||
{
|
||||
name: 'text-turn',
|
||||
prompt: 'Reply with exactly: SDK snapshot OK',
|
||||
sessionId: 'sdk-snapshot-text',
|
||||
children: 0,
|
||||
},
|
||||
{
|
||||
name: 'bash-tool',
|
||||
prompt: 'Run this exact command with your bash tool, then reply with its stdout only: echo dsh-sdk-proof-7391',
|
||||
sessionId: 'sdk-snapshot-bash',
|
||||
children: 0,
|
||||
},
|
||||
{
|
||||
name: 'subagent-spawn',
|
||||
prompt: "Use the subagent tool exactly once with description 'echo probe' and prompt: Reply with exactly: child answer 42. Then reply with the subagent's final answer verbatim.",
|
||||
sessionId: 'sdk-snapshot-subagent',
|
||||
children: 1,
|
||||
},
|
||||
]
|
||||
|
||||
interface PersistedLog {
|
||||
readonly path: string
|
||||
readonly content: string
|
||||
readonly header: Record<string, unknown>
|
||||
}
|
||||
|
||||
async function jsonlFiles(dir: string): Promise<string[]> {
|
||||
const entries = await readdir(dir, { recursive: true })
|
||||
return entries.filter(entry => entry.endsWith('.jsonl')).map(entry => join(dir, entry)).sort()
|
||||
}
|
||||
|
||||
async function persistedLogs(sessionsRoot: string): Promise<PersistedLog[]> {
|
||||
const files = await jsonlFiles(sessionsRoot)
|
||||
return Promise.all(files.map(async (path) => {
|
||||
const content = await readFile(path, 'utf8')
|
||||
const header = JSON.parse(content.slice(0, content.indexOf('\n'))) as Record<string, unknown>
|
||||
return { path, content, header }
|
||||
}))
|
||||
}
|
||||
|
||||
function contextOf(logs: readonly { content: string; header: Record<string, unknown> }[], cwd: string): NormalizeContext {
|
||||
return {
|
||||
sessionIds: logs.flatMap(log => typeof log.header.id === 'string' ? [log.header.id] : []),
|
||||
cwd,
|
||||
}
|
||||
}
|
||||
|
||||
function contextOfContents(contents: readonly string[]): NormalizeContext {
|
||||
const headers = contents.map(content => JSON.parse(content.slice(0, content.indexOf('\n'))) as Record<string, unknown>)
|
||||
return {
|
||||
sessionIds: headers.flatMap(header => typeof header.id === 'string' ? [header.id] : []),
|
||||
cwd: typeof headers[0]?.cwd === 'string' ? headers[0].cwd : '\0no-cwd\0',
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the SDK-visible notification stream: embedded `session.event`
|
||||
* envelopes get the session-log treatment (times zeroed, headers tokenized),
|
||||
* then every record is scrubbed like a wire frame.
|
||||
*/
|
||||
function normalizeNotifications(notifications: readonly HarnessNotification[], ctx: NormalizeContext): string {
|
||||
const events = notifications
|
||||
.filter(n => n.method === 'session.event')
|
||||
.map(n => n.params.event as Record<string, unknown>)
|
||||
const normalizedEvents = events.length === 0
|
||||
? []
|
||||
: scrubRequestHeaders(normalizeSessionLog(
|
||||
`${events.map(event => JSON.stringify(event)).join('\n')}\n`,
|
||||
ctx,
|
||||
)).trimEnd().split('\n').map(line => JSON.parse(line) as Record<string, unknown>)
|
||||
let eventIndex = 0
|
||||
const records = notifications.map((notification) => {
|
||||
if (notification.method !== 'session.event') return { method: notification.method, params: notification.params }
|
||||
const event = normalizedEvents[eventIndex++]
|
||||
return { method: notification.method, params: { ...notification.params, event } }
|
||||
})
|
||||
return normalizeStdout(`${records.map(record => JSON.stringify(record)).join('\n')}\n`, ctx)
|
||||
}
|
||||
|
||||
/** Normalize the turn-result projection (status, reason kind, final text). */
|
||||
function normalizeResult(result: TurnResult, ctx: NormalizeContext): string {
|
||||
return normalizeStdout(`${JSON.stringify({
|
||||
status: result.status,
|
||||
reason: result.reason,
|
||||
finalResponse: result.finalResponse,
|
||||
})}\n`, ctx)
|
||||
}
|
||||
|
||||
/** One SDK turn against a fresh runtime subprocess in an isolated cwd. */
|
||||
async function runScenario(scenario: SdkScenario): Promise<{
|
||||
result: TurnResult
|
||||
notifications: HarnessNotification[]
|
||||
logs: PersistedLog[]
|
||||
cwd: string
|
||||
}> {
|
||||
const cwd = await mkdtemp(join(tmpdir(), `sdk-snapshot-${scenario.name}-`))
|
||||
const sessionsRoot = join(cwd, '.sessions')
|
||||
const scenarioDir = join(snapshotsDir, scenario.name)
|
||||
const launch = resolveExampleLaunch({
|
||||
srcBin: runtimeBin,
|
||||
configArgs: [],
|
||||
tsconfigPath: repoTsconfig,
|
||||
})
|
||||
const childFixtures = Array.from(
|
||||
{ length: scenario.children },
|
||||
(_, index) => join(scenarioDir, `session.${index + 1}.jsonl`),
|
||||
)
|
||||
const env: Record<string, string> = {
|
||||
...Object.fromEntries(Object.entries(process.env).filter(([, value]) => value !== undefined)) as Record<string, string>,
|
||||
...Object.fromEntries(Object.entries(launch.env).filter(([, value]) => value !== undefined)) as Record<string, string>,
|
||||
DSH_CORDIS_CONFIG: recording ? liveConfig : replayConfig,
|
||||
DSH_SESSION_ROOT: sessionsRoot,
|
||||
DSH_CWD: cwd,
|
||||
DSH_SNAPSHOT: mode,
|
||||
NODE_OPTIONS: [process.env.NODE_OPTIONS, '--disable-warning=ExperimentalWarning'].filter(Boolean).join(' '),
|
||||
...recording ? {} : {
|
||||
DSH_SNAPSHOT_FILE: join(scenarioDir, 'session.jsonl'),
|
||||
...childFixtures.length > 0 ? { DSH_SNAPSHOT_CHILD_FILES: childFixtures.join(delimiter) } : {},
|
||||
},
|
||||
}
|
||||
|
||||
const harness = new DeepSeekHarness({
|
||||
launch: {
|
||||
command: launch.command,
|
||||
args: launch.args,
|
||||
cwd,
|
||||
env,
|
||||
requestTimeoutMs: 110_000,
|
||||
},
|
||||
cwd,
|
||||
provider: 'deepseek',
|
||||
model: 'deepseek-v4-flash',
|
||||
})
|
||||
try {
|
||||
const notifications: HarnessNotification[] = []
|
||||
const result = await harness.run(scenario.prompt, {
|
||||
sessionId: scenario.sessionId,
|
||||
onNotification: (notification) => { notifications.push(notification) },
|
||||
})
|
||||
await harness.close()
|
||||
const logs = await persistedLogs(sessionsRoot)
|
||||
return { result, notifications, logs, cwd }
|
||||
} finally {
|
||||
await harness.close()
|
||||
await rm(cwd, { recursive: true, force: true })
|
||||
}
|
||||
}
|
||||
|
||||
/** Order logs parent-first, children by creation time (fixture layout order). */
|
||||
function orderLogs(logs: PersistedLog[], scenario: SdkScenario): PersistedLog[] {
|
||||
const parents = logs.filter(log => typeof log.header.parentSession !== 'string')
|
||||
const children = logs.filter(log => typeof log.header.parentSession === 'string')
|
||||
.sort((left, right) => Number(left.header.createdAt) - Number(right.header.createdAt))
|
||||
expect(parents).toHaveLength(1)
|
||||
expect(children).toHaveLength(scenario.children)
|
||||
return [...parents, ...children]
|
||||
}
|
||||
|
||||
function fixtureFiles(scenario: SdkScenario): string[] {
|
||||
const dir = join(snapshotsDir, scenario.name)
|
||||
return [
|
||||
join(dir, 'session.jsonl'),
|
||||
...Array.from({ length: scenario.children }, (_, index) => join(dir, `session.${index + 1}.jsonl`)),
|
||||
]
|
||||
}
|
||||
|
||||
describe('TypeScript SDK snapshots over the jsonrpc runtime', () => {
|
||||
for (const scenario of SCENARIOS) {
|
||||
it(`replays ${scenario.name} through the SDK`, async () => {
|
||||
const scenarioDir = join(snapshotsDir, scenario.name)
|
||||
const notificationsExpectedPath = join(scenarioDir, 'notifications.expected.jsonl')
|
||||
const resultExpectedPath = join(scenarioDir, 'result.expected.json')
|
||||
|
||||
const { result, notifications, logs, cwd } = await runScenario(scenario)
|
||||
const ordered = orderLogs(logs, scenario)
|
||||
const actualContext = contextOf(ordered, cwd)
|
||||
|
||||
if (recording) {
|
||||
// Fixtures carry tokenized request headers; llm-replay reads only
|
||||
// assistant output and tool traffic, so scrubbing keeps prompts and
|
||||
// schemas out of the corpus without affecting replay.
|
||||
await mkdir(scenarioDir, { recursive: true })
|
||||
await Promise.all(ordered.map(async (log, index) => {
|
||||
const file = fixtureFiles(scenario)[index]
|
||||
if (file === undefined) throw new Error(`no fixture path for persisted log ${index}`)
|
||||
await writeFile(file, scrubRequestHeaders(log.content))
|
||||
}))
|
||||
}
|
||||
|
||||
const files = fixtureFiles(scenario)
|
||||
let expectedContents = await Promise.all(files.map(file => readFile(file, 'utf8')))
|
||||
|
||||
if (refreshing) {
|
||||
const harvested = ordered.map((log): HarvestedLog => ({
|
||||
id: String(log.header.id),
|
||||
createdAt: Number(log.header.createdAt),
|
||||
...typeof log.header.parentSession === 'string' ? { parentSession: log.header.parentSession } : {},
|
||||
content: log.content,
|
||||
}))
|
||||
const replacements = refreshFixtureReplacements(harvested, expectedContents)
|
||||
expectedContents = await Promise.all(ordered.map(async (log, index) => {
|
||||
const existing = expectedContents[index]
|
||||
const file = files[index]
|
||||
if (existing === undefined || file === undefined) throw new Error(`no fixture for persisted log ${index}`)
|
||||
const stable = stabilizeRefreshLog(log.content, existing, replacements, actualContext)
|
||||
await writeFile(file, stable)
|
||||
return stable
|
||||
}))
|
||||
}
|
||||
|
||||
// Persisted transcripts match the committed fixtures.
|
||||
const expectedContext = contextOfContents(expectedContents)
|
||||
for (const [index, log] of ordered.entries()) {
|
||||
const expected = expectedContents[index]
|
||||
if (expected === undefined) throw new Error(`no fixture for persisted log ${index}`)
|
||||
expect(scrubRequestHeaders(normalizeSessionLog(log.content, actualContext)))
|
||||
.toBe(scrubRequestHeaders(normalizeSessionLog(expected, expectedContext)))
|
||||
}
|
||||
|
||||
// The SDK-visible wire stream and turn result match their expected outputs.
|
||||
const normalizedNotifications = normalizeNotifications(notifications, actualContext)
|
||||
const normalizedResult = normalizeResult(result, actualContext)
|
||||
if (recording || refreshing) {
|
||||
await writeFile(notificationsExpectedPath, normalizedNotifications)
|
||||
await writeFile(resultExpectedPath, normalizedResult)
|
||||
}
|
||||
expect(normalizedNotifications).toBe(await readFile(notificationsExpectedPath, 'utf8'))
|
||||
expect(normalizedResult).toBe(await readFile(resultExpectedPath, 'utf8'))
|
||||
|
||||
// Wire-shape invariants that must hold in every mode.
|
||||
expect(result.status).toBe('ok')
|
||||
expect(notifications.at(-1)?.method).toBe('session.finished')
|
||||
if (scenario.children > 0) {
|
||||
expect(notifications.some(n => n.method === 'subagent.started')).toBe(true)
|
||||
expect(notifications.some(n => n.method === 'subagent.finished')).toBe(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,97 @@
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Run this exact command with your bash tool, then reply with its stdout only: echo dsh-sdk-proof-7391"}],"source":{"kind":"user"}},"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"Run this exact command with","messageSeqs":[1],"source":{"kind":"fallback"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":5,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":6,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":7,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" run"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" a"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" specific"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" bash"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" command"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" and"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" its"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" stdout"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" only"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"{"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"command"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":": "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"echo"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" d"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"sh"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":34,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"-s"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":35,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"dk"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":36,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"-proof"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":37,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"-"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":38,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"739"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":39,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"1"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":40,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":41,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":", "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":42,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":43,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"description"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":44,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":45,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":": "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":46,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":47,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"Run"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":48,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" the"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":49,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" echo"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":50,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" command"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":51,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" as"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":52,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":" requested"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":53,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":54,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","argumentsDelta":"}"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":55,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to run a specific bash command and reply with its stdout only."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":56,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":57,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":123,"outputTokens":89,"cacheReadTokens":1664,"reasoningTokens":17}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":58,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":59,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a specific bash command and reply with its stdout only."},{"type":"tool-call","id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":123,"outputTokens":89,"cacheReadTokens":1664,"reasoningTokens":17}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":60,"time":0,"data":{"turn":1,"step":1,"callId":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":61,"time":0,"data":{"turn":1,"step":1,"callId":"call_00_Ry17evSfTr0uJnHhg3X93070","content":[{"type":"text","text":"dsh-sdk-proof-7391\n"}],"isError":false},"sourceEventSeqs":[60],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":62,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":63,"time":0,"data":{"turn":1,"step":2}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":64,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":65,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":66,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" command"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":67,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" produced"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":68,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":69,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" expected"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":70,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" output"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":71,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":72,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" I"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":73,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"'ll"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":74,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":75,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":76,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" just"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":77,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" that"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":78,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" stdout"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":79,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":80,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":81,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"d"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":82,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"sh"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":83,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"-s"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":84,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"dk"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":85,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"-proof"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":86,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"-"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":87,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"739"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":88,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"1"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":89,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The command produced the expected output. I'll reply with just that stdout."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":90,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"dsh-sdk-proof-7391"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":91,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":233,"outputTokens":24,"cacheReadTokens":1664,"reasoningTokens":15}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":92,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":93,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The command produced the expected output. I'll reply with just that stdout."},{"type":"text","text":"dsh-sdk-proof-7391"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":233,"outputTokens":24,"cacheReadTokens":1664,"reasoningTokens":15}},"sourceEventSeqs":[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":94,"time":0,"data":{"turn":1,"step":2}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":95,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}}
|
||||
{"method":"session.finished","params":{"sessionId":"{{sessionId}}","status":"ok","reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"status":"ok","reason":{"kind":"completed"},"finalResponse":"dsh-sdk-proof-7391"}
|
||||
@@ -0,0 +1,30 @@
|
||||
{"type":"session","version":0,"id":"sdk-snapshot-bash","createdAt":1785097395899,"cwd":"/tmp/sdk-snapshot-bash-tool-ywbuab","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1785097395904,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785097395905,"data":{"content":[{"type":"text","text":"Run this exact command with your bash tool, then reply with its stdout only: echo dsh-sdk-proof-7391"}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785097395907,"data":{"title":"Run this exact command with","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1785097395908,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1785097395909,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1785097396437,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":6,"time0":1785097396438,"data":{"turn":1,"step":1,"index":0,"dt":[219,22,1,0,0,0,1,24,25,0,0,25,1,24,1,0],"texts":["The"," user"," wants"," me"," to"," run"," a"," specific"," bash"," command"," and"," reply"," with"," its"," stdout"," only","."]}}
|
||||
{"type":"assistant/chunk","seq":23,"time":1785097396856,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":24,"time0":1785097396857,"data":{"turn":1,"step":1,"index":1,"dt":[0,0,24,1,0,0,25,0,0,0,0,1,24,0,0,1,24,1,25,0,0,0,25,0,0,25,1,0,0,25],"id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","args":["","{","\"","command","\"",": ","\"","echo"," d","sh","-s","dk","-proof","-","739","1","\"",", ","\"","description","\"",": ","\"","Run"," the"," echo"," command"," as"," requested","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":55,"time":1785097397114,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to run a specific bash command and reply with its stdout only."}}}}
|
||||
{"type":"assistant/chunk","seq":56,"time":1785097397114,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":57,"time":1785097397114,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":123,"outputTokens":89,"cacheReadTokens":1664,"reasoningTokens":17}}}}
|
||||
{"type":"assistant/chunk","seq":58,"time":1785097397114,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":59,"time":1785097397118,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to run a specific bash command and reply with its stdout only."},{"type":"tool-call","id":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":123,"outputTokens":89,"cacheReadTokens":1664,"reasoningTokens":17}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":60,"time":1785097397119,"data":{"turn":1,"step":1,"callId":"call_00_Ry17evSfTr0uJnHhg3X93070","name":"bash","arguments":"{\"command\": \"echo dsh-sdk-proof-7391\", \"description\": \"Run the echo command as requested\"}"}}
|
||||
{"type":"tool/result","seq":61,"time":1785097397142,"data":{"turn":1,"step":1,"callId":"call_00_Ry17evSfTr0uJnHhg3X93070","content":[{"type":"text","text":"dsh-sdk-proof-7391\n"}],"isError":false},"sourceEventSeqs":[60],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":62,"time":1785097397145,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":63,"time":1785097397145,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":64,"time":1785097398036,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":65,"time0":1785097398037,"data":{"turn":1,"step":2,"index":0,"dt":[218,25,1,0,24,1,0,0,25,0,0,26,1,0],"texts":["The"," command"," produced"," the"," expected"," output","."," I","'ll"," reply"," with"," just"," that"," stdout","."]}}
|
||||
{"type":"assistant/chunk","seq":80,"time":1785097398358,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":81,"time0":1785097398358,"data":{"turn":1,"step":2,"index":1,"dt":[0,24,0,0,0,1,0],"texts":["d","sh","-s","dk","-proof","-","739","1"]}}
|
||||
{"type":"assistant/chunk","seq":89,"time":1785097398408,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The command produced the expected output. I'll reply with just that stdout."}}}}
|
||||
{"type":"assistant/chunk","seq":90,"time":1785097398408,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"dsh-sdk-proof-7391"}}}}
|
||||
{"type":"assistant/chunk","seq":91,"time":1785097398409,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":233,"outputTokens":24,"cacheReadTokens":1664,"reasoningTokens":15}}}}
|
||||
{"type":"assistant/chunk","seq":92,"time":1785097398409,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":93,"time":1785097398409,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The command produced the expected output. I'll reply with just that stdout."},{"type":"text","text":"dsh-sdk-proof-7391"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":233,"outputTokens":24,"cacheReadTokens":1664,"reasoningTokens":15}},"sourceEventSeqs":[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":94,"time":1785097398411,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":95,"time":1785097398412,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,175 @@
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Use the subagent tool exactly once with description 'echo probe' and prompt: Reply with exactly: child answer 42. Then reply with the subagent's final answer verbatim."}],"source":{"kind":"user"}},"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"Use the subagent tool exactly","messageSeqs":[1],"source":{"kind":"fallback"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":5,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":6,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":7,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":":\n"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"1"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" Use"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" sub"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"agent"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" tool"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" once"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" description"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" '"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"echo"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" probe"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"'"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" and"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" prompt"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" '"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"Reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":":"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":34,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":35,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":36,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":37,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":38,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":".'\n"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":39,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"2"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":40,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":41,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" Then"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":42,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":43,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":44,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":45,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" sub"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":46,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"agent"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":47,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"'s"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":48,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" final"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":49,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":50,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" verb"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":51,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"atim"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":52,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":".\n\n"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":53,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"Let"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":54,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":55,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" do"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":56,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" this"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":57,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" step"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":58,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" by"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":59,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" step"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":60,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":61,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":62,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":63,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"{"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":64,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":65,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"description"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":66,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":67,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":": "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":68,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":69,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"echo"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":70,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" probe"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":71,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":72,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":", "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":73,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":74,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"prom"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":75,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"pt"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":76,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":77,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":": "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":78,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":79,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"Reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":80,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":81,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" exactly"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":82,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":":"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":83,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":84,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":85,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":86,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":87,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":88,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":89,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":1,"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","argumentsDelta":"}"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":90,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":91,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":92,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":93,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":94,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."},{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":95,"time":0,"data":{"turn":1,"step":1,"callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}}}
|
||||
{"method":"subagent.started","params":{"parentSessionId":"{{sessionId}}","childSessionId":"{{sessionId}}"}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Reply with exactly: child answer 42."}],"source":{"kind":"user"}},"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"Reply with exactly: child answer","messageSeqs":[1],"source":{"kind":"fallback"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":5,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":6,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":7,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":".\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":30,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":31,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":32,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}}
|
||||
{"method":"subagent.finished","params":{"provider":"spawn","agentId":"{{sessionId}}","parentSessionId":"{{sessionId}}","childSessionId":"{{sessionId}}","status":"ok","stopReason":"completed","lastAssistantMessage":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}]}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":96,"time":0,"data":{"turn":1,"step":1,"callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","content":[{"type":"text","text":"child answer 42."}],"isError":false},"sourceEventSeqs":[95],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":97,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":98,"time":0,"data":{"turn":1,"step":2}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":99,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":100,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":101,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" sub"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":102,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"agent"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":103,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" replied"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":104,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":105,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":106,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":107,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":108,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":109,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":110,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":".\""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":111,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" Now"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":112,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" I"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":113,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" need"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":114,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":115,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":116,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":117,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":118,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" sub"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":119,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"agent"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":120,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"'s"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":121,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" final"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":122,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":123,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":" verb"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":124,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"atim"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":125,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":126,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":127,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"child"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":128,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":" answer"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":129,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":" "}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":130,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"42"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":131,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":1,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":132,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":133,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":134,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":135,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":136,"time":0,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."},{"type":"text","text":"child answer 42."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}},"sourceEventSeqs":[99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":137,"time":0,"data":{"turn":1,"step":2}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":138,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}}
|
||||
{"method":"session.finished","params":{"sessionId":"{{sessionId}}","status":"ok","reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"status":"ok","reason":{"kind":"completed"},"finalResponse":"child answer 42."}
|
||||
@@ -0,0 +1,17 @@
|
||||
{"type":"session","version":0,"id":"0b7fd85c-9f6f-4d46-b954-363984ce66fb","createdAt":1785097410282,"cwd":"/tmp/sdk-snapshot-subagent-spawn-6fzuBd","parentSession":"sdk-snapshot-subagent","delegationDepth":1}
|
||||
{"type":"turn/start","seq":0,"time":1785097410283,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785097410283,"data":{"content":[{"type":"text","text":"Reply with exactly: child answer 42."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785097410283,"data":{"title":"Reply with exactly: child answer","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1785097410284,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1785097410284,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1785097410836,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":6,"time0":1785097410836,"data":{"turn":1,"step":1,"index":0,"dt":[149,26,0,0,24,1,0,0,0,25,0,1,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","child"," answer"," ","42",".\""]}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1785097411113,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":21,"time0":1785097411113,"data":{"turn":1,"step":1,"index":1,"dt":[1,0,0,0],"texts":["child"," answer"," ","42","."]}}
|
||||
{"type":"assistant/chunk","seq":26,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""}}}}
|
||||
{"type":"assistant/chunk","seq":27,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}
|
||||
{"type":"assistant/chunk","seq":28,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}}}}
|
||||
{"type":"assistant/chunk","seq":29,"time":1785097411138,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":30,"time":1785097411139,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"child answer 42.\""},{"type":"text","text":"child answer 42."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":107,"outputTokens":20,"cacheReadTokens":1664,"reasoningTokens":14}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":31,"time":1785097411143,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":32,"time":1785097411143,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,30 @@
|
||||
{"type":"session","version":0,"id":"sdk-snapshot-subagent","createdAt":1785097408901,"cwd":"/tmp/sdk-snapshot-subagent-spawn-6fzuBd","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1785097408905,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785097408905,"data":{"content":[{"type":"text","text":"Use the subagent tool exactly once with description 'echo probe' and prompt: Reply with exactly: child answer 42. Then reply with the subagent's final answer verbatim."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785097408907,"data":{"title":"Use the subagent tool exactly","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1785097408908,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1785097408908,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1785097409495,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":6,"time0":1785097409496,"data":{"turn":1,"step":1,"index":0,"dt":[170,25,1,0,0,0,0,24,0,1,0,0,0,26,0,0,0,0,0,26,0,0,0,0,0,30,0,0,1,0,0,20,1,0,0,28,0,1,0,0,0,23,1,0,0,0,0,25,1,25,26,1,0,0],"texts":["The"," user"," wants"," me"," to",":\n","1","."," Use"," the"," sub","agent"," tool"," exactly"," once"," with"," description"," '","echo"," probe","'"," and"," prompt"," '","Reply"," with"," exactly",":"," child"," answer"," ","42",".'\n","2","."," Then"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim",".\n\n","Let"," me"," do"," this"," step"," by"," step","."]}}
|
||||
{"type":"assistant/chunk","seq":61,"time":1785097410031,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":62,"time0":1785097410031,"data":{"turn":1,"step":1,"index":1,"dt":[25,1,0,0,0,26,0,0,0,51,1,0,0,0,0,26,1,0,0,0,25,1,0,0,25,1,0],"id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","args":["","{","\"","description","\"",": ","\"","echo"," probe","\"",", ","\"","prom","pt","\"",": ","\"","Reply"," with"," exactly",":"," child"," answer"," ","42",".","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":90,"time":1785097410271,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."}}}}
|
||||
{"type":"assistant/chunk","seq":91,"time":1785097410272,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":92,"time":1785097410272,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}}}}
|
||||
{"type":"assistant/chunk","seq":93,"time":1785097410272,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":94,"time":1785097410276,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to:\n1. Use the subagent tool exactly once with description 'echo probe' and prompt 'Reply with exactly: child answer 42.'\n2. Then reply with the subagent's final answer verbatim.\n\nLet me do this step by step."},{"type":"tool-call","id":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":135,"outputTokens":124,"cacheReadTokens":1664,"reasoningTokens":55}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":95,"time":1785097410277,"data":{"turn":1,"step":1,"callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","name":"subagent","arguments":"{\"description\": \"echo probe\", \"prompt\": \"Reply with exactly: child answer 42.\"}"}}
|
||||
{"type":"tool/result","seq":96,"time":1785097411146,"data":{"turn":1,"step":1,"callId":"call_00_oHPNQ1nLoakoaAGXIxCM7404","content":[{"type":"text","text":"child answer 42."}],"isError":false},"sourceEventSeqs":[95],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":97,"time":1785097411148,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":98,"time":1785097411149,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":99,"time":1785097411681,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":100,"time0":1785097411681,"data":{"turn":1,"step":2,"index":0,"dt":[132,26,0,26,1,26,0,0,0,0,26,0,1,0,0,25,0,0,28,0,0,1,0,0,23],"texts":["The"," sub","agent"," replied"," with"," \"","child"," answer"," ","42",".\""," Now"," I"," need"," to"," reply"," with"," the"," sub","agent","'s"," final"," answer"," verb","atim","."]}}
|
||||
{"type":"assistant/chunk","seq":126,"time":1785097411997,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":127,"time0":1785097411997,"data":{"turn":1,"step":2,"index":1,"dt":[0,0,0,26],"texts":["child"," answer"," ","42","."]}}
|
||||
{"type":"assistant/chunk","seq":132,"time":1785097412024,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."}}}}
|
||||
{"type":"assistant/chunk","seq":133,"time":1785097412025,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"child answer 42."}}}}
|
||||
{"type":"assistant/chunk","seq":134,"time":1785097412025,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}}}}
|
||||
{"type":"assistant/chunk","seq":135,"time":1785097412025,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":136,"time":1785097412026,"data":{"turn":1,"step":2,"content":[{"type":"reasoning","text":"The subagent replied with \"child answer 42.\" Now I need to reply with the subagent's final answer verbatim."},{"type":"text","text":"child answer 42."}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":19,"outputTokens":32,"cacheReadTokens":1920,"reasoningTokens":26}},"sourceEventSeqs":[99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":137,"time":1785097412028,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":138,"time":1785097412028,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,38 @@
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":0,"time":0,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"user/message","seq":1,"time":0,"data":{"content":[{"type":"text","text":"Reply with exactly: SDK snapshot OK"}],"source":{"kind":"user"}},"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"session/title","seq":2,"time":0,"data":{"title":"Reply with exactly: SDK snapshot","messageSeqs":[1],"source":{"kind":"fallback"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/start","seq":3,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"request/header","seq":4,"time":0,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":5,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":6,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":7,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"SD"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":16,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"K"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":17,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" snapshot"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":18,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" OK"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"\"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" Let"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" do"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" that"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":25,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":26,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"SD"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":27,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"K"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":28,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" snapshot"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":" OK"}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"SDK snapshot OK\". Let me do that."}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"SDK snapshot OK"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":1769,"outputTokens":24,"cacheReadTokens":0,"reasoningTokens":19}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":34,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"SDK snapshot OK\". Let me do that."},{"type":"text","text":"SDK snapshot OK"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1769,"outputTokens":24,"cacheReadTokens":0,"reasoningTokens":19}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"surfaceOp":"append"}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"step/end","seq":35,"time":0,"data":{"turn":1,"step":1}}}}
|
||||
{"method":"session.event","params":{"sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":36,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}}
|
||||
{"method":"session.finished","params":{"sessionId":"{{sessionId}}","status":"ok","reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1 @@
|
||||
{"status":"ok","reason":{"kind":"completed"},"finalResponse":"SDK snapshot OK"}
|
||||
@@ -0,0 +1,17 @@
|
||||
{"type":"session","version":0,"id":"sdk-snapshot-text","createdAt":1785097381464,"cwd":"/tmp/sdk-snapshot-text-turn-OwFEJv","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1785097381468,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785097381469,"data":{"content":[{"type":"text","text":"Reply with exactly: SDK snapshot OK"}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785097381471,"data":{"title":"Reply with exactly: SDK snapshot","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"step/start","seq":3,"time":1785097381472,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":4,"time":1785097381472,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":5,"time":1785097381978,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":6,"time0":1785097381979,"data":{"turn":1,"step":1,"index":0,"dt":[138,28,27,1,0,0,24,1,0,0,0,26,0,1,25,1,0,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," exactly"," \"","SD","K"," snapshot"," OK","\"."," Let"," me"," do"," that","."]}}
|
||||
{"type":"assistant/chunk","seq":25,"time":1785097382251,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
||||
{"type":"text-chunks","seq0":26,"time0":1785097382251,"data":{"turn":1,"step":1,"index":1,"dt":[27,0,1],"texts":["SD","K"," snapshot"," OK"]}}
|
||||
{"type":"assistant/chunk","seq":30,"time":1785097382279,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly \"SDK snapshot OK\". Let me do that."}}}}
|
||||
{"type":"assistant/chunk","seq":31,"time":1785097382279,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"SDK snapshot OK"}}}}
|
||||
{"type":"assistant/chunk","seq":32,"time":1785097382279,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":1769,"outputTokens":24,"cacheReadTokens":0,"reasoningTokens":19}}}}
|
||||
{"type":"assistant/chunk","seq":33,"time":1785097382279,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":34,"time":1785097382283,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to reply with exactly \"SDK snapshot OK\". Let me do that."},{"type":"text","text":"SDK snapshot OK"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":1769,"outputTokens":24,"cacheReadTokens":0,"reasoningTokens":19}},"sourceEventSeqs":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":35,"time":1785097382288,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":36,"time":1785097382288,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"description": "Workspace umbrella for runnable demos and example-owned test compositions: declares their cordis.yml packages so plain Node resolves real exports\u2192lib. Not a build target.",
|
||||
"description": "Workspace umbrella for runnable demos and example-owned test compositions: declares their cordis.yml packages so plain Node resolves real exports→lib. Not a build target.",
|
||||
"dependencies": {
|
||||
"@cordisjs/plugin-hmr": "workspace:*",
|
||||
"@cordisjs/plugin-include": "workspace:*",
|
||||
@@ -30,25 +30,26 @@
|
||||
"@deepseek-ai/dsh-llm-replay": "workspace:*",
|
||||
"@deepseek-ai/dsh-lsp": "workspace:*",
|
||||
"@deepseek-ai/dsh-lsp-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-permission": "workspace:*",
|
||||
"@deepseek-ai/dsh-plan-mode": "workspace:*",
|
||||
"@deepseek-ai/dsh-subprocess-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-permission": "workspace:*",
|
||||
"@deepseek-ai/dsh-pty": "workspace:*",
|
||||
"@deepseek-ai/dsh-pty-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-repeat-tool-guard": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-policy": "workspace:^",
|
||||
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-query": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-query-sqlite": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-telemetry-otel": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-title-first-message-llm": "workspace:*",
|
||||
"@deepseek-ai/dsh-spill-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-spill-policy": "workspace:*",
|
||||
"@deepseek-ai/dsh-tui-demo": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-title-first-message-llm": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent-acp": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent-fork": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent-dsh-sdk": "workspace:*",
|
||||
"@deepseek-ai/dsh-subagent-spawn": "workspace:*",
|
||||
"@deepseek-ai/dsh-tasks-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-time-context": "workspace:*",
|
||||
@@ -58,9 +59,9 @@
|
||||
"@deepseek-ai/dsh-tool-cordis": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-fs": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-fs-search": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-pty": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-goal": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-lsp": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-pty": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-ralph": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-session-query": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-subagent": "workspace:*",
|
||||
@@ -68,6 +69,7 @@
|
||||
"@deepseek-ai/dsh-tool-web": "workspace:*",
|
||||
"@deepseek-ai/dsh-tool-workflow": "workspace:*",
|
||||
"@deepseek-ai/dsh-tools": "workspace:*",
|
||||
"@deepseek-ai/dsh-tui-demo": "workspace:*",
|
||||
"@deepseek-ai/dsh-user-approval": "workspace:*",
|
||||
"@deepseek-ai/dsh-web": "workspace:*",
|
||||
"@deepseek-ai/dsh-web-fetch-local": "workspace:*",
|
||||
|
||||
@@ -80,10 +80,19 @@ class ScriptedTuiAdapter extends LlmAdapter {
|
||||
throw new Error('the scripted TUI request did not apply the selected model and reasoning effort')
|
||||
}
|
||||
const lastMessage = options.messages.at(-1)
|
||||
const lastText = (lastMessage?.content ?? [])
|
||||
.filter(block => block.type === 'text')
|
||||
.map(block => block.text)
|
||||
.join('\n')
|
||||
// The loop appends plugin-sourced context (the plan-mode notice, the
|
||||
// tool-skill catalog) AFTER the admitted prompt, so the scripted trigger
|
||||
// may sit one or more user messages back: scan the whole trailing run of
|
||||
// user-role messages since the last assistant message.
|
||||
const trailingUserTexts: string[] = []
|
||||
for (let index = options.messages.length - 1; index >= 0; index--) {
|
||||
const message = options.messages[index]
|
||||
if (message?.role !== 'user') break
|
||||
for (const block of message.content) {
|
||||
if (block.type === 'text') trailingUserTexts.push(block.text)
|
||||
}
|
||||
}
|
||||
const lastText = trailingUserTexts.join('\n')
|
||||
if (lastText.includes(DEFAULT_MODE_PROBE)) {
|
||||
if (options.system?.includes('Stay in plan mode for this scripted TUI test.')) {
|
||||
throw new Error('the scripted TUI request retained plan guidance after /plan off')
|
||||
|
||||
@@ -1,63 +1,54 @@
|
||||
terminal 100x36 buffer=normal length=36 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Use the bash tool to — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=25 bufferRow=25
|
||||
cursor hidden column=7 viewportRow=24 bufferRow=24
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Use the bash tool to"
|
||||
style 1-20 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Use the bash tool to run exactly: echo TERMINAL_OK. Then reply with the single word DONE and stop."
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
8| <blank>
|
||||
9| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
10| " The user wants me to run a simple bash command and then reply with \"DONE\". "
|
||||
style 1-74 fg=bright-black italic
|
||||
11| <blank>
|
||||
12| "▌ "
|
||||
style 0-0 fg=green
|
||||
13| "▌ ✓ echo TERMINAL_OK "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-19 bold
|
||||
14| "▌ Echo TERMINAL_OK to verify terminal access "
|
||||
style 0-0 fg=green
|
||||
style 2-43 fg=bright-black
|
||||
15| "▌ TERMINAL_OK "
|
||||
style 0-0 fg=green
|
||||
16| "▌ [exit 0] "
|
||||
style 0-0 fg=green
|
||||
style 2-9 dim
|
||||
17| "▌ "
|
||||
style 0-0 fg=green
|
||||
18| <blank>
|
||||
19| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
20| " The command ran successfully and output \"TERMINAL_OK\". I should now reply with just \"DONE\". "
|
||||
style 1-91 fg=bright-black italic
|
||||
21| <blank>
|
||||
22| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
23| " DONE "
|
||||
24| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
25| " "
|
||||
style 1-1 inverse
|
||||
26| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
27| "deepseek-v4-flash /workspace/project ↑3.0k ↓115 cache 48% 3% contex"
|
||||
style 0-88 dim
|
||||
style 91-99 dim
|
||||
28-35| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Use the bash tool to run exactly: echo TERMINAL_OK. Then reply with the single word DONE and stop. "
|
||||
6| <blank>
|
||||
7| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
8| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
9| "The user wants me to run a simple bash command and then reply with \"DONE\". "
|
||||
style 0-73 fg=bright-black italic
|
||||
10| <blank>
|
||||
11| "● Tool / bash / Echo TERMINAL_OK to verify terminal access"
|
||||
style 0-57 fg=green
|
||||
12| "$ echo TERMINAL_OK "
|
||||
style 0-17 fg=cyan
|
||||
13| "TERMINAL_OK "
|
||||
14| "[exit 0] "
|
||||
style 0-7 dim
|
||||
15| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
16| <blank>
|
||||
17| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
18| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
19| "The command ran successfully and output \"TERMINAL_OK\". I should now reply with just \"DONE\". "
|
||||
style 0-90 fg=bright-black italic
|
||||
20| "DONE "
|
||||
21| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
22| <blank>
|
||||
23| "/workspace/project deepseek-v4-flash ↑3.0k ↓115 cache 48% 3% contex"
|
||||
style 0-46 fg=bright-blue bold
|
||||
style 49-65 fg=bright-black
|
||||
style 68-88 fg=bright-black
|
||||
style 91-99 fg=bright-black
|
||||
24| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
25-35| <blank>
|
||||
|
||||
@@ -1,65 +1,57 @@
|
||||
terminal 100x36 buffer=normal length=36 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Using ONE run_code program: call — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=26 bufferRow=26
|
||||
cursor hidden column=7 viewportRow=26 bufferRow=26
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Using ONE run_code program: call"
|
||||
style 1-32 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Using ONE run_code program: call the bash tool exactly once with the command seq 1 200 | awk "
|
||||
style 0-0 fg=bright-blue
|
||||
style 79-99 fg=cyan
|
||||
7| "▌ '{printf \"line %04d: the quick brown fox jumps over the lazy dog\\n\", $1}', then return ONLY the "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-74 fg=cyan
|
||||
8| "▌ number of lines in its output. Reply with just that number and stop. "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
10| <blank>
|
||||
11| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
12| " The user wants me to write a single run_code program that calls bash exactly once with a specific "
|
||||
style 1-99 fg=bright-black italic
|
||||
13| " command, then returns only the number of lines in its output. "
|
||||
style 1-61 fg=bright-black italic
|
||||
14| <blank>
|
||||
15| "▌ "
|
||||
style 0-0 fg=green
|
||||
16| "▌ ✓ Count lines in seq/awk output "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-32 bold
|
||||
17| "▌ 200 "
|
||||
style 0-0 fg=green
|
||||
18| "▌ "
|
||||
style 0-0 fg=green
|
||||
19| <blank>
|
||||
20| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
21| " The result is 200 lines. The user wants me to reply with just that number and stop. "
|
||||
style 1-83 fg=bright-black italic
|
||||
22| <blank>
|
||||
23| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
24| " 200 "
|
||||
25| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
26| " "
|
||||
style 1-1 inverse
|
||||
27| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
28| "deepseek-v4-flash /workspace/project ↑123 ↓208 cache 99% 4% c"
|
||||
style 0-93 dim
|
||||
style 96-99 dim
|
||||
29-35| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Using ONE run_code program: call the bash tool exactly once with the command seq 1 200 | awk "
|
||||
style 77-99 fg=cyan
|
||||
6| "'{printf \"line %04d: the quick brown fox jumps over the lazy dog\\n\", $1}', then return ONLY the "
|
||||
style 0-72 fg=cyan
|
||||
7| "number of lines in its output. Reply with just that number and stop. "
|
||||
8| <blank>
|
||||
9| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
10| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
11| "The user wants me to write a single run_code program that calls bash exactly once with a specific "
|
||||
style 0-99 fg=bright-black italic
|
||||
12| "command, then returns only the number of lines in its output. "
|
||||
style 0-60 fg=bright-black italic
|
||||
13| <blank>
|
||||
14| "● Tool / run_code"
|
||||
style 0-16 fg=green
|
||||
15| "Count lines in seq/awk output "
|
||||
16| "200 "
|
||||
17| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
18| <blank>
|
||||
19| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
20| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
21| "The result is 200 lines. The user wants me to reply with just that number and stop. "
|
||||
style 0-82 fg=bright-black italic
|
||||
22| "200 "
|
||||
23| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
24| <blank>
|
||||
25| "/workspace/project deepseek-v4-flash ↑123 ↓208 cache 99% 3% c"
|
||||
style 0-52 fg=bright-blue bold
|
||||
style 55-71 fg=bright-black
|
||||
style 74-93 fg=bright-black
|
||||
style 96-99 fg=bright-black
|
||||
26| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
27-35| <blank>
|
||||
|
||||
@@ -1,136 +1,140 @@
|
||||
terminal 100x36 buffer=normal length=64 base=28 viewport=28
|
||||
terminal 100x36 buffer=normal length=62 base=26 viewport=26
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Using ONE run_code program: call — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=33 bufferRow=61
|
||||
cursor hidden column=7 viewportRow=35 bufferRow=61
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Using ONE run_code program: call"
|
||||
style 1-32 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Using ONE run_code program: call the bash tool twice — exactly echo CODE_ONE then exactly echo "
|
||||
style 0-0 fg=bright-blue
|
||||
style 65-77 fg=cyan
|
||||
style 92-99 fg=cyan
|
||||
7| "▌ CODE_TWO. Inside that same program, console.log exactly captured output, then return the two "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-9 fg=cyan
|
||||
style 58-72 fg=cyan
|
||||
8| "▌ outputs joined with a plus sign. Reply with that joined string only and stop. "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
10| <blank>
|
||||
11| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
12| " The user wants me to write a single run_code program that: "
|
||||
style 1-36 fg=bright-black italic
|
||||
style 37-44 fg=cyan
|
||||
style 45-58 fg=bright-black italic
|
||||
13| " 1. Calls bash tool twice - first with echo CODE_ONE, then with echo CODE_TWO "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-9 fg=bright-black italic
|
||||
style 10-13 fg=cyan
|
||||
style 14-38 fg=bright-black italic
|
||||
style 39-51 fg=cyan
|
||||
style 52-63 fg=bright-black italic
|
||||
style 64-76 fg=cyan
|
||||
14| " 2. console.log exactly captured output "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-14 fg=cyan
|
||||
style 15-23 fg=bright-black italic
|
||||
style 24-38 fg=cyan
|
||||
15| " 3. Returns the two outputs joined with a plus sign "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-50 fg=bright-black italic
|
||||
16| " "
|
||||
17| " Let me think about the structure. The bash tool returns an object with stdout/stderr. I need to "
|
||||
style 1-38 fg=bright-black italic
|
||||
style 39-42 fg=cyan
|
||||
style 43-99 fg=bright-black italic
|
||||
18| " extract the stdout text from each call. "
|
||||
style 1-39 fg=bright-black italic
|
||||
19| " "
|
||||
20| " Looking at the bash output type: "
|
||||
style 1-32 fg=bright-black italic
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Using ONE run_code program: call the bash tool twice — exactly echo CODE_ONE then exactly echo "
|
||||
style 63-75 fg=cyan
|
||||
style 90-99 fg=cyan
|
||||
6| "CODE_TWO. Inside that same program, console.log exactly captured output, then return the two outputs"
|
||||
style 0-7 fg=cyan
|
||||
style 56-70 fg=cyan
|
||||
7| "joined with a plus sign. Reply with that joined string only and stop. "
|
||||
8| <blank>
|
||||
9| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
10| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
11| "The user wants me to write a single run_code program that: "
|
||||
style 0-35 fg=bright-black italic
|
||||
style 36-43 fg=cyan
|
||||
style 44-57 fg=bright-black italic
|
||||
12| "1. Calls bash tool twice - first with echo CODE_ONE, then with echo CODE_TWO "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-8 fg=bright-black italic
|
||||
style 9-12 fg=cyan
|
||||
style 13-37 fg=bright-black italic
|
||||
style 38-50 fg=cyan
|
||||
style 51-62 fg=bright-black italic
|
||||
style 63-75 fg=cyan
|
||||
13| "2. console.log exactly captured output "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-13 fg=cyan
|
||||
style 14-22 fg=bright-black italic
|
||||
style 23-37 fg=cyan
|
||||
14| "3. Returns the two outputs joined with a plus sign "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-49 fg=bright-black italic
|
||||
15| " "
|
||||
16| "Let me think about the structure. The bash tool returns an object with stdout/stderr. I need to "
|
||||
style 0-37 fg=bright-black italic
|
||||
style 38-41 fg=cyan
|
||||
style 42-99 fg=bright-black italic
|
||||
17| "extract the stdout text from each call. "
|
||||
style 0-38 fg=bright-black italic
|
||||
18| " "
|
||||
19| "Looking at the bash output type: "
|
||||
style 0-31 fg=bright-black italic
|
||||
20| " "
|
||||
21| " "
|
||||
22| " ``` "
|
||||
style 1-3 dim
|
||||
23| " { "
|
||||
24| " kind: \"foreground\"; "
|
||||
25| " exitCode: number | null; "
|
||||
26| " signal: string | null; "
|
||||
27| " timedOut: boolean; "
|
||||
28| " aborted: boolean; "
|
||||
29| " timeoutMs: number; "
|
||||
30| " stdout: { "
|
||||
31| " text: string; "
|
||||
32| " truncated: boolean; "
|
||||
33| " spillPath?: string; "
|
||||
34| " }; "
|
||||
35| " stderr: { ... }; "
|
||||
36| " sandbox?: { ... }; "
|
||||
37| " } "
|
||||
38| " ``` "
|
||||
style 1-3 dim
|
||||
39| " "
|
||||
40| " So I need to access .stdout.text from each result. "
|
||||
style 1-20 fg=bright-black italic
|
||||
style 21-32 fg=cyan
|
||||
style 33-50 fg=bright-black italic
|
||||
41| " "
|
||||
42| " Let me write the program. "
|
||||
style 1-25 fg=bright-black italic
|
||||
43| <blank>
|
||||
44| "▌ "
|
||||
style 0-0 fg=green
|
||||
45| "▌ ✓ Call bash twice, log, join outputs "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-37 bold
|
||||
46| "▌ captured output "
|
||||
style 0-0 fg=green
|
||||
47| "▌ CODE_ONE+CODE_TWO "
|
||||
style 0-0 fg=green
|
||||
48| "▌ "
|
||||
style 0-0 fg=green
|
||||
49| <blank>
|
||||
50| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
51| " The program ran successfully. The output shows: "
|
||||
style 1-47 fg=bright-black italic
|
||||
52| " - captured output (from console.log) "
|
||||
style 1-2 fg=bright-blue
|
||||
style 3-17 fg=cyan
|
||||
style 18-36 fg=bright-black italic
|
||||
53| " - CODE_ONE+CODE_TWO (the returned joined string) "
|
||||
style 1-2 fg=bright-blue
|
||||
style 3-19 fg=cyan
|
||||
style 20-48 fg=bright-black italic
|
||||
22| " { "
|
||||
style 2-2 fg=cyan
|
||||
23| " kind: \"foreground\"; "
|
||||
style 2-22 fg=cyan
|
||||
24| " exitCode: number | null; "
|
||||
style 2-27 fg=cyan
|
||||
25| " signal: string | null; "
|
||||
style 2-25 fg=cyan
|
||||
26| " timedOut: boolean; "
|
||||
style 2-21 fg=cyan
|
||||
27| " aborted: boolean; "
|
||||
style 2-20 fg=cyan
|
||||
28| " timeoutMs: number; "
|
||||
style 2-21 fg=cyan
|
||||
29| " stdout: { "
|
||||
style 2-12 fg=cyan
|
||||
30| " text: string; "
|
||||
style 2-18 fg=cyan
|
||||
31| " truncated: boolean; "
|
||||
style 2-24 fg=cyan
|
||||
32| " spillPath?: string; "
|
||||
style 2-24 fg=cyan
|
||||
33| " }; "
|
||||
style 2-5 fg=cyan
|
||||
34| " stderr: { ... }; "
|
||||
style 2-19 fg=cyan
|
||||
35| " sandbox?: { ... }; "
|
||||
style 2-21 fg=cyan
|
||||
36| " } "
|
||||
style 2-2 fg=cyan
|
||||
37| " "
|
||||
38| " "
|
||||
39| "So I need to access .stdout.text from each result. "
|
||||
style 0-19 fg=bright-black italic
|
||||
style 20-31 fg=cyan
|
||||
style 32-49 fg=bright-black italic
|
||||
40| " "
|
||||
41| "Let me write the program. "
|
||||
style 0-24 fg=bright-black italic
|
||||
42| <blank>
|
||||
43| "● Tool / run_code"
|
||||
style 0-16 fg=green
|
||||
44| "Call bash twice, log, join outputs "
|
||||
45| "captured output "
|
||||
46| "CODE_ONE+CODE_TWO "
|
||||
47| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
48| <blank>
|
||||
49| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
50| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
51| "The program ran successfully. The output shows: "
|
||||
style 0-46 fg=bright-black italic
|
||||
52| "- captured output (from console.log) "
|
||||
style 0-1 fg=bright-blue
|
||||
style 2-16 fg=cyan
|
||||
style 17-35 fg=bright-black italic
|
||||
53| "- CODE_ONE+CODE_TWO (the returned joined string) "
|
||||
style 0-1 fg=bright-blue
|
||||
style 2-18 fg=cyan
|
||||
style 19-47 fg=bright-black italic
|
||||
54| " "
|
||||
55| " The user asked me to reply with that joined string only and stop. So I'll reply with just "
|
||||
style 1-99 fg=bright-black italic
|
||||
56| " CODE_ONE+CODE_TWO. "
|
||||
style 1-17 fg=cyan
|
||||
style 18-18 fg=bright-black italic
|
||||
57| <blank>
|
||||
58| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
59| " CODE_ONE+CODE_TWO "
|
||||
60| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
61| " "
|
||||
style 1-1 inverse
|
||||
62| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
63| "deepseek-v4-flash /workspace/project ↑182 ↓446 cache 98% 4% context tools:c"
|
||||
style 0-78 dim
|
||||
style 81-99 dim
|
||||
55| "The user asked me to reply with that joined string only and stop. So I'll reply with just "
|
||||
style 0-99 fg=bright-black italic
|
||||
56| "CODE_ONE+CODE_TWO. "
|
||||
style 0-16 fg=cyan
|
||||
style 17-17 fg=bright-black italic
|
||||
57| "CODE_ONE+CODE_TWO "
|
||||
58| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
59| <blank>
|
||||
60| "/workspace/project deepseek-v4-flash ↑182 ↓446 cache 98% 4% context"
|
||||
style 0-37 fg=bright-blue bold
|
||||
style 40-56 fg=bright-black
|
||||
style 59-78 fg=bright-black
|
||||
style 81-90 fg=bright-black
|
||||
61| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{"type": "session", "version": 0, "id": "11111111-1111-4111-8111-111111111111", "createdAt": 1783950000000, "cwd": "/tmp/advanced-acp", "delegationDepth": 0}
|
||||
{"type":"turn/start","seq":0,"time":1783957884479,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1783957884479,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":1,"time":1783957884479,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"}},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":2,"time":1783957884486,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":3,"time":1783957884486,"data":{"header":{"config":{"provider":"deepseek","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"assistant/chunk","seq":4,"time":1783950000005,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
@@ -10,17 +10,17 @@
|
||||
{"type":"assistant/chunk","seq":8,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":9,"time":1783957884487,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[4,5,6,7,8],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":10,"time":1783957884487,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}
|
||||
{"type":"tool/result","seq":11,"time":1783957884488,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"mounted dyn-1 (plugin \"snapshot-marker\", state: active)"}],"isError":false},"sourceEventSeqs":[10],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":11,"time":1783957884488,"data":{"turn":1,"step":1,"callId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false},"sourceEventSeqs":[10],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":12,"time":1783957884489,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":13,"time":1783957884489,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":14,"time":1783950000015,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":15,"time":1783950000016,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Verify the dynamically mounted marker service\"}"}}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Verify the dynamically mounted marker service\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":15,"time":1783950000016,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Verify the temporary marker Plugin\"}"}}}
|
||||
{"type":"assistant/chunk","seq":16,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Verify the temporary marker Plugin\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1783950000018,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":19,"time":1783957884490,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Verify the dynamically mounted marker service\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[14,15,16,17,18],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":20,"time":1783957884490,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'dynamic' })\", \"description\": \"Verify the dynamically mounted marker service\"}"}}
|
||||
{"type":"tool/code-dispatch","seq":21,"time":1783957884560,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"dynamic"},"isError":false,"resultSummary":"## dynamic\n- dyn-1: snapshot-marker [active]"}}
|
||||
{"type":"assistant/message","seq":19,"time":1783957884490,"data":{"turn":1,"step":2,"content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Verify the temporary marker Plugin\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[14,15,16,17,18],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":20,"time":1783957884490,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Verify the temporary marker Plugin\"}"}}
|
||||
{"type":"tool/code-dispatch","seq":21,"time":1783957884560,"data":{"parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"resultSummary":"## dynamic\n- dyn-1: snapshot-marker [active]"}}
|
||||
{"type":"tool/result","seq":22,"time":1783957884561,"data":{"turn":1,"step":2,"callId":"advanced-code","content":[{"type":"text","text":"## dynamic\n- dyn-1: snapshot-marker [active]"}],"isError":false,"meta":{"logs":[]}},"sourceEventSeqs":[20],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":23,"time":1783957884561,"data":{"turn":1,"step":2}}
|
||||
{"type":"step/start","seq":24,"time":1783957884562,"data":{"turn":1,"step":3}}
|
||||
@@ -51,7 +51,7 @@
|
||||
{"type":"assistant/chunk","seq":49,"time":1783957884719,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":50,"time":1783957884719,"data":{"turn":1,"step":5,"content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[45,46,47,48,49],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":51,"time":1783957884719,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}
|
||||
{"type":"tool/result","seq":52,"time":1783957884719,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"unmounted dyn-1 (plugin \"snapshot-marker\")"}],"isError":false},"sourceEventSeqs":[51],"surfaceOp":"append"}
|
||||
{"type":"tool/result","seq":52,"time":1783957884719,"data":{"turn":1,"step":5,"callId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false},"sourceEventSeqs":[51],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":53,"time":1783957884719,"data":{"turn":1,"step":5}}
|
||||
{"type":"step/start","seq":54,"time":1783957884720,"data":{"turn":1,"step":6}}
|
||||
{"type":"assistant/chunk","seq":55,"time":1783957884720,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
|
||||
@@ -1,106 +1,95 @@
|
||||
terminal 100x36 buffer=normal length=48 base=12 viewport=12
|
||||
terminal 100x36 buffer=normal length=59 base=23 viewport=23
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Run this advanced flow exactly — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=33 bufferRow=45
|
||||
cursor hidden column=7 viewportRow=35 bufferRow=58
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Run this advanced flow exactly"
|
||||
style 1-30 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Run this advanced flow exactly once: mount a no-op Cordis plugin named snapshot-marker; use "
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ run_code to inspect the live dynamic mounts through tools.cordis_inspect; delegate once to a "
|
||||
style 0-0 fg=bright-blue
|
||||
8| "▌ direct spawn child; run one workflow that delegates to another spawn child; unmount dyn-1; then "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ reply with exactly ADVANCED_ACP_OK. "
|
||||
style 0-0 fg=bright-blue
|
||||
10| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use "
|
||||
6| "run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a "
|
||||
7| "direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply "
|
||||
8| "with exactly ADVANCED_ACP_OK. "
|
||||
9| <blank>
|
||||
10| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
11| <blank>
|
||||
12| "▌ "
|
||||
style 0-0 fg=green
|
||||
13| "▌ ✓ Mount plugin into live cordis runtime "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-40 bold
|
||||
14| "▌ mounted dyn-1 (plugin \"snapshot-marker\", state: active) "
|
||||
style 0-0 fg=green
|
||||
15| "▌ "
|
||||
style 0-0 fg=green
|
||||
16| <blank>
|
||||
17| "▌ "
|
||||
style 0-0 fg=green
|
||||
18| "▌ ✓ Verify the dynamically mounted marker service "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-48 bold
|
||||
19| "▌ ## dynamic "
|
||||
style 0-0 fg=green
|
||||
20| "▌ - dyn-1: snapshot-marker [active] "
|
||||
style 0-0 fg=green
|
||||
21| "▌ "
|
||||
style 0-0 fg=green
|
||||
22| <blank>
|
||||
23| "▌ "
|
||||
style 0-0 fg=green
|
||||
24| "▌ ✓ subagent "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-11 bold
|
||||
25| "▌ DIRECT_CHILD_OK "
|
||||
style 0-0 fg=green
|
||||
26| "▌ "
|
||||
style 0-0 fg=green
|
||||
27| <blank>
|
||||
28| "▌ "
|
||||
style 0-0 fg=green
|
||||
29| "▌ ✓ workflow: advanced-acp-snapshot "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-34 bold
|
||||
30| "▌ workflow \"advanced-acp-snapshot\" completed (1 agent). "
|
||||
style 0-0 fg=green
|
||||
31| "▌ Return value: "
|
||||
style 0-0 fg=green
|
||||
32| "▌ { "
|
||||
style 0-0 fg=green
|
||||
33| "▌ \"reply\": \"WORKFLOW_CHILD_OK\" "
|
||||
style 0-0 fg=green
|
||||
34| "▌ } "
|
||||
style 0-0 fg=green
|
||||
35| "▌ "
|
||||
style 0-0 fg=green
|
||||
12| "● Tool / cordis_mount"
|
||||
style 0-20 fg=green
|
||||
13| "Mount temporary Cordis Plugin "
|
||||
14| "Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH "
|
||||
15| "restarts). "
|
||||
16| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
17| <blank>
|
||||
18| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
19| <blank>
|
||||
20| "● Tool / run_code"
|
||||
style 0-16 fg=green
|
||||
21| "Verify the temporary marker Plugin "
|
||||
22| " "
|
||||
23| "Temporary Plugins "
|
||||
style 0-16 fg=bright-blue bold
|
||||
24| " "
|
||||
25| "- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: "
|
||||
style 0-1 fg=bright-blue
|
||||
26| " until unmounted or DSH restarts "
|
||||
27| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
28| <blank>
|
||||
29| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
30| <blank>
|
||||
31| "● Tool / subagent"
|
||||
style 0-16 fg=green
|
||||
32| "DIRECT_CHILD_OK "
|
||||
33| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
34| <blank>
|
||||
35| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
36| <blank>
|
||||
37| "▌ "
|
||||
style 0-0 fg=green
|
||||
38| "▌ ✓ Unmount dyn-1 "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-16 bold
|
||||
39| "▌ unmounted dyn-1 (plugin \"snapshot-marker\") "
|
||||
style 0-0 fg=green
|
||||
40| "▌ "
|
||||
style 0-0 fg=green
|
||||
41| <blank>
|
||||
42| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
43| " ADVANCED_ACP_OK "
|
||||
44| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
45| " "
|
||||
style 1-1 inverse
|
||||
46| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
47| "deepseek-v4-flash /workspace/project ↑18 ↓18 cache 0% 8% cont"
|
||||
style 0-90 dim
|
||||
style 93-99 dim
|
||||
37| "● Tool / workflow"
|
||||
style 0-16 fg=green
|
||||
38| "workflow: advanced-acp-snapshot "
|
||||
39| "workflow \"advanced-acp-snapshot\" completed (1 agent). "
|
||||
40| "Return value: "
|
||||
41| "{ "
|
||||
42| " \"reply\": \"WORKFLOW_CHILD_OK\" "
|
||||
43| "} "
|
||||
44| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
45| <blank>
|
||||
46| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
47| <blank>
|
||||
48| "● Tool / cordis_unmount"
|
||||
style 0-22 fg=green
|
||||
49| "Unmount temporary Cordis Plugin dyn-1 "
|
||||
50| "Temporary Plugin dyn-1 was unmounted and removed. "
|
||||
51| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
52| <blank>
|
||||
53| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
54| "ADVANCED_ACP_OK "
|
||||
55| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
56| <blank>
|
||||
57| "/workspace/project deepseek-v4-flash ↑18 ↓18 cache 0% 8% cont"
|
||||
style 0-52 fg=bright-blue bold
|
||||
style 55-71 fg=bright-black
|
||||
style 74-90 fg=bright-black
|
||||
style 93-99 fg=bright-black
|
||||
58| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -1,96 +1,80 @@
|
||||
terminal 100x36 buffer=normal length=45 base=9 viewport=9
|
||||
terminal 100x36 buffer=normal length=43 base=7 viewport=7
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Use the workflow tool exactly — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=33 bufferRow=42
|
||||
cursor hidden column=7 viewportRow=35 bufferRow=42
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Use the workflow tool exactly"
|
||||
style 1-29 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Use the workflow tool exactly once, with args omitted, meta set to { \"name\": \"snapshot-flow\", "
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ \"description\": \"one child for the snapshot\" }, and this EXACT script body (copy it verbatim): "
|
||||
style 0-0 fg=bright-blue
|
||||
8| "▌ phase('Run') "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ const reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.') "
|
||||
style 0-0 fg=bright-blue
|
||||
10| "▌ return { reply } "
|
||||
style 0-0 fg=bright-blue
|
||||
11| "▌ After the workflow returns, reply with the single word WORKFLOW_DONE and stop. Do not use any "
|
||||
style 0-0 fg=bright-blue
|
||||
12| "▌ other tool. "
|
||||
style 0-0 fg=bright-blue
|
||||
13| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
14| <blank>
|
||||
15| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
16| " The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully "
|
||||
style 1-99 fg=bright-black italic
|
||||
17| " follow the instructions: "
|
||||
style 1-24 fg=bright-black italic
|
||||
18| " "
|
||||
19| " 1. args omitted (so I don't include it) "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-39 fg=bright-black italic
|
||||
20| " 2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" } "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-82 fg=bright-black italic
|
||||
21| " 3. script = as given verbatim "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-29 fg=bright-black italic
|
||||
22| " 4. After it returns, reply with \"WORKFLOW_DONE\" "
|
||||
style 1-3 fg=bright-blue
|
||||
style 4-47 fg=bright-black italic
|
||||
23| " "
|
||||
24| " Let me do exactly that. "
|
||||
style 1-23 fg=bright-black italic
|
||||
25| <blank>
|
||||
26| "▌ "
|
||||
style 0-0 fg=green
|
||||
27| "▌ ✓ workflow: snapshot-flow "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-26 bold
|
||||
28| "▌ workflow \"snapshot-flow\" completed (1 agent). "
|
||||
style 0-0 fg=green
|
||||
29| "▌ Return value: "
|
||||
style 0-0 fg=green
|
||||
30| "▌ { "
|
||||
style 0-0 fg=green
|
||||
31| "▌ \"reply\": \"WF_CHILD_OK\" "
|
||||
style 0-0 fg=green
|
||||
32| "▌ } "
|
||||
style 0-0 fg=green
|
||||
33| "▌ "
|
||||
style 0-0 fg=green
|
||||
34| <blank>
|
||||
35| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
36| " The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly "
|
||||
style 1-99 fg=bright-black italic
|
||||
37| " \"WORKFLOW_DONE\" and stop. "
|
||||
style 1-25 fg=bright-black italic
|
||||
38| <blank>
|
||||
39| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
40| " WORKFLOW_DONE "
|
||||
41| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
42| " "
|
||||
style 1-1 inverse
|
||||
43| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
44| "deepseek-v4-flash /workspace/project ↑3.5k ↓227 cache 47% 3% context "
|
||||
style 0-86 dim
|
||||
style 89-99 dim
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Use the workflow tool exactly once, with args omitted, meta set to { \"name\": \"snapshot-flow\", "
|
||||
6| "\"description\": \"one child for the snapshot\" }, and this EXACT script body (copy it verbatim): "
|
||||
7| "phase('Run') "
|
||||
8| "const reply = await agent('Reply with exactly the word WF_CHILD_OK and nothing else.') "
|
||||
9| "return { reply } "
|
||||
10| "After the workflow returns, reply with the single word WORKFLOW_DONE and stop. Do not use any other "
|
||||
11| "tool. "
|
||||
12| <blank>
|
||||
13| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
14| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
15| "The user wants me to use the workflow tool exactly once with specific parameters. Let me carefully "
|
||||
style 0-99 fg=bright-black italic
|
||||
16| "follow the instructions: "
|
||||
style 0-23 fg=bright-black italic
|
||||
17| " "
|
||||
18| "1. args omitted (so I don't include it) "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-38 fg=bright-black italic
|
||||
19| "2. meta = { \"name\": \"snapshot-flow\", \"description\": \"one child for the snapshot\" } "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-81 fg=bright-black italic
|
||||
20| "3. script = as given verbatim "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-28 fg=bright-black italic
|
||||
21| "4. After it returns, reply with \"WORKFLOW_DONE\" "
|
||||
style 0-2 fg=bright-blue
|
||||
style 3-46 fg=bright-black italic
|
||||
22| " "
|
||||
23| "Let me do exactly that. "
|
||||
style 0-22 fg=bright-black italic
|
||||
24| <blank>
|
||||
25| "● Tool / workflow"
|
||||
style 0-16 fg=green
|
||||
26| "workflow: snapshot-flow "
|
||||
27| "workflow \"snapshot-flow\" completed (1 agent). "
|
||||
28| "Return value: "
|
||||
29| "{ "
|
||||
30| " \"reply\": \"WF_CHILD_OK\" "
|
||||
31| "} "
|
||||
32| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
33| <blank>
|
||||
34| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
35| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
36| "The workflow returned successfully with the reply \"WF_CHILD_OK\". Now I need to reply with exactly "
|
||||
style 0-99 fg=bright-black italic
|
||||
37| "\"WORKFLOW_DONE\" and stop. "
|
||||
style 0-24 fg=bright-black italic
|
||||
38| "WORKFLOW_DONE "
|
||||
39| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
40| <blank>
|
||||
41| "/workspace/project deepseek-v4-flash ↑3.5k ↓227 cache 47% 3% context"
|
||||
style 0-44 fg=bright-blue bold
|
||||
style 47-63 fg=bright-black
|
||||
style 66-86 fg=bright-black
|
||||
style 89-98 fg=bright-black
|
||||
42| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
|
||||
@@ -1,70 +1,62 @@
|
||||
terminal 100x36 buffer=normal length=36 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Reply with exactly the word: — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=33 bufferRow=33
|
||||
cursor hidden column=7 viewportRow=30 bufferRow=30
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Reply with exactly the word:"
|
||||
style 1-28 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| " Entering plan mode (applies from the next step). Use /plan off to leave. "
|
||||
style 1-72 fg=bright-black
|
||||
5| <blank>
|
||||
6| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
8| "▌ Reply with exactly the word: ONE. No tools. "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
10| <blank>
|
||||
11| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
12| " The user wants me to reply with exactly the word \"ONE\" and use no tools. "
|
||||
style 1-72 fg=bright-black italic
|
||||
13| <blank>
|
||||
14| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
15| " ONE "
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Reply with exactly the word: ONE. No tools. "
|
||||
6| <blank>
|
||||
7| "Entering plan mode (applies from the next step). Use /plan off to leave. "
|
||||
style 0-71 fg=bright-black
|
||||
8| <blank>
|
||||
9| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
10| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
11| "The user wants me to reply with exactly the word \"ONE\" and use no tools. "
|
||||
style 0-71 fg=bright-black italic
|
||||
12| "ONE "
|
||||
13| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
14| <blank>
|
||||
15| "Leaving plan mode (applies from the next step). "
|
||||
style 0-46 fg=bright-black
|
||||
16| <blank>
|
||||
17| " Leaving plan mode (applies from the next step). "
|
||||
style 1-47 fg=bright-black
|
||||
18| <blank>
|
||||
19| " Context · plan-mode "
|
||||
style 1-19 dim
|
||||
20| " The user switched this session back to the default mode. "
|
||||
style 1-56 fg=bright-black
|
||||
21| <blank>
|
||||
22| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
23| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
24| "▌ Reply with exactly the word: TWO. No tools. "
|
||||
style 0-0 fg=bright-blue
|
||||
25| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
26| <blank>
|
||||
27| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
28| " The user wants me to reply with exactly the word \"TWO\" and no tools. "
|
||||
style 1-68 fg=bright-black italic
|
||||
29| <blank>
|
||||
30| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
31| " TWO "
|
||||
32| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
33| " "
|
||||
style 1-1 inverse
|
||||
34| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
35| "deepseek-v4-flash /workspace/project ↑2.9k ↓41 cache 49% 3% co"
|
||||
style 0-92 dim
|
||||
style 95-99 dim
|
||||
17| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
18| "Reply with exactly the word: TWO. No tools. "
|
||||
19| <blank>
|
||||
20| "Context · plan-mode "
|
||||
style 0-18 dim
|
||||
21| "The user switched this session back to the default mode. "
|
||||
style 0-55 fg=bright-black
|
||||
22| <blank>
|
||||
23| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
24| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
25| "The user wants me to reply with exactly the word \"TWO\" and no tools. "
|
||||
style 0-67 fg=bright-black italic
|
||||
26| "TWO "
|
||||
27| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
28| <blank>
|
||||
29| "/workspace/project deepseek-v4-flash ↑2.9k ↓41 cache 49% 3% co"
|
||||
style 0-51 fg=bright-blue bold
|
||||
style 54-70 fg=bright-black
|
||||
style 73-92 fg=bright-black
|
||||
style 95-99 fg=bright-black
|
||||
30| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
31-35| <blank>
|
||||
|
||||
@@ -1,81 +1,52 @@
|
||||
terminal 100x36 buffer=normal length=37 base=1 viewport=1
|
||||
terminal 100x36 buffer=normal length=36 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Use the read tool twice — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=33 bufferRow=34
|
||||
cursor hidden column=7 viewportRow=27 bufferRow=27
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Use the read tool twice"
|
||||
style 1-23 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Use the read tool twice in the same assistant message: read a.txt and b.txt. Then reply DONE. "
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Use the read tool twice in the same assistant message: read a.txt and b.txt. Then reply DONE. "
|
||||
6| <blank>
|
||||
7| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
8| <blank>
|
||||
9| "▌ "
|
||||
style 0-0 fg=green
|
||||
10| "▌ ✓ Read a.txt "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-13 bold
|
||||
11| "▌ <path>/workspace/project/a.txt</path> "
|
||||
style 0-0 fg=green
|
||||
12| "▌ <type>file</type> "
|
||||
style 0-0 fg=green
|
||||
13| "▌ <content> "
|
||||
style 0-0 fg=green
|
||||
14| "▌ 1: alpha "
|
||||
style 0-0 fg=green
|
||||
15| "▌ "
|
||||
style 0-0 fg=green
|
||||
16| "▌ (End of file - total 1 lines) "
|
||||
style 0-0 fg=green
|
||||
17| "▌ </content> "
|
||||
style 0-0 fg=green
|
||||
18| "▌ "
|
||||
style 0-0 fg=green
|
||||
19| <blank>
|
||||
20| "▌ "
|
||||
style 0-0 fg=green
|
||||
21| "▌ ✓ Read b.txt "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-13 bold
|
||||
22| "▌ <path>/workspace/project/b.txt</path> "
|
||||
style 0-0 fg=green
|
||||
23| "▌ <type>file</type> "
|
||||
style 0-0 fg=green
|
||||
24| "▌ <content> "
|
||||
style 0-0 fg=green
|
||||
25| "▌ 1: beta "
|
||||
style 0-0 fg=green
|
||||
26| "▌ "
|
||||
style 0-0 fg=green
|
||||
27| "▌ (End of file - total 1 lines) "
|
||||
style 0-0 fg=green
|
||||
28| "▌ </content> "
|
||||
style 0-0 fg=green
|
||||
29| "▌ "
|
||||
style 0-0 fg=green
|
||||
30| <blank>
|
||||
31| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
32| " DONE "
|
||||
33| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
34| " "
|
||||
style 1-1 inverse
|
||||
35| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
36| "deepseek-v4-flash /workspace/project ↑20 ↓6 cache 0% 3% context t"
|
||||
style 0-84 dim
|
||||
style 87-99 dim
|
||||
9| "● Tool / read"
|
||||
style 0-12 fg=green
|
||||
10| "Read a.txt "
|
||||
11| "1: alpha "
|
||||
12| " "
|
||||
13| "(End of file - total 1 lines) "
|
||||
14| <blank>
|
||||
15| "● Tool / read"
|
||||
style 0-12 fg=green
|
||||
16| "Read b.txt "
|
||||
17| "1: beta "
|
||||
18| " "
|
||||
19| "(End of file - total 1 lines) "
|
||||
20| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
21| <blank>
|
||||
22| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
23| "DONE "
|
||||
24| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
25| <blank>
|
||||
26| "/workspace/project deepseek-v4-flash ↑20 ↓6 cache 0% 3% context"
|
||||
style 0-47 fg=bright-blue bold
|
||||
style 50-66 fg=bright-black
|
||||
style 69-84 fg=bright-black
|
||||
style 87-96 fg=bright-black
|
||||
27| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
28-35| <blank>
|
||||
|
||||
@@ -1,57 +1,48 @@
|
||||
terminal 100x36 buffer=normal length=36 base=0 viewport=0
|
||||
lifecycle started=1 stopped=0 progress=inactive
|
||||
title "Use the todo_write tool to — DSH TUI snapshot"
|
||||
cursor hidden column=1 viewportRow=31 bufferRow=31
|
||||
cursor hidden column=7 viewportRow=31 bufferRow=31
|
||||
buffer
|
||||
0| " DEEPSEEK HARNESS"
|
||||
style 1-8 fg=bright-blue bold
|
||||
style 10-16 bold
|
||||
1| " Use the todo_write tool to"
|
||||
style 1-26 fg=bright-black
|
||||
2| " deepseek-v4-flash • main-session"
|
||||
style 1-34 dim
|
||||
2| " main-session"
|
||||
style 1-12 dim
|
||||
3| <blank>
|
||||
4| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
5| "▌ You "
|
||||
style 0-0 fg=bright-blue
|
||||
style 2-4 fg=bright-blue bold
|
||||
6| "▌ Use the todo_write tool to record a plan with exactly three todos: \"read the code\" (in_progress), "
|
||||
style 0-0 fg=bright-blue
|
||||
7| "▌ \"write the fix\" (pending), \"run the tests\" (pending). Send all three in one todo_write call. Then "
|
||||
style 0-0 fg=bright-blue
|
||||
8| "▌ reply with the single word DONE and stop. "
|
||||
style 0-0 fg=bright-blue
|
||||
9| "▌ "
|
||||
style 0-0 fg=bright-blue
|
||||
10| <blank>
|
||||
11| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
12| " The user wants me to use the todo_write tool to record a plan with exactly three todos in the "
|
||||
style 1-99 fg=bright-black italic
|
||||
13| " specified statuses, then reply with \"DONE\". "
|
||||
style 1-43 fg=bright-black italic
|
||||
14| <blank>
|
||||
15| "▌ "
|
||||
style 0-0 fg=green
|
||||
16| "▌ ✓ Update todo list "
|
||||
style 0-0 fg=green
|
||||
style 2-2 fg=green bold
|
||||
style 3-19 bold
|
||||
17| "▌ Updated todo list: 2 pending, 1 in progress, 0 completed. "
|
||||
style 0-0 fg=green
|
||||
18| "▌ "
|
||||
style 0-0 fg=green
|
||||
19| <blank>
|
||||
20| " Reasoning "
|
||||
style 1-9 fg=bright-black italic
|
||||
21| " The todos have been written successfully. Now I just need to reply with the single word \"DONE\". "
|
||||
style 1-95 fg=bright-black italic
|
||||
22| <blank>
|
||||
23| " Assistant "
|
||||
style 1-9 fg=bright-magenta bold
|
||||
24| " DONE "
|
||||
25| <blank>
|
||||
4| "You "
|
||||
style 0-2 fg=bright-blue bold underline
|
||||
5| "Use the todo_write tool to record a plan with exactly three todos: \"read the code\" (in_progress), "
|
||||
6| "\"write the fix\" (pending), \"run the tests\" (pending). Send all three in one todo_write call. Then "
|
||||
7| "reply with the single word DONE and stop. "
|
||||
8| <blank>
|
||||
9| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
10| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
11| "The user wants me to use the todo_write tool to record a plan with exactly three todos in the "
|
||||
style 0-99 fg=bright-black italic
|
||||
12| "specified statuses, then reply with \"DONE\". "
|
||||
style 0-42 fg=bright-black italic
|
||||
13| <blank>
|
||||
14| "● Tool / todo_write"
|
||||
style 0-18 fg=green
|
||||
15| "Update todo list "
|
||||
16| "Updated todo list: 2 pending, 1 in progress, 0 completed. "
|
||||
17| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
18| <blank>
|
||||
19| "Assistant "
|
||||
style 0-8 fg=bright-magenta bold underline
|
||||
20| "Reasoning "
|
||||
style 0-8 fg=bright-black italic
|
||||
21| "The todos have been written successfully. Now I just need to reply with the single word \"DONE\". "
|
||||
style 0-94 fg=bright-black italic
|
||||
22| "DONE "
|
||||
23| "Model wait 0.0s · Completed 2026-07-21 12:00:00 "
|
||||
style 0-46 dim
|
||||
24-25| <blank>
|
||||
26| "Plan"
|
||||
style 0-3 fg=bright-blue bold
|
||||
27| " ● read the code"
|
||||
@@ -60,13 +51,13 @@ buffer
|
||||
style 2-2 dim
|
||||
29| " ○ run the tests"
|
||||
style 2-2 dim
|
||||
30| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
31| " "
|
||||
style 1-1 inverse
|
||||
32| "────────────────────────────────────────────────────────────────────────────────────────────────────"
|
||||
style 0-99 dim
|
||||
33| "deepseek-v4-flash /workspace/project ↑3.1k ↓145 cache 47% 3% context tools:"
|
||||
style 0-79 dim
|
||||
style 82-99 dim
|
||||
34-35| <blank>
|
||||
30| "/workspace/project deepseek-v4-flash ↑3.1k ↓145 cache 47% 3% context"
|
||||
style 0-37 fg=bright-blue bold
|
||||
style 40-56 fg=bright-black
|
||||
style 59-79 fg=bright-black
|
||||
style 82-91 fg=bright-black
|
||||
31| " dsh ◍ "
|
||||
style 1-3 fg=bright-blue bold
|
||||
style 5-6 fg=bright-black
|
||||
style 7-7 inverse
|
||||
32-35| <blank>
|
||||
|
||||
@@ -71,17 +71,37 @@ async function seedResumeSession(cwd: string): Promise<void> {
|
||||
].join('\n'))
|
||||
}
|
||||
|
||||
/** The rendered system prompt from the first `request/header` in the workspace's persisted session log. */
|
||||
async function readLoggedSystemPrompt(cwd: string): Promise<string> {
|
||||
/** Model-visible startup context from the first request in the workspace's persisted session log. */
|
||||
interface LoggedRequestContext {
|
||||
/** The system prompt string the launcher sends. */
|
||||
system: string
|
||||
/** The durable skill-catalog message serialized to text. */
|
||||
skillCatalog: string
|
||||
}
|
||||
|
||||
async function readLoggedRequestContext(cwd: string): Promise<LoggedRequestContext> {
|
||||
const sessionsDir = join(cwd, '.sessions')
|
||||
const entries = await readdir(sessionsDir, { recursive: true })
|
||||
// A single keyless run writes one session log; the source section is global, so any log carries it.
|
||||
const logRelPath = entries.find(name => name.endsWith('.jsonl'))
|
||||
if (logRelPath === undefined) throw new Error(`no session log written under ${sessionsDir}`)
|
||||
const lines = (await readFile(join(sessionsDir, logRelPath), 'utf8')).split('\n').filter(Boolean)
|
||||
let skillCatalog = ''
|
||||
for (const line of lines) {
|
||||
const event = JSON.parse(line) as { type: string; data: { header?: { system?: string } } }
|
||||
if (event.type === 'request/header') return event.data.header?.system ?? ''
|
||||
const event = JSON.parse(line) as SessionEvent
|
||||
if (
|
||||
event.type === 'user/message'
|
||||
&& event.data.source.kind === 'plugin'
|
||||
&& event.data.source.plugin === 'dsh-tool-skill'
|
||||
) {
|
||||
skillCatalog = JSON.stringify(event.data.content)
|
||||
}
|
||||
if (event.type === 'request/header') {
|
||||
return {
|
||||
system: event.data.header.system ?? '',
|
||||
skillCatalog,
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(`session log ${logRelPath} has no request/header event`)
|
||||
}
|
||||
@@ -176,6 +196,10 @@ describe('tui-agent keyless smoke (real Loader tree in a PTY)', () => {
|
||||
expect(output).toContain('KV cache')
|
||||
expect(output).toContain('Context')
|
||||
expect(output).toContain('128,000')
|
||||
expect(output).toContain('System prompt')
|
||||
expect(output).toContain('You are an AI agent powered by the DeepSeek Harness SDK.')
|
||||
expect(output).toContain('Registered tools')
|
||||
expect(output).toContain('ask_user_question')
|
||||
expect(output).toContain('\u001B[?2004l')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
@@ -208,6 +232,7 @@ describe('tui-agent keyless smoke (real Loader tree in a PTY)', () => {
|
||||
{ waitFor: 'Scripted skill body received.', send: '/exit\r' },
|
||||
],
|
||||
})
|
||||
expect(output).not.toContain('[instructions]')
|
||||
expect(output).toContain('Scripted skill body received.')
|
||||
expect(output).toContain('\u001B[?2004l')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
@@ -342,11 +367,13 @@ describe('dsh CLI keyless smoke (apps/cli through the same PTY)', () => {
|
||||
expect(output).toContain('ui-tui: session "missing-session" failed to start:')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
it('tells the model where its own source lives, in the system prompt it sends', async () => {
|
||||
it('tells the model its source path and offers the bundled maintenance skills', async () => {
|
||||
// The launcher resolves the checkout root three hops up from apps/cli/{src,lib};
|
||||
// this test file sits an equal depth under the same root, so the same hop applies.
|
||||
// The source-path line is a system-prompt section; the bundled skills reach the
|
||||
// model through a durable user message, so each assertion targets its own field.
|
||||
const sourceRoot = fileURLToPath(new URL('../../..', import.meta.url))
|
||||
let loggedSystem = ''
|
||||
let context: LoggedRequestContext = { system: '', skillCatalog: '' }
|
||||
await smoke({
|
||||
label: 'dsh source-path prompt',
|
||||
tempDirPrefix: 'dsh-source-path-',
|
||||
@@ -358,8 +385,11 @@ describe('dsh CLI keyless smoke (apps/cli through the same PTY)', () => {
|
||||
{ waitFor: 'How should the scripted run proceed?', send: '\r' },
|
||||
{ waitFor: 'Decision received. Scripted TUI run complete.', send: '/exit\r' },
|
||||
],
|
||||
inspect: async (cwd) => { loggedSystem = await readLoggedSystemPrompt(cwd) },
|
||||
inspect: async (cwd) => { context = await readLoggedRequestContext(cwd) },
|
||||
})
|
||||
expect(loggedSystem).toContain(`Your own source code is the checkout at ${sourceRoot}; you can read it there to learn how dsh works and how to extend it.`)
|
||||
expect(context.system).toContain(`Your own source code is the checkout at ${sourceRoot}; you can read it there to learn how dsh works and how to extend it.`)
|
||||
expect(context.skillCatalog).toContain("- `dsh-customize`: Customize or maintain any dsh source checkout — the one powering the current DSH process, the installed `dsh` command, or a sibling dsh/deepseek-harness clone. Use before any requested action that alters such a checkout's files or git state. Read-only questions that only inspect the checkout do not trigger this. Do not edit the personal staging checkout directly.")
|
||||
expect(context.skillCatalog).toContain('- `dsh-upgrade`: Upgrades a source-installed, personally customized DSH checkout to upstream master while preserving local changes and an unchanged rollback worktree. Use when the user asks to update or upgrade DSH.')
|
||||
expect(context.skillCatalog).toContain('- `dsh-upstream-customization`: Classifies personal DSH customizations for upstream contribution and, after explicit per-feature approval, rebuilds one on upstream master and opens a draft pull request. Use when the user asks to contribute, publish, or upstream a local DSH change, or asks whether one is worth proposing.')
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ import { cp, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/pr
|
||||
import { tmpdir } from 'node:os'
|
||||
import { basename, dirname, isAbsolute, join, relative, sep } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { afterAll, describe, expect, it } from 'vitest'
|
||||
import { afterAll, describe, expect, it, vi } from 'vitest'
|
||||
import { Context } from 'cordis'
|
||||
import { scrubRequestHeaders } from '@deepseek-ai/dsh-acp-snapshot'
|
||||
import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
@@ -26,7 +26,7 @@ import * as ToolCordis from '@deepseek-ai/dsh-tool-cordis'
|
||||
import * as ToolTodo from '@deepseek-ai/dsh-tool-todo'
|
||||
import * as ToolRalph from '@deepseek-ai/dsh-tool-ralph'
|
||||
import * as ToolWorkflow from '@deepseek-ai/dsh-tool-workflow'
|
||||
import { createTuiChat, FILE_REFERENCE_PROMPT } from '@deepseek-ai/dsh-tui'
|
||||
import { createTuiChat, FILE_REFERENCE_PROMPT, TuiPromptService } from '@deepseek-ai/dsh-tui'
|
||||
import LocalSpillStore from '@deepseek-ai/dsh-spill-local'
|
||||
import * as SpillPolicy from '@deepseek-ai/dsh-spill-policy'
|
||||
import UserInteractionService from '@deepseek-ai/dsh-user-interaction'
|
||||
@@ -227,6 +227,7 @@ async function mountScenarioContext(
|
||||
await ctx.plugin(FsPolicy)
|
||||
await ctx.plugin(ToolFs)
|
||||
await ctx.plugin(UserInteractionService)
|
||||
await ctx.plugin(TuiPromptService)
|
||||
// todo_write is opt-in: only the todo-plan scenario mounts it, matching the shipped
|
||||
// config that omits it. The other scenarios prove the default todo-free composition.
|
||||
if (scenario.enableTodo === true) await ctx.plugin(ToolTodo)
|
||||
@@ -264,6 +265,7 @@ interface ScenarioResult {
|
||||
}
|
||||
|
||||
async function runScenario(scenario: Scenario): Promise<ScenarioResult> {
|
||||
const clock = vi.spyOn(Date, 'now').mockReturnValue(new Date(2026, 6, 21, 12, 0, 0).getTime())
|
||||
const dir = scenarioDir(scenario)
|
||||
const fixtureFile = join(dir, 'session.jsonl')
|
||||
const childFiles = childFixturePaths(scenario)
|
||||
@@ -296,7 +298,7 @@ async function runScenario(scenario: Scenario): Promise<ScenarioResult> {
|
||||
const agent: Agent = handle.agent
|
||||
controller = createTuiChat(ctx, {
|
||||
sessionId: 'main-session',
|
||||
color: true,
|
||||
theme: { color: true },
|
||||
showReasoning: true,
|
||||
title: 'DSH TUI snapshot',
|
||||
welcome: `Recorded replay: ${scenario.name}`,
|
||||
@@ -406,6 +408,7 @@ async function runScenario(scenario: Scenario): Promise<ScenarioResult> {
|
||||
await ctx?.fiber.dispose()
|
||||
await terminal.dispose()
|
||||
await rm(cwd, { recursive: true, force: true })
|
||||
clock.mockRestore()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
examples/web-cordis/.gitignore
vendored
Normal file
2
examples/web-cordis/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.sessions/
|
||||
.storages/
|
||||
18
examples/web-cordis/cordis.yml
Normal file
18
examples/web-cordis/cordis.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Opt-in Web composition for inspecting the self-referential Cordis tools.
|
||||
# Temporary Plugin code can reach every injected live capability; treat this
|
||||
# deployment like shell access, not as a security boundary.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ../../apps/cli/cordis.yml
|
||||
patches:
|
||||
# AppCLIEntry normally injects this assembly-owned path before `dsh web`
|
||||
# boots; the standalone Cordis launcher needs the equivalent patch here.
|
||||
- id: webserver
|
||||
config:
|
||||
host: 127.0.0.1
|
||||
port: 3081
|
||||
distIndex: !!js "new URL('./apps/web/dist/index.html', 'file://' + process.cwd() + '/').pathname"
|
||||
- insert:
|
||||
- id: tool-cordis
|
||||
name: '@deepseek-ai/dsh-tool-cordis'
|
||||
Reference in New Issue
Block a user