review: one fold implementation, uniform end-edge absence, partial text in tool errors, snapshot scenario

Address ds-review-bot on #2127:

- assistant-output: the rule has ONE implementation, the incremental
  AssistantOutputFold (push/pushText/collect); finalAssistantOutput folds a
  complete suffix, the SDK backend folds notification events, and the ACP
  backend folds raw chunk text into the same streamed fallback.
- subagent/end.lastAssistantMessage: 'no output' is encoded once — absent,
  never [], on both lifecycle shapes (observeRun now omits empty output).
- tool-subagent: a non-completed foreground result stays isError but appends
  the child's preserved partial text after the stop-reason headline.
- Authored keyless snapshot scenario subagent-max-tokens-partial pins the
  assembled transcript: the child's committed log carries the usage-only
  empty message and the parent's tool result carries the partial answer.
- Rule-boundary sentence (message wins over later streamed text) and the
  consumer half recorded in the Agent Note; comments trimmed to pointers.
This commit is contained in:
Hypatia May
2026-08-10 16:09:04 +08:00
parent 2418f44781
commit ea47c32805
24 changed files with 221 additions and 96 deletions

View File

@@ -154,6 +154,9 @@ describe('dsh-tool-subagent', () => {
const result = await callSubagent(ctx, { description: 'd', prompt: 'p' })
expect(result.isError).toBe(true)
expect(text(result)).toContain(fragment)
// The failure is not partial success, but the child's preserved partial
// answer still reaches the parent model inside the error result.
expect(text(result)).toContain('scripted subagent reply')
})
it('registers under a configurable toolName so multiple providers can coexist', async () => {