step-1: add v3 ws frame protocol (schemas.py)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user