엔진 게이트웨이 계약 고정
This commit is contained in:
parent
ebef20560e
commit
f0771db919
8 changed files with 1123 additions and 72 deletions
|
|
@ -24,6 +24,8 @@ from .config import settings
|
|||
from .contracts.engine_gateway import (
|
||||
AIRole,
|
||||
EngineMessage,
|
||||
EngineGatewaySseLineDecoder,
|
||||
EngineGatewaySsePacket,
|
||||
GenerateRequest,
|
||||
GenerateResponse,
|
||||
StreamRequest,
|
||||
|
|
@ -147,9 +149,8 @@ class EngineClient:
|
|||
async def stream(self, req: StreamRequest) -> AsyncIterator[str]:
|
||||
"""SSE 토큰 스트림 프록시.
|
||||
|
||||
게이트웨이 SSE(`text/event-stream`) 의 data: 청크를 그대로 yield.
|
||||
라우트(sessions.py)가 이걸 받아 자체 SSE 이벤트(heartbeat 포함)로 재방출.
|
||||
TODO: 게이트웨이 이벤트 프레이밍 확정(토큰/usage/done 이벤트 구분).
|
||||
게이트웨이 SSE(`text/event-stream`) 의 원시 non-empty line을 yield한다.
|
||||
새 호출부는 raw line 대신 `stream_packets()`를 사용한다.
|
||||
"""
|
||||
try:
|
||||
async with self.client.stream(
|
||||
|
|
@ -164,6 +165,19 @@ class EngineClient:
|
|||
except httpx.HTTPError as e:
|
||||
raise EngineError(f"engine stream transport error: {e}") from e
|
||||
|
||||
async def stream_packets(self, req: StreamRequest) -> AsyncIterator[EngineGatewaySsePacket]:
|
||||
"""Decode gateway SSE into the shared token/done/error contract.
|
||||
|
||||
Keep wire-format parsing at the gateway client boundary so app services
|
||||
do not depend on raw SSE line structure. A future Node.js gateway should
|
||||
only need to preserve `app.contracts.engine_gateway`.
|
||||
"""
|
||||
decoder = EngineGatewaySseLineDecoder()
|
||||
async for raw in self.stream(req):
|
||||
packet = decoder.feed_line(raw)
|
||||
if packet is not None:
|
||||
yield packet
|
||||
|
||||
|
||||
# 앱 전역 싱글톤 (main lifespan 에서 startup/shutdown)
|
||||
engine_client = EngineClient()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue