왜 adapter?
Local이랑 cloud 모델을 app 다시 짜지 않고 swap하고 싶어. 패턴: 모든 provider가 구현하는 narrow interface 정의, 모든 provider가 emit하는 universal chunk type 하나. Route, store, frontend는 interface랑 얘기; provider 전용 코드는 그 뒤에 있어.
최소 인터페이스
stream(messages, tools, **opts)— 의미 있는 유일한 method. Universal chunk sequence yield.health_check()— Fallback 라우팅용 빠른 yes/no.list_models()— UI랑 discovery용.
Universal chunk
StreamChunk 한 모양이 yield 필요한 거 다 커버: 텍스트 delta, thinking delta, tool call, timing 가진 final done flag. 각 adapter가 자기 provider의 wire 모양을 universal chunk로 번역.
너무 abstract하지 마
Adapter는 의도적으로 narrow. Route는 NDJSON vs SSE 모름, stream()만 알아. Adapter는 FastAPI route 모름, NDJSON vs SSE만 알아. 한 가지가 경계에 있고 그게 chunk yield 프로토콜이야.