From b67441309c4d7cb4bc4e97b3f773a1ed291d33ee Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Mon, 14 Sep 2026 02:22:10 -0700 Subject: [PATCH] =?UTF-8?q?fix(contracts):=20SessionLiveInfo=20model/tools?= =?UTF-8?q?/skills=20stay=20optional=20=E2=80=94=20lazy=20and=20mirror=20p?= =?UTF-8?q?aths=20emit=20session.info=20without=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The strict suite showed 41 emit sites sending {model} or {} alone; the TUI banner coerces the missing maps instead of the contract lying about them. --- apps/shared/src/gateway-contract.generated.ts | 12 ++++++------ apps/shared/src/gateway-contract.openrpc.json | 12 ++---------- tui_gateway/contracts/common.py | 6 +++--- ui-tui/src/components/branding.tsx | 14 ++++++++------ 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/apps/shared/src/gateway-contract.generated.ts b/apps/shared/src/gateway-contract.generated.ts index c19d4f3f10..3174d29d86 100644 --- a/apps/shared/src/gateway-contract.generated.ts +++ b/apps/shared/src/gateway-contract.generated.ts @@ -515,15 +515,15 @@ export interface ConfigSetResult { } /** ``tui_gateway/server.py::_session_info`` — the ``session.info`` event and the ``info`` field of ``session.create`` / ``session.resume`` / ``session.activate`` results. */ export interface SessionLiveInfo { - model: string + model?: string provider?: string reasoning_effort?: string service_tier?: string fast?: boolean yolo?: boolean approval_mode?: string - tools: Record - skills: Record + tools?: Record + skills?: Record cwd?: string branch?: string | null project?: ProjectRef | null @@ -2615,15 +2615,15 @@ export interface SessionCwdSetParams { } /** The refreshed ``session.info`` view (full agent view, or the lazy shape). */ export interface SessionCwdSetResult { - model: string + model?: string provider?: string reasoning_effort?: string service_tier?: string fast?: boolean yolo?: boolean approval_mode?: string - tools: Record - skills: Record + tools?: Record + skills?: Record cwd?: string branch?: string | null project?: ProjectRef | null diff --git a/apps/shared/src/gateway-contract.openrpc.json b/apps/shared/src/gateway-contract.openrpc.json index 7875ed1921..a6af1cf595 100644 --- a/apps/shared/src/gateway-contract.openrpc.json +++ b/apps/shared/src/gateway-contract.openrpc.json @@ -24503,6 +24503,7 @@ "description": "The refreshed ``session.info`` view (full agent view, or the lazy shape).", "properties": { "model": { + "default": "", "title": "Model", "type": "string" }, @@ -24728,11 +24729,6 @@ "title": "Lazy" } }, - "required": [ - "model", - "tools", - "skills" - ], "title": "SessionCwdSetResult", "type": "object" }, @@ -25357,6 +25353,7 @@ "description": "``tui_gateway/server.py::_session_info`` \u2014 the ``session.info`` event and the ``info`` field of\n``session.create`` / ``session.resume`` / ``session.activate`` results.", "properties": { "model": { + "default": "", "title": "Model", "type": "string" }, @@ -25582,11 +25579,6 @@ "title": "Lazy" } }, - "required": [ - "model", - "tools", - "skills" - ], "title": "SessionLiveInfo", "type": "object" }, diff --git a/tui_gateway/contracts/common.py b/tui_gateway/contracts/common.py index ea9760c051..a445d278ba 100644 --- a/tui_gateway/contracts/common.py +++ b/tui_gateway/contracts/common.py @@ -62,15 +62,15 @@ class SessionLiveInfo(OpenModel): """``tui_gateway/server.py::_session_info`` — the ``session.info`` event and the ``info`` field of ``session.create`` / ``session.resume`` / ``session.activate`` results.""" - model: str + model: str = "" provider: str = "" reasoning_effort: str = "" service_tier: str = "" fast: bool = False yolo: bool = False approval_mode: str = "manual" - tools: dict[str, list[str]] - skills: dict[str, list[str]] + tools: dict[str, list[str]] = Field(default_factory=dict) + skills: dict[str, list[str]] = Field(default_factory=dict) cwd: str = "" branch: str | None = None project: ProjectRef | None = None diff --git a/ui-tui/src/components/branding.tsx b/ui-tui/src/components/branding.tsx index 99c6bb6f37..2d9d93fe1d 100644 --- a/ui-tui/src/components/branding.tsx +++ b/ui-tui/src/components/branding.tsx @@ -250,8 +250,9 @@ export function SessionPanel({ info, maxWidth, sid, t }: SessionPanelProps) { } // ── Collapsible skills section ── - const skillEntries = Object.entries(info.skills).sort() - const skillsTotal = flat(info.skills).length + const skills = info.skills ?? {} + const skillEntries = Object.entries(skills).sort() + const skillsTotal = flat(skills).length const skillsCatCount = skillEntries.length const skillsBody = () => { @@ -276,8 +277,9 @@ export function SessionPanel({ info, maxWidth, sid, t }: SessionPanelProps) { } // ── Collapsible tools section ── - const toolEntries = Object.entries(info.tools).sort() - const toolsTotal = flat(info.tools).length + const tools = info.tools ?? {} + const toolEntries = Object.entries(tools).sort() + const toolsTotal = flat(tools).length // MCP headline counts *connected* servers, not configured-but-disabled ones, // so it matches the classic CLI banner (`sum(s.connected)` in @@ -354,7 +356,7 @@ export function SessionPanel({ info, maxWidth, sid, t }: SessionPanelProps) { - {info.model.split('/').pop()} + {(info.model ?? '').split('/').pop()} · Nous Research @@ -386,7 +388,7 @@ export function SessionPanel({ info, maxWidth, sid, t }: SessionPanelProps) { // here so they aren't lost. - {info.model.split('/').pop()} + {(info.model ?? '').split('/').pop()} · Nous Research