@ggui-ai/protocol 0.1.0-rc.3 → 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/bridge/invoke-agent.d.ts +8 -8
- package/dist/bridge/invoke-agent.d.ts.map +1 -1
- package/dist/bridge/invoke-agent.js +12 -12
- package/dist/envelopes/builders.d.ts +2 -4
- package/dist/envelopes/builders.d.ts.map +1 -1
- package/dist/envelopes/builders.js +2 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/integrations/mcp-apps.d.ts +354 -711
- package/dist/integrations/mcp-apps.d.ts.map +1 -1
- package/dist/integrations/mcp-apps.js +266 -208
- package/dist/recommended-prompts.d.ts +1 -1
- package/dist/recommended-prompts.js +1 -1
- package/dist/schemas/data-contract.d.ts +4 -3
- package/dist/schemas/data-contract.d.ts.map +1 -1
- package/dist/schemas/data-contract.js +4 -3
- package/dist/schemas/invoke.d.ts +2 -2
- package/dist/schemas/invoke.js +2 -2
- package/dist/schemas/mcp.d.ts +60 -79
- package/dist/schemas/mcp.d.ts.map +1 -1
- package/dist/schemas/mcp.js +93 -116
- package/dist/schemas/sync-check.js +1 -1
- package/dist/stream/stream-parser.d.ts +4 -4
- package/dist/stream/stream-parser.d.ts.map +1 -1
- package/dist/stream/stream-parser.js +9 -9
- package/dist/transport/websocket.d.ts +14 -49
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/types/app-config.d.ts +17 -32
- package/dist/types/app-config.d.ts.map +1 -1
- package/dist/types/canvas-lifecycle.d.ts +13 -13
- package/dist/types/canvas-lifecycle.d.ts.map +1 -1
- package/dist/types/canvas-lifecycle.js +3 -3
- package/dist/types/contract-inference.d.ts +4 -7
- package/dist/types/contract-inference.d.ts.map +1 -1
- package/dist/types/data-bindings.d.ts +1 -1
- package/dist/types/data-bindings.d.ts.map +1 -1
- package/dist/types/data-contract.d.ts +10 -10
- package/dist/types/data-contract.d.ts.map +1 -1
- package/dist/types/events.d.ts +14 -56
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js +1 -8
- package/dist/types/feedback.d.ts +2 -4
- package/dist/types/feedback.d.ts.map +1 -1
- package/dist/types/handshake-suggestion.d.ts +1 -1
- package/dist/types/host-context.d.ts +5 -15
- package/dist/types/host-context.d.ts.map +1 -1
- package/dist/types/host-context.js +1 -1
- package/dist/types/live-channel.d.ts +128 -191
- package/dist/types/live-channel.d.ts.map +1 -1
- package/dist/types/llm-route.d.ts +233 -0
- package/dist/types/llm-route.d.ts.map +1 -0
- package/dist/types/llm-route.js +433 -0
- package/dist/types/llm.d.ts +34 -16
- package/dist/types/llm.d.ts.map +1 -1
- package/dist/types/llm.js +34 -38
- package/dist/types/mcp.d.ts +47 -137
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/mcp.js +2 -2
- package/dist/types/openrouter-models.d.ts +3 -2
- package/dist/types/openrouter-models.d.ts.map +1 -1
- package/dist/types/render-event.d.ts +119 -0
- package/dist/types/render-event.d.ts.map +1 -0
- package/dist/types/render-event.js +38 -0
- package/dist/types/session.d.ts +216 -342
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/ui-generator.d.ts +8 -9
- package/dist/types/ui-generator.d.ts.map +1 -1
- package/dist/validation/contract-validator.d.ts +60 -4
- package/dist/validation/contract-validator.d.ts.map +1 -1
- package/dist/validation/contract-validator.js +101 -5
- package/dist/validation/reserved-channels.d.ts +1 -1
- package/dist/validation/reserved-channels.js +5 -5
- package/dist/validation/sanitize-error.js +1 -1
- package/dist/validation/schema-compat-invariants.d.ts +2 -2
- package/dist/validation/schema-compat-invariants.js +2 -2
- package/dist/validation/schema-meta-validation.d.ts +1 -1
- package/dist/validation/schema-meta-validation.js +2 -2
- package/dist/validation/schema-subset.d.ts +1 -1
- package/dist/version.d.ts +253 -46
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +253 -46
- package/package.json +3 -2
- package/dist/navigation/index.d.ts +0 -3
- package/dist/navigation/index.d.ts.map +0 -1
- package/dist/navigation/index.js +0 -1
- package/dist/navigation/stack-navigation.d.ts +0 -55
- package/dist/navigation/stack-navigation.d.ts.map +0 -1
- package/dist/navigation/stack-navigation.js +0 -80
package/dist/types/session.d.ts
CHANGED
|
@@ -1,399 +1,270 @@
|
|
|
1
|
-
import type { EventSubscription } from './events';
|
|
2
1
|
import type { CapabilityPermissions, QualityMetadata } from './capabilities';
|
|
3
2
|
import type { KNOWN_PERMISSION_NAMES } from '../validation/hygiene-rules';
|
|
4
3
|
import type { PropsSpec, StreamSpec, ActionSpec, ContextSpec, ClientCapabilitiesSpec, GadgetDescriptor, JsonSchema, JsonObject } from './data-contract';
|
|
5
4
|
import type { EndUserIdentity } from './auth';
|
|
6
5
|
import type { HostContextProjection } from './host-context';
|
|
7
|
-
import type {
|
|
8
|
-
import type { McpAppsStackItem } from '../integrations/mcp-apps';
|
|
6
|
+
import type { McpAppsRender } from '../integrations/mcp-apps';
|
|
9
7
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
* Recognised system-card kinds the runtime renders via built-in
|
|
9
|
+
* components. The wire is open-ended (string), but new kinds without a
|
|
10
|
+
* matching renderer fall through to a generic "system message" card so
|
|
11
|
+
* an old runtime + new server still produce something visible.
|
|
12
|
+
*/
|
|
13
|
+
export type SystemRenderKind = 'no-credentials' | 'mcp-apps-probe' | (string & {});
|
|
14
|
+
/**
|
|
15
|
+
* Adapter permission status
|
|
16
|
+
*/
|
|
17
|
+
export type PermissionStatus = 'granted' | 'denied' | 'prompt';
|
|
18
|
+
/**
|
|
19
|
+
* Adapter permissions — per-render map keyed by Web Permissions API
|
|
20
|
+
* name (see `KNOWN_PERMISSION_NAMES` in `validation/hygiene-rules.ts`).
|
|
17
21
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
22
|
+
* Keys derive from `KNOWN_PERMISSION_NAMES` so there's one source of
|
|
23
|
+
* truth for permission identifiers across the protocol surface
|
|
24
|
+
* (schema validation, hygiene rules, and runtime SDK cache).
|
|
20
25
|
*/
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/** Human-readable label displayed on the UI element */
|
|
25
|
-
label: string;
|
|
26
|
-
/** Optional description shown as secondary text */
|
|
27
|
-
description?: string;
|
|
28
|
-
/** Optional icon hint (emoji or icon name) */
|
|
29
|
-
icon?: string;
|
|
30
|
-
/** Visual style hint */
|
|
31
|
-
variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
|
|
32
|
-
/** Whether to show confirmation before triggering */
|
|
33
|
-
confirm?: boolean | string;
|
|
34
|
-
/** Whether currently disabled */
|
|
35
|
-
disabled?: boolean;
|
|
36
|
-
}
|
|
26
|
+
export type AdapterPermissions = {
|
|
27
|
+
readonly [K in (typeof KNOWN_PERMISSION_NAMES)[number]]?: PermissionStatus;
|
|
28
|
+
};
|
|
37
29
|
/**
|
|
38
|
-
*
|
|
30
|
+
* Lifecycle status of a {@link Render}. RenderStore implementations MAY
|
|
31
|
+
* populate this on `get`; absent ⇒ caller treats as `'active'`.
|
|
39
32
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* - `type: 'mcpApps'` → {@link McpAppsStackItem}.
|
|
33
|
+
* Two states only:
|
|
34
|
+
* - `'active'` — within TTL, agent may still write/read.
|
|
35
|
+
* - `'expired'` — TTL elapsed; no further writes accepted, reads return
|
|
36
|
+
* a historical snapshot.
|
|
45
37
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
|
|
38
|
+
* There is no explicit terminal state. Renders decay implicitly via TTL.
|
|
39
|
+
* The dropped `'completed'` state was a vestige of the deleted Session
|
|
40
|
+
* vessel — kept symmetrical with `ggui_new_session`, which was deleted
|
|
41
|
+
* in the earlier handshake collapse. The companion `ggui_close` tool
|
|
42
|
+
* that wrote it was removed in the same slice.
|
|
43
|
+
*/
|
|
44
|
+
export type RenderStatus = 'active' | 'expired';
|
|
45
|
+
/**
|
|
46
|
+
* Common base for every {@link Render} variant. Carries identity,
|
|
47
|
+
* tenancy, lifecycle, and conversation-scoped context that every
|
|
48
|
+
* rendered thing has regardless of how its visible bits are
|
|
49
|
+
* produced (LLM-generated component, server-emitted system card,
|
|
50
|
+
* embedded MCP-App iframe).
|
|
52
51
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
52
|
+
* **Conversation-scoped context note** — fields that convey "this
|
|
53
|
+
* render belongs to a logical group of renders within a host
|
|
54
|
+
* conversation" (hostContext continuity, sibling render discovery)
|
|
55
|
+
* are NOT duplicated onto each Render. They look up via the optional
|
|
56
|
+
* {@link RenderBase.hostSession} pair instead. See
|
|
57
|
+
* [[session-concept-deletion-2026-05-27]] for the framing.
|
|
56
58
|
*/
|
|
57
|
-
export interface
|
|
58
|
-
|
|
59
|
+
export interface RenderBase {
|
|
60
|
+
/** Render identity. The value an iframe's bootstrap meta and every
|
|
61
|
+
* wire reference (props_update, consume, update) keys by. */
|
|
62
|
+
readonly id: string;
|
|
63
|
+
/** App identity (tenancy boundary, always per-render). */
|
|
64
|
+
readonly appId: string;
|
|
65
|
+
/** Authenticated end-user (after the auth gate). Absent for anon
|
|
66
|
+
* flows. */
|
|
67
|
+
readonly userId?: string;
|
|
68
|
+
/** Full authenticated end-user identity (populated after auth gate). */
|
|
69
|
+
readonly endUserIdentity?: EndUserIdentity;
|
|
59
70
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Theme preset id for THIS stack item — agent-explicit per-push
|
|
67
|
-
* override on the layered theme-resolution chain:
|
|
71
|
+
* Host-supplied conversation-grouping pair, captured ONCE at render
|
|
72
|
+
* creation from `_meta["ai.ggui/host-session"]` on the inbound tool
|
|
73
|
+
* call. Identifies the MCP host (claude.ai, sample, etc.) and the
|
|
74
|
+
* host's opaque grouping key for "this conversation" — typically
|
|
75
|
+
* the host's thread/chat id.
|
|
68
76
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
77
|
+
* Multiple renders inside one host conversation share the same
|
|
78
|
+
* `hostSessionId`. The `ggui_list_renders(hostName, hostSessionId)`
|
|
79
|
+
* tool enumerates renders belonging to a host conversation; absent
|
|
80
|
+
* `hostSession` ⇒ the render is one-shot (functional but
|
|
81
|
+
* non-rehydratable).
|
|
73
82
|
*
|
|
74
|
-
*
|
|
75
|
-
* this only when the agent wants ONE push to render differently
|
|
76
|
-
* from the session default (e.g. an urgent alert in `crimson` while
|
|
77
|
-
* the rest of the chat stays on `slate`). Most pushes omit it and
|
|
78
|
-
* inherit the session theme; that's the intended common case.
|
|
83
|
+
* Once captured, immutable for the render's lifetime.
|
|
79
84
|
*/
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
* Carries request-specific data values (e.g., { city: "Seoul", temperature: 15 }).
|
|
85
|
-
* Renderer passes these as: <Component {...props} /> */
|
|
86
|
-
props?: TProps;
|
|
87
|
-
/** The prompt that produced this component (if LLM-generated) */
|
|
88
|
-
prompt?: string;
|
|
89
|
-
/** Human-readable description of what this component is */
|
|
90
|
-
description?: string;
|
|
91
|
-
/** Content type. Determines how componentCode is interpreted.
|
|
92
|
-
* Default: 'application/javascript+react' */
|
|
93
|
-
contentType?: string;
|
|
94
|
-
/** Agent message to display while the component generates (thinking indicator) */
|
|
95
|
-
message?: string;
|
|
96
|
-
/** JSON Schema for validating user-submitted form data */
|
|
97
|
-
schema?: JsonSchema;
|
|
85
|
+
readonly hostSession?: {
|
|
86
|
+
readonly hostName: string;
|
|
87
|
+
readonly hostSessionId: string;
|
|
88
|
+
};
|
|
98
89
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
90
|
+
* Theme preset id for this render. Resolution chain:
|
|
91
|
+
* 1. `Render.themeId` — agent-explicit per-render override
|
|
92
|
+
* 2. `App.defaultThemeId` — server-side per-app default
|
|
93
|
+
* 3. server fallback (process default)
|
|
94
|
+
* First non-undefined wins at bootstrap-meta projection.
|
|
104
95
|
*/
|
|
105
|
-
|
|
106
|
-
/** Capability permissions granted to this component */
|
|
107
|
-
capabilities?: CapabilityPermissions;
|
|
96
|
+
readonly themeId?: string;
|
|
108
97
|
/**
|
|
109
|
-
*
|
|
98
|
+
* Latest `HostContextProjection` echoed from the iframe-runtime via
|
|
99
|
+
* the live-channel `host_context_observed` message. Captured at
|
|
100
|
+
* iframe `ui/initialize` time + updated on every spec-defined
|
|
101
|
+
* `ui/notifications/host-context-changed` notification.
|
|
110
102
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
103
|
+
* Surfaced to the agent via `client.hostContext` on `ggui_handshake`
|
|
104
|
+
* and `ggui_consume` output so the agent can reason about device
|
|
105
|
+
* class, available display modes, and container dimensions.
|
|
106
|
+
*
|
|
107
|
+
* Absent ⇒ the iframe has not echoed a HostContext yet; agent falls
|
|
108
|
+
* back to ggui's `InterfaceContext`.
|
|
109
|
+
*/
|
|
110
|
+
readonly hostContext?: HostContextProjection;
|
|
111
|
+
/**
|
|
112
|
+
* Per-render Web Permissions API status map. Populated as the user
|
|
113
|
+
* grants / denies adapter requests (geolocation, camera, etc.) over
|
|
114
|
+
* the render's lifetime.
|
|
113
115
|
*/
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
116
|
+
readonly adapterPermissions?: AdapterPermissions;
|
|
117
|
+
/** Resolved lifecycle status. Absent ⇒ caller treats as `'active'`. */
|
|
118
|
+
readonly status?: RenderStatus;
|
|
119
|
+
/** Monotonic event ledger sequence (per-render — each Render has its
|
|
120
|
+
* own RenderEvent ledger). */
|
|
121
|
+
readonly eventSequence: number;
|
|
122
|
+
/** Creation timestamp (epoch ms). */
|
|
123
|
+
readonly createdAt: number;
|
|
124
|
+
/** Last activity timestamp (epoch ms). */
|
|
125
|
+
readonly lastActivityAt: number;
|
|
126
|
+
/** Expiry timestamp (epoch ms). */
|
|
127
|
+
readonly expiresAt: number;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* `Render` — the canonical protocol shape for a single rendered UI.
|
|
131
|
+
*
|
|
132
|
+
* Three variants share {@link RenderBase} (identity, tenancy,
|
|
133
|
+
* lifecycle); each variant adds its own visible-bits surface:
|
|
134
|
+
*
|
|
135
|
+
* - {@link ComponentRender} — LLM-generated / native React component.
|
|
136
|
+
* Carries `componentCode`, `propsSpec`, `actionSpec`, `streamSpec`,
|
|
137
|
+
* `contextSpec`, `gadgetDescriptors`, etc.
|
|
138
|
+
* - {@link SystemRender} — server-emitted system card. Carries an
|
|
139
|
+
* opaque `kind` + structured `props`; the runtime maps the kind to
|
|
140
|
+
* a built-in `.tsx` renderer.
|
|
141
|
+
* - {@link McpAppsRender} — embedded third-party MCP-App iframe.
|
|
142
|
+
* Carries `resourceUri` + MCP server config. (Lives in
|
|
143
|
+
* `@ggui-ai/protocol/integrations/mcp-apps` to keep core typing
|
|
144
|
+
* MCP-Apps-opt-in.)
|
|
145
|
+
*
|
|
146
|
+
* Narrowing pattern:
|
|
147
|
+
* ```ts
|
|
148
|
+
* if (render.type === 'mcpApps') {
|
|
149
|
+
* // McpAppsRender — render via host-role adapter
|
|
150
|
+
* } else if (render.type === 'system') {
|
|
151
|
+
* // SystemRender — render via built-in card registry
|
|
152
|
+
* } else {
|
|
153
|
+
* // ComponentRender — render via DynamicComponent
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export type Render<TProps = JsonObject> = ComponentRender<TProps> | SystemRender | McpAppsRender;
|
|
158
|
+
/**
|
|
159
|
+
* Render variant: LLM-generated / native React component.
|
|
160
|
+
*
|
|
161
|
+
* Discriminator: `type === 'component'` OR `type` absent (back-compat
|
|
162
|
+
* default — every producer that omits `type` is producing this variant).
|
|
163
|
+
*/
|
|
164
|
+
export interface ComponentRender<TProps = JsonObject> extends RenderBase {
|
|
165
|
+
/** Variant discriminator. Optional; absent ⇒ `'component'`. */
|
|
166
|
+
readonly type?: 'component';
|
|
167
|
+
/** Blueprint component code (pure UI). */
|
|
168
|
+
readonly componentCode: string;
|
|
169
|
+
/** Props passed to the component at render time. Carries
|
|
170
|
+
* request-specific data values (e.g., `{ city: 'Seoul', temperature: 15 }`). */
|
|
171
|
+
readonly props?: TProps;
|
|
172
|
+
/** The prompt that produced this component (when LLM-generated). */
|
|
173
|
+
readonly prompt?: string;
|
|
174
|
+
/** Human-readable description of what this component is. */
|
|
175
|
+
readonly description?: string;
|
|
176
|
+
/** Content type. Determines how `componentCode` is interpreted.
|
|
177
|
+
* Default: `'application/javascript+react'`. */
|
|
178
|
+
readonly contentType?: string;
|
|
179
|
+
/** Agent message to display while the component generates
|
|
180
|
+
* (thinking indicator). */
|
|
181
|
+
readonly message?: string;
|
|
182
|
+
/** JSON Schema for validating user-submitted form data. */
|
|
183
|
+
readonly schema?: JsonSchema;
|
|
184
|
+
/** Capability permissions granted to this component. */
|
|
185
|
+
readonly capabilities?: CapabilityPermissions;
|
|
186
|
+
/** Quality evaluation metadata. */
|
|
187
|
+
readonly quality?: QualityMetadata;
|
|
188
|
+
/** Generation error message (populated on failure). */
|
|
189
|
+
readonly error?: string;
|
|
190
|
+
/** Stream contract — describes what data the component accepts in
|
|
191
|
+
* real-time via `ggui_emit`. */
|
|
192
|
+
readonly streamSpec?: StreamSpec;
|
|
193
|
+
/** Props contract — initial render data interface
|
|
194
|
+
* (JSON Schema-based). */
|
|
195
|
+
readonly propsSpec?: PropsSpec;
|
|
196
|
+
/** Action contract — user interaction callbacks
|
|
197
|
+
* (JSON Schema-based). */
|
|
198
|
+
readonly actionSpec?: ActionSpec;
|
|
125
199
|
/** Context contract — observable client state surfaced to the agent's
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
contextSpec?: ContextSpec;
|
|
200
|
+
* LLM context via React Context Providers. */
|
|
201
|
+
readonly contextSpec?: ContextSpec;
|
|
129
202
|
/**
|
|
130
203
|
* Client capabilities catalog — declarative browser-capability gadget
|
|
131
|
-
* hook bindings carried alongside this
|
|
132
|
-
*
|
|
204
|
+
* hook bindings carried alongside this render. Mirrored verbatim from
|
|
205
|
+
* `DataContract.clientCapabilities` at `ggui_render` commit time.
|
|
133
206
|
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* resolves from `App.gadgets`). Resolution metadata (`version`,
|
|
140
|
-
* `bundleUrl`, `bundleSri`, `bundleHost`, `permission`, `connect`,
|
|
141
|
-
* `styleUrl`, ...) lives on the parallel
|
|
142
|
-
* {@link SessionStackEntry.gadgetDescriptors} sidecar — a filtered
|
|
143
|
-
* snapshot of `App.gadgets` covering only the descriptors referenced
|
|
144
|
-
* by this contract.
|
|
145
|
-
*
|
|
146
|
-
* Absent ⇒ no permissions requested (default-deny). Bootstrap omits
|
|
147
|
-
* `permissionsPolicy` and the public-render HTTP response sets no
|
|
148
|
-
* `Permissions-Policy` header beyond the host's own defaults.
|
|
207
|
+
* Package-keyed wire shape; identity (`package` + per-export `name`)
|
|
208
|
+
* preserved verbatim from the agent's render payload — no enrichment
|
|
209
|
+
* overlay, no `version` (resolves from `App.gadgets`). Resolution
|
|
210
|
+
* metadata lives on the parallel
|
|
211
|
+
* {@link ComponentRender.gadgetDescriptors} sidecar.
|
|
149
212
|
*/
|
|
150
|
-
clientCapabilities?: ClientCapabilitiesSpec;
|
|
213
|
+
readonly clientCapabilities?: ClientCapabilitiesSpec;
|
|
151
214
|
/**
|
|
152
|
-
* Descriptor sidecar
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* Snapshot at push-time; never re-resolved at render. Permissions-Policy
|
|
157
|
-
* + CSP + bundle-loader derivation read from this array (see
|
|
158
|
-
* `bootstrap-meta-derivation.ts`).
|
|
159
|
-
*
|
|
160
|
-
* Smaller than the full `App.gadgets` (~1-5KB typical); the full
|
|
161
|
-
* catalog stays recoverable from operator config if forensics need it.
|
|
162
|
-
*
|
|
163
|
-
* Omitted when `clientCapabilities` declares no gadgets.
|
|
215
|
+
* Descriptor sidecar — subset of `App.gadgets` containing exactly
|
|
216
|
+
* the descriptors referenced by `clientCapabilities`. Snapshot at
|
|
217
|
+
* render-commit time; never re-resolved at runtime. Permissions-Policy
|
|
218
|
+
* + CSP + bundle-loader derivation read from this array.
|
|
164
219
|
*/
|
|
165
|
-
gadgetDescriptors?: readonly GadgetDescriptor[];
|
|
220
|
+
readonly gadgetDescriptors?: readonly GadgetDescriptor[];
|
|
166
221
|
/**
|
|
167
222
|
* Last-known snapshot of the contextSpec slot values, mirrored from
|
|
168
|
-
* the runtime's `ui/update-model-context` posts via
|
|
169
|
-
*
|
|
170
|
-
*
|
|
223
|
+
* the runtime's `ui/update-model-context` posts via
|
|
224
|
+
* `ggui_runtime_sync_context`. Last-write-wins (REPLACE semantics,
|
|
225
|
+
* never merge).
|
|
171
226
|
*
|
|
172
227
|
* Resume contract — when chat-history rehydrate re-mounts the
|
|
173
228
|
* iframe, the resource handler seeds `contextSlots[i].default` with
|
|
174
229
|
* `contextSnapshot[name]` (when present) instead of the
|
|
175
|
-
* authoring-time default.
|
|
176
|
-
* user's interactive state (typed text, counter values, toggle
|
|
177
|
-
* positions); with it, the user sees their last-known state.
|
|
230
|
+
* authoring-time default.
|
|
178
231
|
*
|
|
179
232
|
* Absent on initial render until the first context-update fires
|
|
180
|
-
* from the runtime.
|
|
181
|
-
* (`deriveStackItemBootstrapView`) gracefully falls back to
|
|
182
|
-
* `entry.default` per slot when this field is absent.
|
|
233
|
+
* from the runtime.
|
|
183
234
|
*/
|
|
184
|
-
contextSnapshot?: JsonObject;
|
|
185
|
-
createdAt: string;
|
|
235
|
+
readonly contextSnapshot?: JsonObject;
|
|
186
236
|
}
|
|
187
237
|
/**
|
|
188
|
-
*
|
|
189
|
-
* components. The wire is open-ended (string), but new kinds without a
|
|
190
|
-
* matching renderer fall through to a generic "system message" card so
|
|
191
|
-
* an old runtime + new server still produce something visible.
|
|
192
|
-
*/
|
|
193
|
-
export type SystemStackItemKind = 'no-credentials' | 'mcp-apps-probe' | (string & {});
|
|
194
|
-
/**
|
|
195
|
-
* Stack item — server-emitted system card.
|
|
196
|
-
*
|
|
197
|
-
* The third StackItem variant. Used when the SERVER (not an LLM, not
|
|
198
|
-
* an MCP host) needs to render a UI card the operator can act on:
|
|
199
|
-
* "set up your LLM key", "rate limited, try later", "server is
|
|
200
|
-
* misconfigured", etc.
|
|
238
|
+
* Render variant: server-emitted system card.
|
|
201
239
|
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
* bypasses TS, lint, and design-system co-evolution, and forces server
|
|
206
|
-
* code to hand-emit `React.createElement` calls. The system variant
|
|
207
|
-
* carries an opaque `kind` + structured `props`; the runtime maps the
|
|
208
|
-
* kind to a real `.tsx` component bundled inside it.
|
|
240
|
+
* Used when the SERVER (not an LLM, not an MCP host) needs to render
|
|
241
|
+
* a UI card the operator can act on: "set up your LLM key", "rate
|
|
242
|
+
* limited, try later", "server is misconfigured", etc.
|
|
209
243
|
*
|
|
210
244
|
* Wire shape is intentionally tiny — server emits identifier + data,
|
|
211
|
-
* not code.
|
|
245
|
+
* not code. The runtime maps `kind` to a built-in `.tsx` component.
|
|
212
246
|
*/
|
|
213
|
-
export interface
|
|
214
|
-
|
|
215
|
-
type: 'system';
|
|
247
|
+
export interface SystemRender<TProps extends JsonObject = JsonObject> extends RenderBase {
|
|
248
|
+
readonly type: 'system';
|
|
216
249
|
/**
|
|
217
250
|
* Identifier the runtime maps to a built-in renderer. Stable strings
|
|
218
251
|
* (kebab-case) that survive runtime version skew — adding a new kind
|
|
219
252
|
* never breaks an older runtime; it just falls through to a generic
|
|
220
253
|
* card carrying the props as raw JSON.
|
|
221
254
|
*/
|
|
222
|
-
kind:
|
|
255
|
+
readonly kind: SystemRenderKind;
|
|
223
256
|
/** Props forwarded to the built-in renderer. */
|
|
224
|
-
props?: TProps;
|
|
257
|
+
readonly props?: TProps;
|
|
225
258
|
/** Optional descriptive text the server can attach (telemetry, logs). */
|
|
226
|
-
description?: string;
|
|
227
|
-
createdAt: string;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Canonical session-stack entry — discriminated union over the three
|
|
231
|
-
* stack-item variants ggui supports:
|
|
232
|
-
*
|
|
233
|
-
* - {@link StackItem} — generated / native component (has
|
|
234
|
-
* `componentCode`, `actionSpec`, `streamSpec`, etc.).
|
|
235
|
-
* - {@link McpAppsStackItem} — embedded third-party MCP App iframe.
|
|
236
|
-
* - {@link SystemStackItem} — server-emitted system card (carries a
|
|
237
|
-
* stable `kind` + props; runtime renders via a built-in
|
|
238
|
-
* component).
|
|
239
|
-
*
|
|
240
|
-
* Narrowing pattern:
|
|
241
|
-
* ```ts
|
|
242
|
-
* if (entry.type === 'mcpApps') {
|
|
243
|
-
* // McpAppsStackItem — render via host-role adapter
|
|
244
|
-
* } else if (entry.type === 'system') {
|
|
245
|
-
* // SystemStackItem — render via built-in card registry
|
|
246
|
-
* } else {
|
|
247
|
-
* // StackItem — render via DynamicComponent
|
|
248
|
-
* }
|
|
249
|
-
* ```
|
|
250
|
-
*
|
|
251
|
-
* Or use the {@link isMcpAppsStackItem} / component helpers exported
|
|
252
|
-
* from `@ggui-ai/protocol/integrations/mcp-apps`.
|
|
253
|
-
*/
|
|
254
|
-
export type SessionStackEntry<TProps = JsonObject> = StackItem<TProps> | McpAppsStackItem | SystemStackItem;
|
|
255
|
-
/**
|
|
256
|
-
* Adapter permission status
|
|
257
|
-
*/
|
|
258
|
-
export type PermissionStatus = 'granted' | 'denied' | 'prompt';
|
|
259
|
-
/**
|
|
260
|
-
* Adapter permissions — per-session map keyed by Web Permissions API
|
|
261
|
-
* name (see `KNOWN_PERMISSION_NAMES` in `validation/hygiene-rules.ts`).
|
|
262
|
-
*
|
|
263
|
-
* Keys derive from `KNOWN_PERMISSION_NAMES` so there's one source of
|
|
264
|
-
* truth for permission identifiers across the protocol surface
|
|
265
|
-
* (schema validation, hygiene rules, and runtime SDK cache).
|
|
266
|
-
*
|
|
267
|
-
* Pre-launch posture: no backward-compat alias for the old field
|
|
268
|
-
* names — every consumer reads/writes through the runtime SDK
|
|
269
|
-
* `requestPermission` call, which itself is gated against the same
|
|
270
|
-
* enum.
|
|
271
|
-
*/
|
|
272
|
-
export type AdapterPermissions = {
|
|
273
|
-
readonly [K in (typeof KNOWN_PERMISSION_NAMES)[number]]?: PermissionStatus;
|
|
274
|
-
};
|
|
275
|
-
/**
|
|
276
|
-
* Session state (internal — includes implementation details like connectionId)
|
|
277
|
-
*/
|
|
278
|
-
export interface Session {
|
|
279
|
-
id: string;
|
|
280
|
-
appId: string;
|
|
281
|
-
connectionId?: string;
|
|
282
|
-
userId?: string;
|
|
283
|
-
/** Full authenticated end-user identity (populated after auth gate) */
|
|
284
|
-
endUserIdentity?: EndUserIdentity;
|
|
285
|
-
/**
|
|
286
|
-
* Theme preset id for this chat-scoped session. Set on
|
|
287
|
-
* `ggui_new_session` from the agent's explicit `themeId` input or
|
|
288
|
-
* the per-app `App.defaultThemeId` default. Read at every
|
|
289
|
-
* `ggui_push` commit so the bootstrap-meta projection can resolve
|
|
290
|
-
* the layered theme chain (see {@link StackItem.themeId} for the
|
|
291
|
-
* full ordering). Absent ⇒ the chain falls through to the app /
|
|
292
|
-
* server default at render time.
|
|
293
|
-
*/
|
|
294
|
-
themeId?: string;
|
|
295
|
-
stack: SessionStackEntry[];
|
|
296
|
-
currentStackIndex: number;
|
|
297
|
-
adapterPermissions: AdapterPermissions;
|
|
298
|
-
eventSequence: number;
|
|
299
|
-
createdAt: number;
|
|
300
|
-
lastActivityAt: number;
|
|
301
|
-
expiresAt: number;
|
|
302
|
-
/**
|
|
303
|
-
* Resolved session lifecycle status. SessionStore implementations
|
|
304
|
-
* MAY populate this on `get` (e.g. InMemory + Sqlite compute from
|
|
305
|
-
* internal `closed` flag + `expiresAt`; cloud Dynamo reads
|
|
306
|
-
* `sessionStatus` row column). Absent = caller treats as
|
|
307
|
-
* `'active'` — the legacy default for stores that don't surface
|
|
308
|
-
* lifecycle state.
|
|
309
|
-
*/
|
|
310
|
-
status?: 'active' | 'completed' | 'expired';
|
|
311
|
-
/**
|
|
312
|
-
* Latest `HostContextProjection` echoed from the iframe-runtime via
|
|
313
|
-
* the live-channel `host_context_observed` message. Captured at iframe
|
|
314
|
-
* `ui/initialize` time + updated on every spec-defined
|
|
315
|
-
* `ui/notifications/host-context-changed` notification.
|
|
316
|
-
*
|
|
317
|
-
* Surfaced to the agent via `client.hostContext` on `ggui_handshake`
|
|
318
|
-
* and `ggui_consume` output so the agent can reason about device
|
|
319
|
-
* class, available display modes, and container dimensions on each
|
|
320
|
-
* turn..
|
|
321
|
-
*
|
|
322
|
-
* Absent ⇒ the iframe has not echoed a HostContext yet (first push
|
|
323
|
-
* before iframe mount, or non-spec-compliant host that doesn't
|
|
324
|
-
* supply `McpUiHostContext`). Agent falls back to ggui's own
|
|
325
|
-
* `InterfaceContext` in that case.
|
|
326
|
-
*/
|
|
327
|
-
hostContext?: HostContextProjection;
|
|
328
|
-
/**
|
|
329
|
-
* Resolved MCP-Apps presentation mode for this session. Persisted at
|
|
330
|
-
* `ggui_new_session` time from the app config's `defaultMcpAppsMode`
|
|
331
|
-
* so mid-session app-config changes don't disrupt live sessions.
|
|
332
|
-
*
|
|
333
|
-
* - `'inline'` (default): each `ggui_push` returns its own ui://
|
|
334
|
-
* resource. Today's behavior.
|
|
335
|
-
* - `'canvas'`: a session-scoped iframe was minted by
|
|
336
|
-
* `ggui_new_session`. `ggui_push` delivers via live-channel WS once
|
|
337
|
-
* the canvas iframe completes its `ui/initialize` handshake (see
|
|
338
|
-
* {@link canvasLoaded}).
|
|
339
|
-
*
|
|
340
|
-
* Absent ⇒ `'inline'` (zero-config default for legacy sessions).
|
|
341
|
-
*
|
|
342
|
-
*/
|
|
343
|
-
mcpAppsMode?: McpAppsMode;
|
|
344
|
-
/**
|
|
345
|
-
* Set to `true` when the canvas iframe (for `mcpAppsMode === 'canvas'`
|
|
346
|
-
* sessions) has completed its `ui/initialize` handshake AND opened
|
|
347
|
-
* its live-channel subscription. Read by `ggui_push` to decide whether
|
|
348
|
-
* to deliver state via WS (canvas loaded) or return a per-push
|
|
349
|
-
* resource (canvas not yet loaded → fallback to inline-style
|
|
350
|
-
* delivery for that single push).
|
|
351
|
-
*
|
|
352
|
-
* Always undefined / false for `mcpAppsMode === 'inline'` sessions.
|
|
353
|
-
*
|
|
354
|
-
*/
|
|
355
|
-
canvasLoaded?: boolean;
|
|
356
|
-
/**
|
|
357
|
-
* Currently-active stack item id from the canvas's user nav stack.
|
|
358
|
-
* Updated server-side on every `canvas_navigated` envelope from the
|
|
359
|
-
* iframe. Drives `ggui_consume`'s active-pipe resolution (consumer
|
|
360
|
-
* picks events targeting the active item, ignoring background
|
|
361
|
-
* cold-gen for items the user has navigated away from) and gates
|
|
362
|
-
* which in-flight `runGeneration` AbortSignals should fire.
|
|
363
|
-
*
|
|
364
|
-
* Distinct from `currentStackIndex`: that field tracks the SERVER's
|
|
365
|
-
* stack mutation cursor (last push location); this tracks the
|
|
366
|
-
* USER's navigation focus. They can diverge when the agent pushes
|
|
367
|
-
* item C while the user is on item B — currentStackIndex points
|
|
368
|
-
* to C, activeStackItemId stays B.
|
|
369
|
-
*
|
|
370
|
-
* Absent for inline sessions + the first push of a canvas session
|
|
371
|
-
* before any `canvas_navigated` lands..
|
|
372
|
-
*/
|
|
373
|
-
activeStackItemId?: string;
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Session view — clean protocol representation (no internal fields).
|
|
377
|
-
* This is what agents see via getSession.
|
|
378
|
-
*/
|
|
379
|
-
export interface SessionView {
|
|
380
|
-
id: string;
|
|
381
|
-
appId: string;
|
|
382
|
-
status: 'active' | 'completed' | 'expired';
|
|
383
|
-
stack: SessionStackEntry[];
|
|
384
|
-
currentStackIndex: number;
|
|
385
|
-
eventSequence: number;
|
|
386
|
-
endUserIdentity?: EndUserIdentity;
|
|
387
|
-
adapterPermissions?: AdapterPermissions;
|
|
388
|
-
createdAt: string;
|
|
389
|
-
lastActivityAt: string;
|
|
390
|
-
expiresAt: string;
|
|
259
|
+
readonly description?: string;
|
|
391
260
|
}
|
|
392
261
|
/**
|
|
393
262
|
* A single turn in the agent-user conversation.
|
|
394
|
-
* Platforms SHOULD record conversation turns automatically and forward
|
|
263
|
+
* Platforms SHOULD record conversation turns automatically and forward
|
|
264
|
+
* them to agents.
|
|
395
265
|
*
|
|
396
|
-
* Generic `TToolArgs` defaults to {@link JsonObject} for the tool call
|
|
266
|
+
* Generic `TToolArgs` defaults to {@link JsonObject} for the tool call
|
|
267
|
+
* arguments type.
|
|
397
268
|
*/
|
|
398
269
|
export interface ConversationTurn<TToolArgs = JsonObject> {
|
|
399
270
|
role: 'user' | 'agent';
|
|
@@ -407,10 +278,13 @@ export interface ConversationTurn<TToolArgs = JsonObject> {
|
|
|
407
278
|
/**
|
|
408
279
|
* Progress update emitted by a producer during component production.
|
|
409
280
|
* Delivered via the `ggui:logs` bridge event.
|
|
281
|
+
*
|
|
282
|
+
* Post-Phase-B: collapsed from `{ sessionId, stackItemId }` to a single
|
|
283
|
+
* `renderId` (the two identifiers were the same value once each render
|
|
284
|
+
* was its own thing).
|
|
410
285
|
*/
|
|
411
286
|
export interface ProgressUpdate {
|
|
412
|
-
|
|
413
|
-
stackItemId: string;
|
|
287
|
+
renderId: string;
|
|
414
288
|
step: 'queued' | 'negotiating' | 'matching' | 'generating' | 'compiling' | 'evaluating' | 'complete' | 'error';
|
|
415
289
|
label: string;
|
|
416
290
|
percent: number;
|