mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The snapshot tier was built single-session: dsh-llm-replay served calls from one global positional cursor, and the harness harvested one session log. A subagent runs as a second agent with its own session, so a parent→child scenario could neither replay deterministically nor harvest the child's log. This resolves the TODO(subagent-snapshots) deferral from the subagent RFC. - Stamp the calling session id onto the model request: GenerateOptions.sessionId (typed Branded<'SessionId'> to avoid the dsh-llm↔dsh-session cycle), set by the agent loop from agent.session.id. Adapters ignore it; an llm/stream listener routes by it. - Key replay per session: dsh-llm-replay loads the parent log plus one per child (childFiles / $DSH_SNAPSHOT_CHILD_FILES), derives a script per recorded session, and binds each live (freshly-random) session to a recorded script by first-call order — parent first (earliest createdAt, first to stream). Keys by WHO calls, so it survives a future concurrent/backgrounded subagent; a global cursor would not. An unrecorded extra session fails loud. - Harvest every log: the harness collects all .jsonl across cwd buckets, ordered primary-first (top-level, then children by createdAt), and RunResult exposes the plural sessionLogs. The spec writes each back on record (session.jsonl + session.<n>.jsonl) and diffs each against its fixture on replay. - Wire the subagent seam + spawn + fork + tool into the acp-agent example (both cordis configs) and add two nested scenarios recorded against the real API: subagent-spawn (parent + 1 child) and subagent-multi (parent + 2 children, 3 sessions). Both replay keyless in the default gate. A new RFC documents the design (docs/rfc/implemented/testing/). Single-session replay is unchanged (a call with no sessionId is one anonymous primary session). TODO follow-up: a dedicated branded-ids package could own the SessionId brand and dissolve the cross-package cycle note; out of scope for this testing PR.
34 lines
4.8 KiB
JSON
34 lines
4.8 KiB
JSON
{"type":"session","version":0,"id":"52bb4e53-1cf4-4680-b954-4ad941a9e986","createdAt":1782087752261,"cwd":"/tmp/acp-snap-cwd-v6PaeC","parentSession":"2a50c62e-1d77-4b0e-bfab-3a9285e3aa32"}
|
|
{"type":"turn/start","seq":0,"time":1782087752262,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
|
{"type":"user/message","seq":1,"time":1782087752262,"data":{"content":[{"type":"text","text":"Reply with exactly the word BETA and nothing else."}],"source":{"kind":"user"}}}
|
|
{"type":"step/start","seq":2,"time":1782087752262,"data":{"turn":1,"step":1}}
|
|
{"type":"assistant/chunk","seq":3,"time":1782087752714,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
|
{"type":"assistant/chunk","seq":4,"time":1782087752714,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}
|
|
{"type":"assistant/chunk","seq":5,"time":1782087752857,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}
|
|
{"type":"assistant/chunk","seq":6,"time":1782087752875,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" asked"}}}
|
|
{"type":"assistant/chunk","seq":7,"time":1782087752909,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}
|
|
{"type":"assistant/chunk","seq":8,"time":1782087752909,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}
|
|
{"type":"assistant/chunk","seq":9,"time":1782087752910,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}
|
|
{"type":"assistant/chunk","seq":10,"time":1782087752910,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}
|
|
{"type":"assistant/chunk","seq":11,"time":1782087752910,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}
|
|
{"type":"assistant/chunk","seq":12,"time":1782087752941,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}
|
|
{"type":"assistant/chunk","seq":13,"time":1782087752941,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" word"}}}
|
|
{"type":"assistant/chunk","seq":14,"time":1782087752942,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}
|
|
{"type":"assistant/chunk","seq":15,"time":1782087752942,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"B"}}}
|
|
{"type":"assistant/chunk","seq":16,"time":1782087752942,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"ETA"}}}
|
|
{"type":"assistant/chunk","seq":17,"time":1782087752942,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"\""}}}
|
|
{"type":"assistant/chunk","seq":18,"time":1782087752974,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" and"}}}
|
|
{"type":"assistant/chunk","seq":19,"time":1782087752975,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" nothing"}}}
|
|
{"type":"assistant/chunk","seq":20,"time":1782087752975,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" else"}}}
|
|
{"type":"assistant/chunk","seq":21,"time":1782087752975,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}
|
|
{"type":"assistant/chunk","seq":22,"time":1782087753004,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
|
{"type":"assistant/chunk","seq":23,"time":1782087753004,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"B"}}}
|
|
{"type":"assistant/chunk","seq":24,"time":1782087753004,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"ETA"}}}
|
|
{"type":"assistant/chunk","seq":25,"time":1782087753004,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user asked me to reply with exactly the word \"BETA\" and nothing else."}}}}
|
|
{"type":"assistant/chunk","seq":26,"time":1782087753004,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"BETA"}}}}
|
|
{"type":"assistant/chunk","seq":27,"time":1782087753005,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":67,"outputTokens":21,"cacheReadTokens":896,"reasoningTokens":18}}}}
|
|
{"type":"assistant/chunk","seq":28,"time":1782087753005,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
|
{"type":"assistant/message","seq":29,"time":1782087753005,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user asked me to reply with exactly the word \"BETA\" and nothing else."},{"type":"text","text":"BETA"}],"usage":{"inputTokens":67,"outputTokens":21,"cacheReadTokens":896,"reasoningTokens":18}}}
|
|
{"type":"step/end","seq":30,"time":1782087753005,"data":{"turn":1,"step":1}}
|
|
{"type":"turn/end","seq":31,"time":1782087753005,"data":{"turn":1,"reason":{"kind":"completed"}}}
|