fix(agent-loop): admit prompts under the prepared route

Resolve agent/request and prepareCall inside the accepted open step before committing system and user input. Preserve prompt-assembly model selection, bind capability and dispatch to the same prepared adapter, then log the envelope and derive the request synchronously. Preparation cancellation leaves a balanced empty step with no admitted input.

Normalize incapable-route retained prompt versions with logged per-node empty replacements and a current head, including unchanged rendering and resumed history. Dormant empty tails do not override the effective prompt. No new event or delete operation.

Tests: 389 agent-loop cases pass with exact agent.ts/runtime-context.ts coverage at 100% for all metrics; tsc -b packages/core/agent-loop/tsconfig.json passes. Seven actual-loop MockAdapter cases exercise pi-ai conversion, source-event reconstruction, both route transitions, resume, cancellation barriers, and bound selection. Stale-capability negative control fails all three transition regressions. Update EN/ZH request visibility, lifecycle generator, and owning rationale. Broad catalogs, recorded SDK/GUI and aggregate gates remain parent-owned.
This commit is contained in:
Tianyi Cui
2026-09-07 11:09:39 +08:00
parent c988a6796f
commit 2ce9738564
41 changed files with 389 additions and 193 deletions
+9 -4
View File
@@ -1327,14 +1327,19 @@ function renderLifecycle(): string {
` Driver->>Prompt: ${mermaidCode('system-prompt/assemble')} waterfall`,
` Driver->>Hooks: ${mermaidCode('agent/pre-step')} waterfall`,
' Hooks-->>Driver: authoritative reject or enter(messages)',
' alt proposed step rejected or pre-step failed',
' alt proposed step rejected, first batch empty, or pre-step failed',
' Driver-->>Driver: claimed batch stays removed, the open turn spends no step',
' else enter proposed step',
' Note over Driver,Prompt: project the rendered prompt against the surviving system/message nodes',
` Driver->>Session: ${mermaidCode('step/start')}`,
` Driver->>Session: ${mermaidCode('system/message')} when the rendered prompt changed: replace the latest system node, or append on an in-history route`,
` Driver->>Hooks: ${mermaidCode('agent/request')} waterfall`,
' Driver->>LLM: prepareCall(config, signal)',
' Note over Driver,LLM: cancellation during either async phase commits neither system nor users',
' Note over Driver,Session: synchronous admission using the prepared call capability',
` Driver->>Session: ${mermaidCode('system/message')} ordered per-node reconciliation`,
` Driver->>Session: ${mermaidCode('user/message')} per entered message`,
` Driver->>LLM: ${mermaidCode('agent/request')} waterfall, then ${mermaidCode('llm/stream')} waterfall`,
` Driver->>Session: ${mermaidCode('request/header')} and ${mermaidCode('request/context')} as needed`,
' Driver->>Driver: derive and freeze request from the log',
` Driver->>LLM: bound prepared call through ${mermaidCode('llm/stream')} waterfall`,
' LLM-->>Driver: StreamChunk*',
` Driver-->>SDK: ${mermaidCode('agent/assistant-stream')} chunk*`,
' alt final adapter or terminal in-band request failure',