feat(subagent): deliver continuable child settlement to parents
A continuable child that stopped without reporting — an error, a token ceiling, cancellation, teardown — left its parent nothing to act on. The continuation manager now delivers an unconditional settlement notice to the durable direct parent before releasing ownership, folding consumed work (foldConsumedWork supersedes findLastMessageTurnEnd) so a claimed-but-unrun prompt reads as aborted rather than completed, waking an idle parent, steering a busy one, and never waking a closing tree.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# Keyless assembled-app coverage for continuable child settlement delivery. The
|
||||
# replay child deliberately never calls report; the parent can reach its final
|
||||
# answer only if the continuation manager places the child's closing message in
|
||||
# the parent turn without list_agents, send_message, or a Task collector.
|
||||
|
||||
- id: base
|
||||
name: '@deepseek-ai/cordis-plugin-include'
|
||||
config:
|
||||
path: ./cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- insert:
|
||||
- id: llm-replay
|
||||
name: '@deepseek-ai/dsh-llm-replay'
|
||||
|
||||
# Prevent platform scheduling from choosing a streamed-chunk interleave. The
|
||||
# fence releases only after the real manager notice enters the parent inbox.
|
||||
- id: settlement-fence
|
||||
name: './tests/fixtures/subagent-settlement-fence.ts'
|
||||
43
examples/headless-agent/tests/fixtures/subagent-settlement-fence.ts
vendored
Normal file
43
examples/headless-agent/tests/fixtures/subagent-settlement-fence.ts
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Loader fixture that holds the parent's second step until settlement delivery.
|
||||
* @module subagent-settlement-fence
|
||||
*/
|
||||
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-agent-loop'
|
||||
import type {} from '@deepseek-ai/dsh-subagent'
|
||||
|
||||
/** Fixture plugin name. */
|
||||
export const name = 'subagent-settlement-fence'
|
||||
|
||||
/**
|
||||
* Fence the parent's post-spawn request behind admission of the manager notice.
|
||||
*
|
||||
* This pins content order, not step placement: the held pre-step runs after its
|
||||
* own `Inbox.claim()`, so the notice lands after step 2's claim and is claimed at
|
||||
* step 3 because the child's settlement pipeline is strictly longer than the
|
||||
* parent's claim path, not because a barrier forces it.
|
||||
* @param ctx - assembled headless-agent context.
|
||||
*/
|
||||
export function apply(ctx: Context): void {
|
||||
const delivered = Promise.withResolvers<undefined>()
|
||||
let hasDelivered = false
|
||||
|
||||
ctx.effect(() => {
|
||||
const disposeInbox = ctx.root.on('agent/inbox/inserted', ({ agent, message }) => {
|
||||
if (agent.session.header.parentSession !== undefined || message.source.kind !== 'subagent-settled') return
|
||||
hasDelivered = true
|
||||
delivered.resolve(undefined)
|
||||
})
|
||||
const disposeStep = ctx.root.on('agent/pre-step', async ({ agent, turn, step }, next) => {
|
||||
if (agent.session.header.parentSession === undefined && turn === 1 && step === 2 && !hasDelivered) {
|
||||
await delivered.promise
|
||||
}
|
||||
return next()
|
||||
})
|
||||
return () => {
|
||||
disposeStep()
|
||||
disposeInbox()
|
||||
}
|
||||
}, 'subagent-settlement-fence.listeners')
|
||||
}
|
||||
@@ -45,6 +45,8 @@ const credentialsConfigPath = fileURLToPath(new URL('../credentials.cordis.snaps
|
||||
const invalidCredentialScenarioDir = join(snapshotsDir, 'invalid-credential')
|
||||
const ralphScenarioDir = join(snapshotsDir, 'ralph-loop')
|
||||
const ralphConfigPath = fileURLToPath(new URL('../ralph.cordis.snapshot.yml', import.meta.url))
|
||||
const settlementScenarioDir = join(snapshotsDir, 'subagent-settlement')
|
||||
const settlementConfigPath = fileURLToPath(new URL('../subagent-settlement.cordis.snapshot.yml', import.meta.url))
|
||||
const startupFailureConfigPath = fileURLToPath(new URL('./fixtures/startup-activation-error/cordis.yml', import.meta.url))
|
||||
const startupFailureExpected = join(snapshotsDir, 'startup-activation-error', 'stderr.expected.txt')
|
||||
const binScript = fileURLToPath(new URL('./fixtures/headless-driver.ts', import.meta.url))
|
||||
@@ -777,6 +779,77 @@ describe('headless stream-json snapshots', () => {
|
||||
expect(normalized).toBe(await readFile(streamExpected, 'utf8'))
|
||||
}, LOADER_SMOKE_TEST_TIMEOUT_MS)
|
||||
|
||||
it('delivers a continuable child result without parent polling', async () => {
|
||||
const parentReplay = join(settlementScenarioDir, 'parent.replay.jsonl')
|
||||
const parentOverride = join(settlementScenarioDir, 'parent.override.json')
|
||||
const childReplay = join(settlementScenarioDir, 'child.replay.jsonl')
|
||||
const childExpected = join(settlementScenarioDir, 'child.expected.jsonl')
|
||||
const streamExpected = join(settlementScenarioDir, 'stream-json.expected.jsonl')
|
||||
const task = 'Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, task_output, or task_list.'
|
||||
let runCwd = ''
|
||||
const result = await runLoaderSmoke({
|
||||
label: 'continuable settlement headless stream-json snapshot',
|
||||
tempDirPrefix: 'headless-snapshot-subagent-settlement-',
|
||||
binScript,
|
||||
libBinScript: binScript,
|
||||
configPath: settlementConfigPath,
|
||||
binArgs: [settlementConfigPath, task],
|
||||
tsconfigPath,
|
||||
env: {
|
||||
// The override fully supplies the parent script; the child fixture
|
||||
// remains separate so replay binds it to the fresh child Session.
|
||||
DSH_SNAPSHOT_FILE: parentReplay,
|
||||
DSH_SNAPSHOT_OVERRIDE: parentOverride,
|
||||
DSH_SNAPSHOT_CHILD_FILES: childReplay,
|
||||
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(2)
|
||||
const parent = logs.find(log => typeof log.header.parentSession !== 'string')
|
||||
const child = logs.find(log => typeof log.header.parentSession === 'string')
|
||||
if (parent === undefined || child === undefined) throw new Error('missing persisted parent or child log')
|
||||
|
||||
const parentRecords = parseJsonl(parent.content)
|
||||
const calls = parentRecords.filter(record => record.type === 'tool/call')
|
||||
expect(calls.map(record => (record.data as JsonObject | undefined)?.name)).toEqual(['subagent'])
|
||||
const callArguments = (calls[0]?.data as JsonObject | undefined)?.arguments
|
||||
if (typeof callArguments !== 'string') throw new Error('subagent call did not persist its arguments')
|
||||
expect(JSON.parse(callArguments)).toMatchObject({ run_in_background: true })
|
||||
|
||||
const notices = parentRecords.flatMap((record) => {
|
||||
if (record.type !== 'agent/inbox/spliced') return []
|
||||
const inserted = (record.data as JsonObject | undefined)?.inserted
|
||||
if (!Array.isArray(inserted)) return []
|
||||
return (inserted as JsonObject[]).filter((message) => {
|
||||
const source = message.source as JsonObject | undefined
|
||||
return source?.kind === 'subagent-settled'
|
||||
})
|
||||
})
|
||||
expect(notices).toHaveLength(1)
|
||||
expect(JSON.stringify(notices[0])).toContain('CHILD_RESULT')
|
||||
|
||||
const context = contextFromLogs([parent.content, child.content])
|
||||
const normalizedChild = scrubRequestHeaders(normalizeSessionLog(child.content, context))
|
||||
if (refreshing) await writeFile(childExpected, normalizedChild)
|
||||
expect(normalizedChild).toBe(await readFile(childExpected, 'utf8'))
|
||||
expect(normalizedChild).toContain('CHILD_RESULT')
|
||||
expect(normalizedChild).not.toContain('"name":"report"')
|
||||
},
|
||||
})
|
||||
|
||||
expect(result.stderr).toBe('')
|
||||
const records = parseJsonl(result.stdout)
|
||||
expect(records.at(-1)).toMatchObject({
|
||||
type: 'result',
|
||||
output: 'PARENT_RECEIVED_CHILD_RESULT',
|
||||
})
|
||||
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('replays persistent PTY tools through the one-shot app', async () => {
|
||||
const input = JSON.parse(await readFile(join(ptyScenarioDir, 'input.json'), 'utf8')) as {
|
||||
steps?: { op?: unknown; text?: unknown }[]
|
||||
|
||||
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,20 @@
|
||||
{"type":"session","version":0,"id":"{{sessionId}}","createdAt":0,"cwd":"{{cwd}}","parentSession":"{{sessionId}}","origin":"subagent","delegationDepth":1}
|
||||
{"type":"subagent/descriptor","seq":0,"time":0,"data":{"version":2,"mode":"continuable","provider":"spawn","label":"Return child result","agentProvider":"deepseek-official","agentModel":"deepseek-v4-flash"}}
|
||||
{"type":"session/end-seed","seq":1,"time":0,"data":{}}
|
||||
{"type":"agent/inbox/spliced","seq":2,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Reply with exactly CHILD_RESULT and nothing else. Do not call report."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"}]}}
|
||||
{"type":"turn/start","seq":3,"time":0,"data":{"turn":1}}
|
||||
{"type":"agent/inbox/spliced","seq":4,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
|
||||
{"type":"step/start","seq":5,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"user/message","seq":6,"time":0,"data":{"content":[{"type":"text","text":"Reply with exactly CHILD_RESULT and nothing else. Do not call report."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":7,"time":0,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":8,"time":0,"data":{"title":"Reply with exactly CHILD_RESULT and","messageSeqs":[6],"source":{"kind":"fallback"}}}
|
||||
{"type":"request/header","seq":9,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"request/context","seq":10,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
|
||||
{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_RESULT"}}}
|
||||
{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_RESULT"}}}}
|
||||
{"type":"assistant/chunk","seq":14,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":16,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_RESULT"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[11,12,13,14,15],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":17,"time":0,"data":{"turn":1,"step":1}}
|
||||
{"type":"turn/end","seq":18,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,6 @@
|
||||
{"type":"session","version":0,"id":"subagent-settlement-child","createdAt":2,"delegationDepth":1}
|
||||
{"type":"assistant/chunk","seq":0,"time":1,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":1,"time":2,"data":{"turn":1,"step":1,"chunk":{"type":"text-delta","index":0,"text":"CHILD_RESULT"}}}
|
||||
{"type":"assistant/chunk","seq":2,"time":3,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_RESULT"}}}}
|
||||
{"type":"assistant/chunk","seq":3,"time":4,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
|
||||
{"type":"assistant/chunk","seq":4,"time":5,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"kind": "chunks",
|
||||
"chunks": [
|
||||
{ "type": "block-start", "index": 0, "blockType": "tool-call" },
|
||||
{ "type": "tool-call-delta", "index": 0, "id": "start-child", "name": "subagent", "argumentsDelta": "{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}" },
|
||||
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "start-child", "name": "subagent", "arguments": "{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}" } },
|
||||
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
|
||||
{ "type": "finish", "reason": { "kind": "tool-calls" } }
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "chunks",
|
||||
"chunks": [
|
||||
{ "type": "block-start", "index": 0, "blockType": "text" },
|
||||
{ "type": "text-delta", "index": 0, "text": "STARTED" },
|
||||
{ "type": "block-end", "index": 0, "block": { "type": "text", "text": "STARTED" } },
|
||||
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
|
||||
{ "type": "finish", "reason": { "kind": "stop" } }
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "chunks",
|
||||
"chunks": [
|
||||
{ "type": "block-start", "index": 0, "blockType": "text" },
|
||||
{ "type": "text-delta", "index": 0, "text": "PARENT_RECEIVED_CHILD_RESULT" },
|
||||
{ "type": "block-end", "index": 0, "block": { "type": "text", "text": "PARENT_RECEIVED_CHILD_RESULT" } },
|
||||
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
|
||||
{ "type": "finish", "reason": { "kind": "stop" } }
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
{"type":"session","version":0,"id":"subagent-settlement-parent","createdAt":1,"delegationDepth":0}
|
||||
@@ -0,0 +1,38 @@
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":0,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, task_output, or task_list."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"}]}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/start","seq":1,"time":0,"data":{"turn":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":2,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}}
|
||||
{"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":"user/message","seq":4,"time":0,"data":{"content":[{"type":"text","text":"Start one continuable background subagent and answer from its completion notice. Do not call list_agents, send_message, task_output, or task_list."}],"source":{"kind":"user"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"session/title","seq":5,"time":0,"data":{"title":"Start one continuable background subagen","messageSeqs":[4],"source":{"kind":"fallback"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/header","seq":6,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"request/context","seq":7,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":8,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"start-child","name":"subagent","argumentsDelta":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":13,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[8,9,10,11,12],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/call","seq":14,"time":0,"data":{"turn":1,"step":1,"callId":"start-child","name":"subagent","arguments":"{\"description\":\"Return child result\",\"prompt\":\"Reply with exactly CHILD_RESULT and nothing else. Do not call report.\",\"run_in_background\":true}"}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"tool/result","seq":15,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"start-child"},"content":[{"type":"tool-result","toolCallId":"start-child","content":[{"type":"text","text":"started subagent {{sessionId}}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[14],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":16,"time":0,"data":{"turn":1,"step":1}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"agent/inbox/spliced","seq":17,"time":0,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Background subagent {{sessionId}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_RESULT"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{sessionId}} finished and will do no further work unless you send it more.","senderSessionId":"{{sessionId}}"},"role":"user","id":"{{sessionId}}"}]}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":18,"time":0,"data":{"turn":1,"step":2}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":19,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"STARTED"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":21,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"STARTED"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":22,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":23,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":24,"time":0,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"STARTED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[19,20,21,22,23],"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":"agent/inbox/spliced","seq":26,"time":0,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[]}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/start","seq":27,"time":0,"data":{"turn":1,"step":3}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"user/message","seq":28,"time":0,"data":{"content":[{"type":"text","text":"Background subagent {{sessionId}} finished and will do no further work unless you send it more."},{"type":"text","text":"Its closing message:"},{"type":"text","text":"CHILD_RESULT"}],"source":{"kind":"subagent-settled","form":"notice","summary":"Background subagent {{sessionId}} finished and will do no further work unless you send it more.","senderSessionId":"{{sessionId}}"},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":29,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"text-delta","index":0,"text":"PARENT_RECEIVED_CHILD_RESULT"}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":31,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"PARENT_RECEIVED_CHILD_RESULT"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":32,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/chunk","seq":33,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"assistant/message","seq":34,"time":0,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"text","text":"PARENT_RECEIVED_CHILD_RESULT"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[29,30,31,32,33],"surfaceOp":"append"}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"step/end","seq":35,"time":0,"data":{"turn":1,"step":3}}}
|
||||
{"type":"session_event","sessionId":"{{sessionId}}","event":{"type":"turn/end","seq":36,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}}
|
||||
{"type":"result","sessionId":"{{sessionId}}","output":"PARENT_RECEIVED_CHILD_RESULT","usage":{"inputTokens":30,"outputTokens":15}}
|
||||
Reference in New Issue
Block a user