step-1: add v3 ws frame protocol (schemas.py)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 21:21:03 +01:00
parent ac71d99f9a
commit b61ded8458
4 changed files with 426 additions and 0 deletions

View File

@@ -26,6 +26,7 @@ class Settings(BaseSettings):
OPENAI_API_KEY: str = ""
ANTHROPIC_API_KEY: str = ""
GOOGLE_API_KEY: str = ""
CEREBRAS_API_KEY: str = ""
LLM_MODEL: str = "gpt-4o"
LLM_ROUTER_MODEL: str = "gpt-4o-mini"

View File

@@ -161,6 +161,7 @@ class PluginInstallRequest(BaseModel):
# ── WebSocket Frame Protocol ──────────────────────────────────────────
class WsFrameType(str, Enum):
# ── v2 frame types (kept for backward compat) ──────────────────────
chat_request = "chat_request"
text_chunk = "text_chunk"
tool_call = "tool_call"
@@ -171,6 +172,17 @@ class WsFrameType(str, Enum):
agent_data = "agent_data"
agent_complete = "agent_complete"
device_hello = "device_hello"
# ── v3 frame types ─────────────────────────────────────────────────
home_request = "home_request"
popup_request = "popup_request"
stream_start = "stream_start"
stream_text = "stream_text"
stream_block = "stream_block"
stream_end = "stream_end"
popup_domain = "popup_domain"
data_request = "data_request"
data_response = "data_response"
mutation = "mutation"
class WsToolCall(BaseModel):
@@ -249,6 +261,71 @@ class WsAgentComplete(BaseModel):
errors: list[str] = Field(default_factory=list)
# ── WebSocket v3 Frame Models ─────────────────────────────────────────
class WsPopupScope(BaseModel):
"""Scope for a popup request — narrows the agent to a specific entity."""
type: Literal["task", "project", "note", "checkpoint"]
id: str | None = None
class WsHomeRequest(BaseModel):
"""Client → Server: Home chat message."""
type: Literal[WsFrameType.home_request] = WsFrameType.home_request
message: str
conversation_history: list[dict[str, Any]] = Field(default_factory=list)
class WsPopupRequest(BaseModel):
"""Client → Server: Popup chat message scoped to an entity."""
type: Literal[WsFrameType.popup_request] = WsFrameType.popup_request
message: str
scope: WsPopupScope
class WsStreamStart(BaseModel):
"""Server → Client: signals start of a streaming response."""
type: Literal[WsFrameType.stream_start] = WsFrameType.stream_start
request_id: str
class WsStreamText(BaseModel):
"""Server → Client: streamed text token."""
type: Literal[WsFrameType.stream_text] = WsFrameType.stream_text
request_id: str
chunk: str
class WsStreamBlock(BaseModel):
"""Server → Client: structured block (chart, table, entity, timeline)."""
type: Literal[WsFrameType.stream_block] = WsFrameType.stream_block
request_id: str
block_type: Literal["chart", "entity_ref", "table", "timeline"]
data: dict[str, Any]
class WsStreamEnd(BaseModel):
"""Server → Client: signals end of a streaming response."""
type: Literal[WsFrameType.stream_end] = WsFrameType.stream_end
request_id: str
mutations: list[dict[str, Any]] = Field(default_factory=list)
class WsPopupDomain(BaseModel):
"""Server → Client: domain determined for a popup request."""
type: Literal[WsFrameType.popup_domain] = WsFrameType.popup_domain
request_id: str
domain: Literal["tasks", "checkpoints", "notes", "projects"]
# ── Agent Catalog ─────────────────────────────────────────────────────
class AgentCatalogItem(BaseModel):