Extract shared streaming loop into a provider-agnostic driver
The Claude, OpenAI, and Gemini adapters each re-implemented the same
agentic streaming loop (iterate to maxIterations, stream a turn,
accumulate fullText, run tools, feed results back). That triplication
let the loop logic drift between providers.
Introduce backend/src/lib/llm/driver.ts owning the loop, break
conditions, the runTools call, and the single fullText accumulation.
Each provider becomes a thin session factory (create{Claude,OpenAI,
Gemini}Session) that owns its SDK call, event parsing, follow-up
message state, and all callback firing. Public stream* signatures are
unchanged, so callers stay untouched.
Behavior is preserved: per-provider callback ordering, the OpenAI
pre-tool preamble drop, Claude's stop_reason hard-stop, Gemini's
verbatim thoughtSignature replay, and OpenAI instructions-on-iter-0.
Chat history persistence (route-level, fed by callbacks + fullText) is
unaffected. Typecheck passes.
| Repository | mwcyu/Mike-fork |
|---|---|
| Author | Claude <noreply@anthropic.com> |
| Authored | |
| Parents | e688ccbc |
| Stats | 4 files changed , +172 , -50 |
| Part of | LLM streaming-loop refactor (SDK migration + provider-agnostic driver) |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-9dfb6fd5.md
from inside the repo you want the change in.