From 00d824f6551a3dda8347e12ee042afad4ff237ed Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:42:31 -0700 Subject: [PATCH] =?UTF-8?q?refactor(contracts):=20consolidate=20the=20five?= =?UTF-8?q?=20shapes=20declared=20twice=20(PendingApproval,=20MessageReact?= =?UTF-8?q?ion,=20SessionControlSnapshot,=20ApprovalChoice,=20provider=20r?= =?UTF-8?q?ow)=20=E2=80=94=20no=20module-qualified=20TS=20names=20remain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/shared/src/gateway-contract.generated.ts | 79 +- apps/shared/src/gateway-contract.openrpc.json | 812 ++++++------------ .../contracts/billing_delegation_pets.py | 11 +- tui_gateway/contracts/common.py | 28 +- tui_gateway/contracts/events.py | 23 +- tui_gateway/contracts/groups_bot_relay.py | 6 +- ...ofiles_vault_complete_foreign_subagents.py | 20 +- tui_gateway/contracts/prompt_voice.py | 18 +- tui_gateway/contracts/sessions.py | 16 +- 9 files changed, 307 insertions(+), 706 deletions(-) diff --git a/apps/shared/src/gateway-contract.generated.ts b/apps/shared/src/gateway-contract.generated.ts index 7f00494d65..af22fe41b2 100644 --- a/apps/shared/src/gateway-contract.generated.ts +++ b/apps/shared/src/gateway-contract.generated.ts @@ -363,10 +363,10 @@ export interface MessageReactParams { export type ReactionAuthor = 'user' | 'agent' export interface MessageReactResult { row_id: number - reactions: tui_gateway_contracts_billing_delegation_pets_MessageReaction[] + reactions: MessageReaction[] } -/** One persisted reaction (``hermes_state_messages.py``); ``seen`` is stamped once announced. */ -export interface tui_gateway_contracts_billing_delegation_pets_MessageReaction { +/** One persisted reaction row (``hermes_state_messages.set_message_reaction``); ``seen`` is stamped once announced. */ +export interface MessageReaction { emoji: string author: string at?: number | null @@ -751,10 +751,10 @@ export interface SessionControlReadParams { session_id: string } export interface SessionControlReadResult { - control: tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot + control: SessionControlSnapshot } /** ``_snapshot_control`` — ``revision`` is a hash of the visible state (``""`` when empty); ``updated_at`` is the newest persisted timestamp (``0`` when none). */ -export interface tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot { +export interface SessionControlSnapshot { goal: GoalSnapshot | null loop: LoopSnapshot | null heartbeat: HeartbeatSnapshot | null @@ -842,7 +842,7 @@ export interface SessionControlArgs { index?: number | null } export interface SessionControlResult { - control: tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot + control: SessionControlSnapshot dispatch: SessionControlDispatch } /** ``_dispatch_envelope`` — the command result's user-visible envelope, every key always present. */ @@ -1099,10 +1099,10 @@ export interface GroupsApproveParams { member_id: string task_id: string execution_generation: number - choice: tui_gateway_contracts_groups_bot_relay_ApprovalChoice + choice: ApprovalChoice request_id: string } -export type tui_gateway_contracts_groups_bot_relay_ApprovalChoice = 'once' | 'deny' +export type ApprovalChoice = 'once' | 'session' | 'always' | 'deny' /** ``result`` is the local ``approval.respond`` answer or the peer's run-action receipt. */ export interface GroupsApproveResult { approved?: boolean @@ -1363,21 +1363,7 @@ export interface ModelSaveKeyParams { session_id?: string | null } export interface ModelSaveKeyResult { - provider: ModelProviderRow -} -/** One provider row of the shared inventory builder (``hermes_cli.inventory``); the closed set of keys is owned there. */ -export interface ModelProviderRow { - slug: string - name?: string - is_current?: boolean - is_user_defined?: boolean | null - models?: unknown[] - total_models?: number | null - authenticated?: boolean | null - auth_type?: string | null - key_env?: string | null - warning?: string | null - [key: string]: unknown + provider: ModelOptionProvider } export interface ModelDisconnectParams { slug: string @@ -2243,10 +2229,10 @@ export interface ApprovalPendingParams { profile?: string | null } export interface ApprovalPendingResult { - approvals: tui_gateway_contracts_prompt_voice_PendingApproval[] + approvals: PendingApproval[] } -/** One unresolved ``tools/approval.py`` gateway queue entry (snapshot of its ``data``); the key set is owned by the approval tool, so it stays open. */ -export interface tui_gateway_contracts_prompt_voice_PendingApproval { +/** One unresolved ``tools/approval.py`` gateway queue entry as ``server._approval_request_payload`` renders it (command redacted; ``choices`` precomputed). The key set is owned by the approval tool. */ +export interface PendingApproval { request_id?: string | null command?: string | null description?: string | null @@ -2471,7 +2457,7 @@ export interface SessionResumeResult { status?: string | null inflight?: InflightTurn | null queued?: QueuedPrompt | null - pending_approval?: tui_gateway_contracts_sessions_PendingApproval | null + pending_approval?: PendingApproval | null open_requests?: OpenRequestEntry[] | null todo_state?: TodoState | null auto_continue?: AutoContinue | null @@ -2491,18 +2477,6 @@ export interface InflightTurn { export interface QueuedPrompt { user: string } -/** ``server._approval_request_payload`` for the oldest unresolved approval (command redacted). */ -export interface tui_gateway_contracts_sessions_PendingApproval { - request_id?: string | null - command?: string | null - description?: string | null - choices?: string[] | null - allow_permanent?: boolean | null - allow_session?: boolean | null - smart_denied?: boolean | null - tool_name?: string | null - [key: string]: unknown -} /** One unanswered server→client request (``server_requests.Request.snapshot``); the reconnecting client re-delivers it to its request handlers. */ export interface OpenRequestEntry { id: string @@ -2541,7 +2515,7 @@ export interface SessionActivateResult { status?: string | null inflight?: InflightTurn | null queued?: QueuedPrompt | null - pending_approval?: tui_gateway_contracts_sessions_PendingApproval | null + pending_approval?: PendingApproval | null open_requests?: OpenRequestEntry[] | null todo_state?: TodoState | null auto_continue?: AutoContinue | null @@ -3660,7 +3634,7 @@ export interface ApprovalRequestParams { request_id: string command?: string description?: string - choices?: tui_gateway_contracts_server_requests_ApprovalChoice[] + choices?: ApprovalChoice[] allow_permanent?: boolean | null allow_session?: boolean | null smart_denied?: boolean | null @@ -3668,9 +3642,8 @@ export interface ApprovalRequestParams { gateway_session_id?: string | null [key: string]: unknown } -export type tui_gateway_contracts_server_requests_ApprovalChoice = 'once' | 'session' | 'always' | 'deny' export interface ApprovalResult { - choice: tui_gateway_contracts_server_requests_ApprovalChoice + choice: ApprovalChoice all?: boolean | null } export interface EmptyRequestParams { @@ -3927,16 +3900,7 @@ export interface SessionReclaimedPayload { reason: string } export interface SessionControlUpdatePayload { - control: tui_gateway_contracts_events_SessionControlSnapshot -} -/** ``methods_session_control._snapshot_control``; goal / loop / heartbeat sub-objects are the allow-listed state-file projections (owned by hermes_cli.goals / loops / heartbeat). */ -export interface tui_gateway_contracts_events_SessionControlSnapshot { - goal?: Record | null - loop?: Record | null - heartbeat?: Record | null - revision?: string - updated_at?: number - [key: string]: unknown + control: SessionControlSnapshot } /** ``methods_session`` billing.step_up on_verification. */ export interface BillingStepUpVerificationPayload { @@ -4031,16 +3995,9 @@ export interface PaneRevealPayload { /** ``tools/react_to_message_tool.py``. */ export interface MessageReactionPayload { row_id: number - reactions: tui_gateway_contracts_events_MessageReaction[] + reactions: MessageReaction[] role: string } -/** ``hermes_state_messages.set_message_reaction`` row. */ -export interface tui_gateway_contracts_events_MessageReaction { - emoji: string - author: string - at?: number | null - [key: string]: unknown -} /** ``session_notifications`` process_registry.on_output. */ export interface TerminalOutputPayload { process_id: string diff --git a/apps/shared/src/gateway-contract.openrpc.json b/apps/shared/src/gateway-contract.openrpc.json index ee0eb5a931..37eab38bbd 100644 --- a/apps/shared/src/gateway-contract.openrpc.json +++ b/apps/shared/src/gateway-contract.openrpc.json @@ -4210,6 +4210,16 @@ "title": "AgentsListResult", "type": "object" }, + "ApprovalChoice": { + "enum": [ + "once", + "session", + "always", + "deny" + ], + "title": "ApprovalChoice", + "type": "string" + }, "ApprovalPendingParams": { "additionalProperties": false, "properties": { @@ -4241,7 +4251,7 @@ "properties": { "approvals": { "items": { - "$ref": "#/components/schemas/tui_gateway_contracts_prompt_voice_PendingApproval" + "$ref": "#/components/schemas/PendingApproval" }, "title": "Approvals", "type": "array" @@ -4322,7 +4332,7 @@ }, "choices": { "items": { - "$ref": "#/components/schemas/tui_gateway_contracts_server_requests_ApprovalChoice" + "$ref": "#/components/schemas/ApprovalChoice" }, "title": "Choices", "type": "array" @@ -4476,7 +4486,7 @@ "additionalProperties": false, "properties": { "choice": { - "$ref": "#/components/schemas/tui_gateway_contracts_server_requests_ApprovalChoice" + "$ref": "#/components/schemas/ApprovalChoice" }, "all": { "anyOf": [ @@ -10284,7 +10294,7 @@ "type": "integer" }, "choice": { - "$ref": "#/components/schemas/tui_gateway_contracts_groups_bot_relay_ApprovalChoice" + "$ref": "#/components/schemas/ApprovalChoice" }, "request_id": { "title": "Request Id", @@ -14366,7 +14376,7 @@ }, "reactions": { "items": { - "$ref": "#/components/schemas/tui_gateway_contracts_billing_delegation_pets_MessageReaction" + "$ref": "#/components/schemas/MessageReaction" }, "title": "Reactions", "type": "array" @@ -14379,6 +14389,50 @@ "title": "MessageReactResult", "type": "object" }, + "MessageReaction": { + "additionalProperties": true, + "description": "One persisted reaction row (``hermes_state_messages.set_message_reaction``); ``seen`` is\nstamped once announced.", + "properties": { + "emoji": { + "title": "Emoji", + "type": "string" + }, + "author": { + "title": "Author", + "type": "string" + }, + "at": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "At" + }, + "seen": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Seen" + } + }, + "required": [ + "emoji", + "author" + ], + "title": "MessageReaction", + "type": "object" + }, "MessageReactionPayload": { "additionalProperties": false, "description": "``tools/react_to_message_tool.py``.", @@ -14389,7 +14443,7 @@ }, "reactions": { "items": { - "$ref": "#/components/schemas/tui_gateway_contracts_events_MessageReaction" + "$ref": "#/components/schemas/MessageReaction" }, "title": "Reactions", "type": "array" @@ -15025,108 +15079,6 @@ "title": "ModelPricing", "type": "object" }, - "ModelProviderRow": { - "additionalProperties": true, - "description": "One provider row of the shared inventory builder (``hermes_cli.inventory``); the closed\nset of keys is owned there.", - "properties": { - "slug": { - "title": "Slug", - "type": "string" - }, - "name": { - "default": "", - "title": "Name", - "type": "string" - }, - "is_current": { - "default": false, - "title": "Is Current", - "type": "boolean" - }, - "is_user_defined": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Is User Defined" - }, - "models": { - "items": {}, - "title": "Models", - "type": "array" - }, - "total_models": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Total Models" - }, - "authenticated": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Authenticated" - }, - "auth_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Auth Type" - }, - "key_env": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Key Env" - }, - "warning": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Warning" - } - }, - "required": [ - "slug" - ], - "title": "ModelProviderRow", - "type": "object" - }, "ModelSaveKeyParams": { "additionalProperties": false, "properties": { @@ -15162,7 +15114,7 @@ "additionalProperties": false, "properties": { "provider": { - "$ref": "#/components/schemas/ModelProviderRow" + "$ref": "#/components/schemas/ModelOptionProvider" } }, "required": [ @@ -15714,6 +15666,140 @@ "title": "PeerRouteStatus", "type": "object" }, + "PendingApproval": { + "additionalProperties": true, + "description": "One unresolved ``tools/approval.py`` gateway queue entry as ``server._approval_request_payload``\nrenders it (command redacted; ``choices`` precomputed). The key set is owned by the approval tool.", + "properties": { + "request_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Request Id" + }, + "command": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Command" + }, + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Description" + }, + "pattern_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pattern Key" + }, + "pattern_keys": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Pattern Keys" + }, + "allow_permanent": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Allow Permanent" + }, + "allow_session": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Allow Session" + }, + "smart_denied": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Smart Denied" + }, + "choices": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Choices" + }, + "tool_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Tool Name" + } + }, + "title": "PendingApproval", + "type": "object" + }, "PetCancelParams": { "additionalProperties": false, "properties": { @@ -23263,7 +23349,7 @@ "pending_approval": { "anyOf": [ { - "$ref": "#/components/schemas/tui_gateway_contracts_sessions_PendingApproval" + "$ref": "#/components/schemas/PendingApproval" }, { "type": "null" @@ -24042,7 +24128,7 @@ "additionalProperties": false, "properties": { "control": { - "$ref": "#/components/schemas/tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot" + "$ref": "#/components/schemas/SessionControlSnapshot" } }, "required": [ @@ -24055,7 +24141,7 @@ "additionalProperties": false, "properties": { "control": { - "$ref": "#/components/schemas/tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot" + "$ref": "#/components/schemas/SessionControlSnapshot" }, "dispatch": { "$ref": "#/components/schemas/SessionControlDispatch" @@ -24068,11 +24154,64 @@ "title": "SessionControlResult", "type": "object" }, + "SessionControlSnapshot": { + "additionalProperties": false, + "description": "``_snapshot_control`` \u2014 ``revision`` is a hash of the visible state (``\"\"`` when empty);\n``updated_at`` is the newest persisted timestamp (``0`` when none).", + "properties": { + "goal": { + "anyOf": [ + { + "$ref": "#/components/schemas/GoalSnapshot" + }, + { + "type": "null" + } + ] + }, + "loop": { + "anyOf": [ + { + "$ref": "#/components/schemas/LoopSnapshot" + }, + { + "type": "null" + } + ] + }, + "heartbeat": { + "anyOf": [ + { + "$ref": "#/components/schemas/HeartbeatSnapshot" + }, + { + "type": "null" + } + ] + }, + "revision": { + "title": "Revision", + "type": "string" + }, + "updated_at": { + "title": "Updated At", + "type": "number" + } + }, + "required": [ + "goal", + "loop", + "heartbeat", + "revision", + "updated_at" + ], + "title": "SessionControlSnapshot", + "type": "object" + }, "SessionControlUpdatePayload": { "additionalProperties": false, "properties": { "control": { - "$ref": "#/components/schemas/tui_gateway_contracts_events_SessionControlSnapshot" + "$ref": "#/components/schemas/SessionControlSnapshot" } }, "required": [ @@ -25834,7 +25973,7 @@ "pending_approval": { "anyOf": [ { - "$ref": "#/components/schemas/tui_gateway_contracts_sessions_PendingApproval" + "$ref": "#/components/schemas/PendingApproval" }, { "type": "null" @@ -32713,451 +32852,6 @@ }, "title": "_SessionScoped", "type": "object" - }, - "tui_gateway_contracts_billing_delegation_pets_MessageReaction": { - "additionalProperties": true, - "description": "One persisted reaction (``hermes_state_messages.py``); ``seen`` is stamped once announced.", - "properties": { - "emoji": { - "title": "Emoji", - "type": "string" - }, - "author": { - "title": "Author", - "type": "string" - }, - "at": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "At" - }, - "seen": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Seen" - } - }, - "required": [ - "emoji", - "author" - ], - "title": "MessageReaction", - "type": "object" - }, - "tui_gateway_contracts_config_free_tier_control_SessionControlSnapshot": { - "additionalProperties": false, - "description": "``_snapshot_control`` \u2014 ``revision`` is a hash of the visible state (``\"\"`` when empty);\n``updated_at`` is the newest persisted timestamp (``0`` when none).", - "properties": { - "goal": { - "anyOf": [ - { - "$ref": "#/components/schemas/GoalSnapshot" - }, - { - "type": "null" - } - ] - }, - "loop": { - "anyOf": [ - { - "$ref": "#/components/schemas/LoopSnapshot" - }, - { - "type": "null" - } - ] - }, - "heartbeat": { - "anyOf": [ - { - "$ref": "#/components/schemas/HeartbeatSnapshot" - }, - { - "type": "null" - } - ] - }, - "revision": { - "title": "Revision", - "type": "string" - }, - "updated_at": { - "title": "Updated At", - "type": "number" - } - }, - "required": [ - "goal", - "loop", - "heartbeat", - "revision", - "updated_at" - ], - "title": "SessionControlSnapshot", - "type": "object" - }, - "tui_gateway_contracts_events_MessageReaction": { - "additionalProperties": true, - "description": "``hermes_state_messages.set_message_reaction`` row.", - "properties": { - "emoji": { - "title": "Emoji", - "type": "string" - }, - "author": { - "title": "Author", - "type": "string" - }, - "at": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "title": "At" - } - }, - "required": [ - "emoji", - "author" - ], - "title": "MessageReaction", - "type": "object" - }, - "tui_gateway_contracts_events_SessionControlSnapshot": { - "additionalProperties": true, - "description": "``methods_session_control._snapshot_control``; goal / loop / heartbeat sub-objects are the\nallow-listed state-file projections (owned by hermes_cli.goals / loops / heartbeat).", - "properties": { - "goal": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Goal" - }, - "loop": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Loop" - }, - "heartbeat": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Heartbeat" - }, - "revision": { - "default": "", - "title": "Revision", - "type": "string" - }, - "updated_at": { - "default": 0, - "title": "Updated At", - "type": "number" - } - }, - "title": "SessionControlSnapshot", - "type": "object" - }, - "tui_gateway_contracts_groups_bot_relay_ApprovalChoice": { - "enum": [ - "once", - "deny" - ], - "title": "ApprovalChoice", - "type": "string" - }, - "tui_gateway_contracts_prompt_voice_PendingApproval": { - "additionalProperties": true, - "description": "One unresolved ``tools/approval.py`` gateway queue entry (snapshot of its ``data``); the key\nset is owned by the approval tool, so it stays open.", - "properties": { - "request_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Request Id" - }, - "command": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Command" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Description" - }, - "pattern_key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Pattern Key" - }, - "pattern_keys": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Pattern Keys" - }, - "allow_permanent": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Allow Permanent" - }, - "allow_session": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Allow Session" - }, - "smart_denied": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Smart Denied" - }, - "choices": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Choices" - }, - "tool_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tool Name" - } - }, - "title": "PendingApproval", - "type": "object" - }, - "tui_gateway_contracts_server_requests_ApprovalChoice": { - "enum": [ - "once", - "session", - "always", - "deny" - ], - "title": "ApprovalChoice", - "type": "string" - }, - "tui_gateway_contracts_sessions_PendingApproval": { - "additionalProperties": true, - "description": "``server._approval_request_payload`` for the oldest unresolved approval (command redacted).", - "properties": { - "request_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Request Id" - }, - "command": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Command" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Description" - }, - "choices": { - "anyOf": [ - { - "items": { - "type": "string" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Choices" - }, - "allow_permanent": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Allow Permanent" - }, - "allow_session": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Allow Session" - }, - "smart_denied": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Smart Denied" - }, - "tool_name": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Tool Name" - } - }, - "title": "PendingApproval", - "type": "object" } } }, diff --git a/tui_gateway/contracts/billing_delegation_pets.py b/tui_gateway/contracts/billing_delegation_pets.py index fe1ea70e12..9cb4c13656 100644 --- a/tui_gateway/contracts/billing_delegation_pets.py +++ b/tui_gateway/contracts/billing_delegation_pets.py @@ -11,7 +11,7 @@ from __future__ import annotations from pydantic import Field from .base import JsonValue, Params, Result, WireEnum -from .common import OpenModel, ProfileParams, SessionParams +from .common import MessageReaction, OpenModel, ProfileParams, SessionParams from .registry import method # ── billing envelope ────────────────────────────────────────────────────────────────────────── @@ -482,15 +482,6 @@ class MessageReactParams(SessionParams): author: ReactionAuthor | None = None -class MessageReaction(OpenModel): - """One persisted reaction (``hermes_state_messages.py``); ``seen`` is stamped once announced.""" - - emoji: str - author: str - at: float | None = None - seen: bool | None = None - - class MessageReactResult(Result): row_id: int reactions: list[MessageReaction] diff --git a/tui_gateway/contracts/common.py b/tui_gateway/contracts/common.py index c83cf1d471..2b3973f726 100644 --- a/tui_gateway/contracts/common.py +++ b/tui_gateway/contracts/common.py @@ -158,6 +158,32 @@ TERMINAL_SUBAGENT_STATUSES = frozenset({ }) +class PendingApproval(OpenModel): + """One unresolved ``tools/approval.py`` gateway queue entry as ``server._approval_request_payload`` + renders it (command redacted; ``choices`` precomputed). The key set is owned by the approval tool.""" + + request_id: str | None = None + command: str | None = None + description: str | None = None + pattern_key: str | None = None + pattern_keys: list[str] | None = None + allow_permanent: bool | None = None + allow_session: bool | None = None + smart_denied: bool | None = None + choices: list[str] | None = None + tool_name: str | None = None + + +class MessageReaction(OpenModel): + """One persisted reaction row (``hermes_state_messages.set_message_reaction``); ``seen`` is + stamped once announced.""" + + emoji: str + author: str + at: float | None = None + seen: bool | None = None + + class SessionParams(Params): """Any method addressed at one live session.""" @@ -188,7 +214,7 @@ class EmptyPayload(Payload): __all__ = [ - "TERMINAL_SUBAGENT_STATUSES", "EmptyPayload", "EmptyResult", "McpServerStatus", "OkResult", "OpenModel", + "TERMINAL_SUBAGENT_STATUSES", "EmptyPayload", "EmptyResult", "McpServerStatus", "MessageReaction", "OkResult", "OpenModel", "PendingApproval", "ProfileParams", "ProjectRef", "SessionLiveInfo", "SessionParams", "StatusResult", "StoredSessionRow", "SubagentStatus", "TranscriptMessage", "Usage", ] diff --git a/tui_gateway/contracts/events.py b/tui_gateway/contracts/events.py index 8cae75396d..fca6ba4e47 100644 --- a/tui_gateway/contracts/events.py +++ b/tui_gateway/contracts/events.py @@ -18,7 +18,8 @@ from __future__ import annotations from pydantic import Field from .base import JsonValue, Payload, WireEnum -from .common import SessionLiveInfo, SubagentStatus, Usage +from .common import MessageReaction, SessionLiveInfo, SubagentStatus, Usage +from .config_free_tier_control import SessionControlSnapshot from .registry import event @@ -371,17 +372,6 @@ class SessionReclaimedPayload(Payload): event("session.reclaimed", SessionReclaimedPayload, doc="The backend reclaimed a live session out from under its clients.") -class SessionControlSnapshot(OpenPayload): - """``methods_session_control._snapshot_control``; goal / loop / heartbeat sub-objects are the - allow-listed state-file projections (owned by hermes_cli.goals / loops / heartbeat).""" - - goal: dict[str, JsonValue] | None = None - loop: dict[str, JsonValue] | None = None - heartbeat: dict[str, JsonValue] | None = None - revision: str = "" - updated_at: float = 0 - - class SessionControlUpdatePayload(Payload): control: SessionControlSnapshot @@ -550,15 +540,6 @@ event("layout.apply", LayoutApplyPayload, doc="Apply a named desktop layout pres event("pane.reveal", PaneRevealPayload, doc="Focus / reveal a named desktop pane.") -class MessageReaction(Payload): - """``hermes_state_messages.set_message_reaction`` row.""" - - emoji: str - author: str - at: float | None = None - model_config = Payload.model_config | {"extra": "allow"} - - class MessageReactionPayload(Payload): """``tools/react_to_message_tool.py``.""" diff --git a/tui_gateway/contracts/groups_bot_relay.py b/tui_gateway/contracts/groups_bot_relay.py index 1204365f5f..1f9923b564 100644 --- a/tui_gateway/contracts/groups_bot_relay.py +++ b/tui_gateway/contracts/groups_bot_relay.py @@ -12,6 +12,7 @@ from __future__ import annotations from .base import JsonValue, Params, Result, WireEnum from .common import OkResult, OpenModel, ProfileParams from .registry import method +from .server_requests import ApprovalChoice # ── shared room shapes ──────────────────────────────────────────────────────────────────────── @@ -311,11 +312,6 @@ method("groups.stop", params=GroupsStopParams, result=GroupsStopResult, doc="Durably cancel queued or running work for one hosted room.") -class ApprovalChoice(WireEnum): - once = "once" - deny = "deny" - - class GroupsApproveParams(RoomParams): member_id: str task_id: str diff --git a/tui_gateway/contracts/profiles_vault_complete_foreign_subagents.py b/tui_gateway/contracts/profiles_vault_complete_foreign_subagents.py index ddc40c8943..c86af31f5f 100644 --- a/tui_gateway/contracts/profiles_vault_complete_foreign_subagents.py +++ b/tui_gateway/contracts/profiles_vault_complete_foreign_subagents.py @@ -15,6 +15,7 @@ from pydantic import Field from .base import JsonValue, Params, Result, WireEnum from .common import OpenModel, ProfileParams, SessionParams, SubagentStatus +from .config_free_tier_control import ModelOptionProvider from .registry import method # ── completions / paste / model keys (methods_complete) ─────────────────────────────────────── @@ -75,23 +76,6 @@ method("paste.collapse", params=PasteCollapseParams, result=PasteCollapseResult, doc="Spill a large paste to a file and hand back the inline placeholder.") -class ModelProviderRow(OpenModel): - """One provider row of the shared inventory builder (``hermes_cli.inventory``); the closed - set of keys is owned there.""" - - # TODO(common): same shape as the ``model.options`` provider rows — consolidate. - slug: str - name: str = "" - is_current: bool = False - is_user_defined: bool | None = None - models: list[JsonValue] = Field(default_factory=list) - total_models: int | None = None - authenticated: bool | None = None - auth_type: str | None = None - key_env: str | None = None - warning: str | None = None - - class ModelSaveKeyParams(Params): slug: str api_key: str @@ -99,7 +83,7 @@ class ModelSaveKeyParams(Params): class ModelSaveKeyResult(Result): - provider: ModelProviderRow + provider: ModelOptionProvider method("model.save_key", params=ModelSaveKeyParams, result=ModelSaveKeyResult, diff --git a/tui_gateway/contracts/prompt_voice.py b/tui_gateway/contracts/prompt_voice.py index e080dda1c9..5376031c50 100644 --- a/tui_gateway/contracts/prompt_voice.py +++ b/tui_gateway/contracts/prompt_voice.py @@ -10,7 +10,7 @@ from __future__ import annotations from pydantic import Field from .base import JsonValue, Params, Result, WireEnum -from .common import OpenModel, SessionParams +from .common import OpenModel, PendingApproval, SessionParams from .registry import method # ── prompt.submit ───────────────────────────────────────────────────────────────────────────── @@ -284,22 +284,6 @@ method("request.answer", params=RequestAnswerParams, result=RequestAnswerResult, # ── approvals ───────────────────────────────────────────────────────────────────────────────── -class PendingApproval(OpenModel): - """One unresolved ``tools/approval.py`` gateway queue entry (snapshot of its ``data``); the key - set is owned by the approval tool, so it stays open.""" - - request_id: str | None = None - command: str | None = None - description: str | None = None - pattern_key: str | None = None - pattern_keys: list[str] | None = None - allow_permanent: bool | None = None - allow_session: bool | None = None - smart_denied: bool | None = None - choices: list[str] | None = None - tool_name: str | None = None - - class ApprovalPendingParams(SessionParams): pass diff --git a/tui_gateway/contracts/sessions.py b/tui_gateway/contracts/sessions.py index 7265d39694..e03100b983 100644 --- a/tui_gateway/contracts/sessions.py +++ b/tui_gateway/contracts/sessions.py @@ -8,7 +8,8 @@ from __future__ import annotations from pydantic import Field from .base import JsonValue, Params, Result, WireEnum -from .common import OpenModel, ProfileParams, SessionLiveInfo, SessionParams, TranscriptMessage, Usage +from .common import (OpenModel, PendingApproval, ProfileParams, SessionLiveInfo, SessionParams, TranscriptMessage, + Usage) from .registry import method @@ -57,19 +58,6 @@ class AutoContinue(Result): interrupted_at: float -class PendingApproval(OpenModel): # TODO(common): twin of server_requests.ApprovalRequestParams minus session_id - """``server._approval_request_payload`` for the oldest unresolved approval (command redacted).""" - - request_id: str | None = None - command: str | None = None - description: str | None = None - choices: list[str] | None = None - allow_permanent: bool | None = None - allow_session: bool | None = None - smart_denied: bool | None = None - tool_name: str | None = None - - class LiveSessionStatus(WireEnum): idle = "idle" starting = "starting"