feat: 운영 안정성과 세션 음성 경험 개선

This commit is contained in:
Yun Chan 2026-07-31 00:13:08 +09:00
parent facc4ad2d9
commit c788343467
95 changed files with 8431 additions and 1785 deletions

View file

@ -15,6 +15,16 @@ from pydantic import BaseModel, Field
AIRole = Literal["client", "counselor", "evaluator"]
EngineMessageRole = Literal["system", "user", "assistant"]
EngineGatewaySseEvent = Literal["token", "done", "error"]
EngineProvider = Literal[
"claude_cli",
"claude_api",
"codex_cli",
"agy_cli",
"openai",
"solar",
]
ReasoningEffort = Literal["low", "medium", "high", "xhigh", "max", "ultra"]
EngineCapabilitySource = Literal["live_cli", "live_api", "static_cli", "unavailable"]
ENGINE_GATEWAY_SSE_TOKEN: EngineGatewaySseEvent = "token"
ENGINE_GATEWAY_SSE_DONE: EngineGatewaySseEvent = "done"
@ -25,6 +35,30 @@ ENGINE_GATEWAY_SSE_EVENTS: tuple[EngineGatewaySseEvent, ...] = (
ENGINE_GATEWAY_SSE_ERROR,
)
ENGINE_GATEWAY_DEFAULT_MODEL_SENTINEL = "gateway-default"
ENGINE_PROVIDERS: tuple[EngineProvider, ...] = (
"claude_cli",
"claude_api",
"codex_cli",
"agy_cli",
"openai",
"solar",
)
ENGINE_REASONING_EFFORTS: tuple[ReasoningEffort, ...] = (
"low",
"medium",
"high",
"xhigh",
"max",
"ultra",
)
ENGINE_PROVIDER_DEFAULTS: dict[EngineProvider, tuple[str, Optional[ReasoningEffort]]] = {
"claude_cli": (ENGINE_GATEWAY_DEFAULT_MODEL_SENTINEL, "high"),
"claude_api": (ENGINE_GATEWAY_DEFAULT_MODEL_SENTINEL, "high"),
"codex_cli": ("gpt-5.6-terra", "medium"),
"agy_cli": ("gemini-3.6-flash-high", "high"),
"openai": (ENGINE_GATEWAY_DEFAULT_MODEL_SENTINEL, None),
"solar": (ENGINE_GATEWAY_DEFAULT_MODEL_SENTINEL, None),
}
def normalize_engine_gateway_model(model: Optional[str]) -> Optional[str]:
@ -45,7 +79,9 @@ class EngineMessage(BaseModel):
class GenerateRequest(BaseModel):
ai_role: AIRole = "client"
messages: list[EngineMessage]
provider: Optional[EngineProvider] = None
model: Optional[str] = None
reasoning_effort: Optional[ReasoningEffort] = None
max_tokens: int = 1024
temperature: float = 0.7
structured_schema: Optional[dict[str, Any]] = None
@ -68,6 +104,26 @@ class GenerateResponse(BaseModel):
structured: Optional[dict[str, Any]] = None
class EngineModelOption(BaseModel):
id: str
label: str
description: str = ""
reasoning_efforts: list[ReasoningEffort] = Field(default_factory=list)
default_reasoning_effort: Optional[ReasoningEffort] = None
is_default: bool = False
class EngineCapabilitiesResponse(BaseModel):
provider: EngineProvider
available: bool
source: EngineCapabilitySource
models: list[EngineModelOption] = Field(default_factory=list)
default_model: Optional[str] = None
default_reasoning_effort: Optional[ReasoningEffort] = None
detail: str = ""
fetched_at: float
def structured_payload_from_response(resp: GenerateResponse) -> dict[str, Any] | None:
"""Return structured output, or a JSON object embedded in legacy text."""