fix(llm): scope adapter failures to model calls

Replace the process-wide adapter-failure WeakSet with a per-call scope bound to the exact AsyncIterable returned by LlmService.stream(). Give every call a unique wrapper so waterfall middleware can reuse an iterable without sharing provenance.

Move agent-loop recovery classification to the model-stream boundary. Only the final adapter behind that exact call can become an agent/request-error; nested llm/stream calls remain ordinary outer middleware failures while preserving the original Error.

Cover nested calls, reused middleware iterables, and end-to-end agent-loop recovery. Update the package and RFC contracts, bilingual pairing record, and generated API and catalog references.
This commit is contained in:
Tianyi Cui
2026-07-19 16:14:58 +08:00
parent bf93605f8c
commit ee6b9d081a
14 changed files with 233 additions and 56 deletions
+1 -1
View File
@@ -342,7 +342,7 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t
- `options` — the full request. A LOOP-built request arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability RFC), so listeners read it, never rewrite it. A hand-built one-shot (compaction summarize) is the caller's own object and stays mutable here.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L42)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L43)
## session/*