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.
36 lines
5.1 KiB
JSON
36 lines
5.1 KiB
JSON
{"type":"session","version":0,"id":"4d76c4bd-1fca-418f-b2fe-b938d7398666","createdAt":1782087699201,"cwd":"/tmp/acp-snap-cwd-s06Syv","parentSession":"9b045576-92f1-48ca-b854-9ba160449992"}
|
|
{"type":"turn/start","seq":0,"time":1782087699202,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
|
{"type":"user/message","seq":1,"time":1782087699202,"data":{"content":[{"type":"text","text":"Reply with exactly the word CHILD_OK and nothing else."}],"source":{"kind":"user"}}}
|
|
{"type":"step/start","seq":2,"time":1782087699202,"data":{"turn":1,"step":1}}
|
|
{"type":"assistant/chunk","seq":3,"time":1782087699839,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
|
{"type":"assistant/chunk","seq":4,"time":1782087699839,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"The"}}}
|
|
{"type":"assistant/chunk","seq":5,"time":1782087699947,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" user"}}}
|
|
{"type":"assistant/chunk","seq":6,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" wants"}}}
|
|
{"type":"assistant/chunk","seq":7,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" me"}}}
|
|
{"type":"assistant/chunk","seq":8,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" to"}}}
|
|
{"type":"assistant/chunk","seq":9,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" reply"}}}
|
|
{"type":"assistant/chunk","seq":10,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" with"}}}
|
|
{"type":"assistant/chunk","seq":11,"time":1782087699977,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" exactly"}}}
|
|
{"type":"assistant/chunk","seq":12,"time":1782087700016,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" the"}}}
|
|
{"type":"assistant/chunk","seq":13,"time":1782087700016,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" word"}}}
|
|
{"type":"assistant/chunk","seq":14,"time":1782087700017,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" \""}}}
|
|
{"type":"assistant/chunk","seq":15,"time":1782087700017,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"CH"}}}
|
|
{"type":"assistant/chunk","seq":16,"time":1782087700034,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"ILD"}}}
|
|
{"type":"assistant/chunk","seq":17,"time":1782087700035,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"_OK"}}}
|
|
{"type":"assistant/chunk","seq":18,"time":1782087700035,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"\""}}}
|
|
{"type":"assistant/chunk","seq":19,"time":1782087700035,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" and"}}}
|
|
{"type":"assistant/chunk","seq":20,"time":1782087700035,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" nothing"}}}
|
|
{"type":"assistant/chunk","seq":21,"time":1782087700035,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":" else"}}}
|
|
{"type":"assistant/chunk","seq":22,"time":1782087700064,"data":{"turn":1,"step":1,"chunk":{"type":"reasoning-delta","index":0,"text":"."}}}
|
|
{"type":"assistant/chunk","seq":23,"time":1782087700064,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
|
|
{"type":"assistant/chunk","seq":24,"time":1782087700064,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"CH"}}}
|
|
{"type":"assistant/chunk","seq":25,"time":1782087700064,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"ILD"}}}
|
|
{"type":"assistant/chunk","seq":26,"time":1782087700107,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":1,"text":"_OK"}}}
|
|
{"type":"assistant/chunk","seq":27,"time":1782087700108,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to reply with exactly the word \"CHILD_OK\" and nothing else."}}}}
|
|
{"type":"assistant/chunk","seq":28,"time":1782087700108,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"text","text":"CHILD_OK"}}}}
|
|
{"type":"assistant/chunk","seq":29,"time":1782087700108,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":964,"outputTokens":23,"cacheReadTokens":0,"reasoningTokens":19}}}}
|
|
{"type":"assistant/chunk","seq":30,"time":1782087700108,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
|
{"type":"assistant/message","seq":31,"time":1782087700108,"data":{"turn":1,"step":1,"content":[{"type":"reasoning","text":"The user wants me to reply with exactly the word \"CHILD_OK\" and nothing else."},{"type":"text","text":"CHILD_OK"}],"usage":{"inputTokens":964,"outputTokens":23,"cacheReadTokens":0,"reasoningTokens":19}}}
|
|
{"type":"step/end","seq":32,"time":1782087700108,"data":{"turn":1,"step":1}}
|
|
{"type":"turn/end","seq":33,"time":1782087700108,"data":{"turn":1,"reason":{"kind":"completed"}}}
|