oui-spec 0.2.0 → 0.3.0

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.
Files changed (63) hide show
  1. package/README.md +94 -122
  2. package/dist/{chunk-CVUUSPF4.js → chunk-BMCL2K74.js} +2 -2
  3. package/dist/chunk-BMCL2K74.js.map +1 -0
  4. package/dist/{chunk-MTMEW6MM.cjs → chunk-DCVVTP3V.cjs} +72 -23
  5. package/dist/chunk-DCVVTP3V.cjs.map +1 -0
  6. package/dist/chunk-F3SKRAGU.cjs +98 -0
  7. package/dist/chunk-F3SKRAGU.cjs.map +1 -0
  8. package/dist/{chunk-YDMGV72W.js → chunk-F3WKIRAU.js} +72 -23
  9. package/dist/chunk-F3WKIRAU.js.map +1 -0
  10. package/dist/chunk-IIZ6HL2L.js +89 -0
  11. package/dist/chunk-IIZ6HL2L.js.map +1 -0
  12. package/dist/chunk-KNWGQRXL.cjs +567 -0
  13. package/dist/chunk-KNWGQRXL.cjs.map +1 -0
  14. package/dist/chunk-NYCJZQSP.js +92 -0
  15. package/dist/chunk-NYCJZQSP.js.map +1 -0
  16. package/dist/chunk-ROGKEMLL.cjs +91 -0
  17. package/dist/chunk-ROGKEMLL.cjs.map +1 -0
  18. package/dist/chunk-TRNVXAB5.js +563 -0
  19. package/dist/chunk-TRNVXAB5.js.map +1 -0
  20. package/dist/{chunk-3DCIL4FV.cjs → chunk-ZKM4XWAB.cjs} +2 -2
  21. package/dist/chunk-ZKM4XWAB.cjs.map +1 -0
  22. package/dist/core/index.cjs +10 -6
  23. package/dist/core/index.d.cts +15 -8
  24. package/dist/core/index.d.ts +15 -8
  25. package/dist/core/index.js +3 -3
  26. package/dist/index.cjs +28 -12
  27. package/dist/index.d.cts +5 -4
  28. package/dist/index.d.ts +5 -4
  29. package/dist/index.js +5 -5
  30. package/dist/react/index.cjs +15 -3
  31. package/dist/react/index.d.cts +33 -50
  32. package/dist/react/index.d.ts +33 -50
  33. package/dist/react/index.js +1 -1
  34. package/dist/spec/index.cjs +2 -2
  35. package/dist/spec/index.d.cts +35 -7
  36. package/dist/spec/index.d.ts +35 -7
  37. package/dist/spec/index.js +1 -1
  38. package/dist/{define-surface-D6XPtoqu.d.cts → surface-runtime--2lZGB7Z.d.cts} +92 -2
  39. package/dist/{define-surface-DXBop-uB.d.ts → surface-runtime-Dj_nhd7r.d.ts} +92 -2
  40. package/dist/transport/index.cjs +4 -4
  41. package/dist/transport/index.d.cts +2 -2
  42. package/dist/transport/index.d.ts +2 -2
  43. package/dist/transport/index.js +2 -2
  44. package/dist/{websocket-CrI0yRNo.d.cts → websocket-YfWILdZ4.d.cts} +36 -18
  45. package/dist/{websocket-CiWvkaz_.d.ts → websocket-c5tIUWY5.d.ts} +36 -18
  46. package/package.json +5 -1
  47. package/spec/OUI-SPEC-v0.1.md +229 -155
  48. package/dist/chunk-2ON5IEXB.cjs +0 -167
  49. package/dist/chunk-2ON5IEXB.cjs.map +0 -1
  50. package/dist/chunk-3DCIL4FV.cjs.map +0 -1
  51. package/dist/chunk-5TQ6AVQH.cjs +0 -108
  52. package/dist/chunk-5TQ6AVQH.cjs.map +0 -1
  53. package/dist/chunk-CVUUSPF4.js.map +0 -1
  54. package/dist/chunk-HK7OXB2W.cjs +0 -157
  55. package/dist/chunk-HK7OXB2W.cjs.map +0 -1
  56. package/dist/chunk-ILUTAHUJ.js +0 -154
  57. package/dist/chunk-ILUTAHUJ.js.map +0 -1
  58. package/dist/chunk-MTMEW6MM.cjs.map +0 -1
  59. package/dist/chunk-O6EI77LD.js +0 -106
  60. package/dist/chunk-O6EI77LD.js.map +0 -1
  61. package/dist/chunk-UIGRLZOX.js +0 -164
  62. package/dist/chunk-UIGRLZOX.js.map +0 -1
  63. package/dist/chunk-YDMGV72W.js.map +0 -1
@@ -10,5 +10,5 @@ var OUI_PROTOCOL_EVENTS = {
10
10
  };
11
11
 
12
12
  exports.OUI_PROTOCOL_EVENTS = OUI_PROTOCOL_EVENTS;
13
- //# sourceMappingURL=chunk-3DCIL4FV.cjs.map
14
- //# sourceMappingURL=chunk-3DCIL4FV.cjs.map
13
+ //# sourceMappingURL=chunk-ZKM4XWAB.cjs.map
14
+ //# sourceMappingURL=chunk-ZKM4XWAB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/spec/types.ts"],"names":[],"mappings":";;;AAiUO,IAAM,mBAAA,GAAsB;AAAA,EACjC,gBAAA,EAAkB,kBAAA;AAAA,EAClB,kBAAA,EAAoB,oBAAA;AAAA,EACpB,cAAA,EAAgB,gBAAA;AAAA,EAChB,aAAA,EAAe,eAAA;AAAA,EACf,kBAAA,EAAoB;AACtB","file":"chunk-ZKM4XWAB.cjs","sourcesContent":["/**\n * OUI — Open UI Specification\n *\n * The machine-readable contract for agent-controllable user interfaces.\n * Any UI application that implements this interface can be controlled by\n * any OUI-compatible agent runtime.\n */\n\n/** JSON Schema type (subset used by OUI) */\nexport type JSONSchema = {\n type?: string | string[];\n properties?: Record<string, JSONSchema>;\n items?: JSONSchema;\n required?: string[];\n enum?: (string | number | boolean)[];\n description?: string;\n default?: unknown;\n oneOf?: JSONSchema[];\n anyOf?: JSONSchema[];\n allOf?: JSONSchema[];\n const?: unknown;\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n format?: string;\n additionalProperties?: boolean | JSONSchema;\n};\n\n/**\n * A Surface is a controllable boundary within an application.\n * It declares what an agent can do (actions), what it can observe (state),\n * and when it's available (activation conditions).\n *\n * Think of it as \"one page\" or \"one feature\" of an application, described\n * in a way that an agent can understand and operate.\n */\nexport interface OUISurface {\n /** Unique identifier for this surface (e.g., 'dataviz-wizard', 'document-editor') */\n id: string;\n\n /** Human-readable name */\n name: string;\n\n /** Description of what this surface does — included in agent context */\n description: string;\n\n /** Version of this surface's contract (semver) */\n version?: string;\n\n /** Actions the agent can invoke on this surface */\n actions: OUIAction[];\n\n /** Observable state the agent can read */\n observations?: OUIObservation[];\n\n /** When this surface is active/available */\n activation?: OUIActivation;\n\n /** Additional metadata for agent context */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Declarative polling configuration for async actions.\n * The OUI runtime in the browser manages the polling lifecycle automatically\n * after the action handler returns its dispatch result.\n */\nexport interface OUIActionPolling {\n /** How often to check (milliseconds) */\n intervalMs: number;\n\n /** Max poll attempts before giving up (optional) */\n maxAttempts?: number;\n\n /** Max total duration before giving up in ms (alternative to maxAttempts) */\n maxDurationMs?: number;\n\n /**\n * Subscribe to a realtime event instead of polling.\n * If provided, the runtime listens for this event instead of using setInterval.\n * More efficient when realtime infrastructure exists.\n */\n subscribe?: {\n /** Event name to listen for */\n event: string;\n /**\n * Filter to match the event. Values prefixed with '$dispatchResult.'\n * are resolved from the handler's return value.\n * Example: { jobId: '$dispatchResult.jobId' }\n */\n filter?: Record<string, unknown>;\n };\n}\n\n/**\n * An Action is a single operation an agent can perform on a surface.\n * Each action becomes a \"tool\" that the LLM can call.\n *\n * The action's handler executes in the UI (or API) and returns a result\n * that the agent sees as the tool's output.\n */\nexport interface OUIAction {\n /** Unique action identifier (becomes the tool name) */\n id: string;\n\n /** Human-readable description — this is what the LLM reads to decide when to use it */\n description: string;\n\n /** JSON Schema for the action's input parameters */\n input: JSONSchema;\n\n /** JSON Schema for the action's return value (optional — agent still gets the result) */\n output?: JSONSchema;\n\n /** If true, the agent runtime should confirm with the user before executing */\n confirm?: boolean;\n\n /** If true, the action is async — returns immediately with a job/tracking ID */\n async?: boolean;\n\n /** Declarative polling configuration — runtime manages the polling lifecycle after dispatch */\n polling?: OUIActionPolling;\n\n /** Human-readable hint about when this action is appropriate to use */\n usage?: string;\n\n /**\n * Preconditions that should be met before this action is called.\n * Expressed as a description (for the LLM) not as executable logic.\n */\n preconditions?: string;\n\n /** Estimated duration hint (e.g., \"instant\", \"2-5s\", \"30-120s\") */\n estimatedDuration?: string;\n\n /** Tags for categorization */\n tags?: string[];\n}\n\n/**\n * An Observation is a piece of application state that the agent can read.\n * Observations are pushed to the agent in real-time as the app state changes,\n * giving it situational awareness without needing screenshots.\n */\nexport interface OUIObservation {\n /** Unique identifier for this observation */\n id: string;\n\n /** Description of what this observation represents */\n description: string;\n\n /** JSON Schema for the observation's value */\n schema: JSONSchema;\n\n /** How frequently this observation updates */\n updateFrequency?: \"realtime\" | \"on-change\" | \"polling\";\n}\n\n/**\n * Activation conditions — when a surface is available to the agent.\n * A surface might only be active on a specific page, when certain\n * entities are loaded, or under specific application states.\n */\nexport interface OUIActivation {\n /** URL path(s) where this surface is active */\n routes?: string | string[];\n\n /** Entity type/ID that must be present for this surface to activate */\n entity?: {\n type: string;\n id?: string;\n };\n\n /** Custom predicate description (for documentation, not execution) */\n condition?: string;\n}\n\n// ─── Protocol Types ──────────────────────────────────────────────────────────\n\n/**\n * A request from the agent runtime to execute an action on a surface.\n */\nexport interface OUIActionRequest {\n /** Unique request ID for correlation */\n requestId: string;\n\n /** Which surface this request targets */\n surfaceId: string;\n\n /** Which action to invoke */\n actionId: string;\n\n /** The action's input parameters (validated against the action's input schema) */\n params: Record<string, unknown>;\n\n /** Timestamp of the request */\n timestamp: number;\n}\n\n/**\n * The result of an action execution, returned from the surface to the agent.\n */\nexport interface OUIActionResult {\n /** Correlates to the request */\n requestId: string;\n\n /** Whether the action succeeded */\n success: boolean;\n\n /** The action's return data (if successful) */\n data?: unknown;\n\n /** Error information (if failed) */\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n\n /** Progress indicator for interim polling results (0-100) */\n progress?: number;\n\n /** Whether this is an interim update (polling still in progress) or final */\n interim?: boolean;\n\n /** Duration of execution in milliseconds */\n durationMs?: number;\n\n /** Timestamp of the result */\n timestamp: number;\n\n /**\n * The surfaces active on the client once the action's effects settled.\n *\n * An action can change what the agent is able to do next: navigating\n * unmounts one page's surfaces and mounts another's. Without this, the agent\n * would act on the capability set it had before the action, which is the\n * set the action just replaced.\n */\n surfaces?: OUISurface[];\n\n /** Latest observation values per surface once the action's effects settled. */\n observations?: OUIObservationSnapshot;\n\n /**\n * False when the client's deadline passed before its UI settled, so\n * `surfaces` and `observations` may still be changing. Absent or true\n * otherwise.\n */\n settled?: boolean;\n}\n\n/** Latest observation values, keyed by surface id and then observation id. */\nexport type OUIObservationSnapshot = Record<string, Record<string, unknown>>;\n\n/**\n * What a client can do right now: the surfaces it has mounted and their latest\n * observation values. A client sends this to its agent runtime (for example,\n * with each turn), and returns it on every action result.\n */\nexport interface OUISurfaceSnapshot {\n surfaces: OUISurface[];\n observations: OUIObservationSnapshot;\n}\n\n/**\n * An observation update pushed from the surface to the agent.\n */\nexport interface OUIObservationUpdate {\n /** Which surface this observation belongs to */\n surfaceId: string;\n\n /** Which observation updated */\n observationId: string;\n\n /** The new value */\n value: unknown;\n\n /** Timestamp of the update */\n timestamp: number;\n}\n\n/**\n * Surface registration event — sent when a surface becomes active.\n */\nexport interface OUISurfaceRegistration {\n /** The full surface manifest */\n surface: OUISurface;\n\n /** Timestamp of registration */\n timestamp: number;\n}\n\n/**\n * Surface deregistration event — sent when a surface becomes inactive.\n */\nexport interface OUISurfaceDeregistration {\n /** Which surface is being deregistered */\n surfaceId: string;\n\n /** Timestamp */\n timestamp: number;\n}\n\n// ─── Transport Protocol Events ───────────────────────────────────────────────\n\n/**\n * All protocol events exchanged between agent runtime and surfaces.\n */\nexport type OUIProtocolEvent =\n | { type: \"surface:register\"; payload: OUISurfaceRegistration }\n | { type: \"surface:deregister\"; payload: OUISurfaceDeregistration }\n | { type: \"action:request\"; payload: OUIActionRequest }\n | { type: \"action:result\"; payload: OUIActionResult }\n | { type: \"observation:update\"; payload: OUIObservationUpdate };\n\n/**\n * Protocol event type strings (for type guards and routing).\n */\nexport const OUI_PROTOCOL_EVENTS = {\n SURFACE_REGISTER: \"surface:register\",\n SURFACE_DEREGISTER: \"surface:deregister\",\n ACTION_REQUEST: \"action:request\",\n ACTION_RESULT: \"action:result\",\n OBSERVATION_UPDATE: \"observation:update\",\n} as const;\n"]}
@@ -1,22 +1,26 @@
1
1
  'use strict';
2
2
 
3
- var chunkHK7OXB2W_cjs = require('../chunk-HK7OXB2W.cjs');
4
- var chunk3DCIL4FV_cjs = require('../chunk-3DCIL4FV.cjs');
5
- require('../chunk-MTMEW6MM.cjs');
3
+ var chunkKNWGQRXL_cjs = require('../chunk-KNWGQRXL.cjs');
4
+ var chunkZKM4XWAB_cjs = require('../chunk-ZKM4XWAB.cjs');
5
+ require('../chunk-DCVVTP3V.cjs');
6
6
 
7
7
 
8
8
 
9
9
  Object.defineProperty(exports, "createOUI", {
10
10
  enumerable: true,
11
- get: function () { return chunkHK7OXB2W_cjs.createOUI; }
11
+ get: function () { return chunkKNWGQRXL_cjs.createOUI; }
12
+ });
13
+ Object.defineProperty(exports, "createSurfaceRuntime", {
14
+ enumerable: true,
15
+ get: function () { return chunkKNWGQRXL_cjs.createSurfaceRuntime; }
12
16
  });
13
17
  Object.defineProperty(exports, "defineSurface", {
14
18
  enumerable: true,
15
- get: function () { return chunkHK7OXB2W_cjs.defineSurface; }
19
+ get: function () { return chunkKNWGQRXL_cjs.defineSurface; }
16
20
  });
17
21
  Object.defineProperty(exports, "OUI_PROTOCOL_EVENTS", {
18
22
  enumerable: true,
19
- get: function () { return chunk3DCIL4FV_cjs.OUI_PROTOCOL_EVENTS; }
23
+ get: function () { return chunkZKM4XWAB_cjs.OUI_PROTOCOL_EVENTS; }
20
24
  });
21
25
  //# sourceMappingURL=index.cjs.map
22
26
  //# sourceMappingURL=index.cjs.map
@@ -1,8 +1,8 @@
1
1
  import { OUISurface } from '../spec/index.cjs';
2
- export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationUpdate, OUIProtocolEvent, OUISurfaceDeregistration, OUISurfaceRegistration, OUI_PROTOCOL_EVENTS } from '../spec/index.cjs';
3
- import { D as DefinedSurface, O as OUIBranded } from '../define-surface-D6XPtoqu.cjs';
4
- export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, c as ObservationDefinition, S as SurfaceDefinition, d as defineSurface } from '../define-surface-D6XPtoqu.cjs';
5
- import { S as SocketLike, c as OUITransportConfig, b as OUITransport } from '../websocket-CrI0yRNo.cjs';
2
+ export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationSnapshot, OUIObservationUpdate, OUIProtocolEvent, OUISurfaceDeregistration, OUISurfaceRegistration, OUISurfaceSnapshot, OUI_PROTOCOL_EVENTS } from '../spec/index.cjs';
3
+ import { D as DefinedSurface, O as OUIBranded } from '../surface-runtime--2lZGB7Z.cjs';
4
+ export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, M as MountedSurface, c as ObservationDefinition, S as SettleOptions, d as SurfaceDefinition, e as SurfaceRuntime, f as SurfaceRuntimeOptions, g as createSurfaceRuntime, h as defineSurface } from '../surface-runtime--2lZGB7Z.cjs';
5
+ import { S as SocketLike, d as OUITransportConfig, c as OUITransport } from '../websocket-YfWILdZ4.cjs';
6
6
 
7
7
  /**
8
8
  * Compile-time validation for a createOUI configuration.
@@ -49,7 +49,11 @@ type IsEmpty<T extends readonly unknown[]> = T extends readonly [] ? true : fals
49
49
  type ValidateSurfaceIds<TIds extends readonly string[]> = IsEmpty<TIds> extends true ? OUIConfigError<"createOUI requires at least one surface. An instance with no surfaces registers nothing and dispatches nowhere."> : [DuplicateIds<TIds>] extends [never] ? unknown : OUIConfigError<`Duplicate surface id: "${DuplicateIds<TIds>}". Surface registration is keyed by id, so the second would silently replace the first.`>;
50
50
 
51
51
  /**
52
- * createOUI — the only supported way to instantiate OUI.
52
+ * createOUI — a fixed set of surfaces announced over one socket.
53
+ *
54
+ * For a client whose surfaces come and go (a React app, where a page's
55
+ * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps
56
+ * the client's own record of what is mounted and answers every request.
53
57
  *
54
58
  * WHY THIS EXISTS
55
59
  *
@@ -72,8 +76,8 @@ type ValidateSurfaceIds<TIds extends readonly string[]> = IsEmpty<TIds> extends
72
76
  * transport, because `OUITransport` values are branded and only this module
73
77
  * brands them.
74
78
  *
75
- * OUI owns the result path. Results return through the observation channel,
76
- * as `use-surface` already implements. An integrator cannot add a parallel
79
+ * OUI owns the result path. Every dispatch carries a requestId and is
80
+ * answered on OUI's result channel. An integrator cannot add a parallel
77
81
  * channel because it cannot construct a transport to add one to.
78
82
  *
79
83
  * The integrator owns content. Surfaces, action schemas, observation schemas
@@ -117,7 +121,10 @@ interface OUIInstance {
117
121
  readonly manifests: readonly OUISurface[];
118
122
  /** Register every surface and connect. */
119
123
  start(): Promise<void>;
120
- /** Deregister every surface and disconnect. */
124
+ /**
125
+ * Deregister every surface and detach OUI from the socket. The socket stays
126
+ * connected: the integrator owns it, and other code may share it.
127
+ */
121
128
  stop(): void;
122
129
  /** Look up a registered surface by id. */
123
130
  getSurface(id: string): DefinedSurface<never> | undefined;
@@ -1,8 +1,8 @@
1
1
  import { OUISurface } from '../spec/index.js';
2
- export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationUpdate, OUIProtocolEvent, OUISurfaceDeregistration, OUISurfaceRegistration, OUI_PROTOCOL_EVENTS } from '../spec/index.js';
3
- import { D as DefinedSurface, O as OUIBranded } from '../define-surface-DXBop-uB.js';
4
- export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, c as ObservationDefinition, S as SurfaceDefinition, d as defineSurface } from '../define-surface-DXBop-uB.js';
5
- import { S as SocketLike, c as OUITransportConfig, b as OUITransport } from '../websocket-CiWvkaz_.js';
2
+ export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationSnapshot, OUIObservationUpdate, OUIProtocolEvent, OUISurfaceDeregistration, OUISurfaceRegistration, OUISurfaceSnapshot, OUI_PROTOCOL_EVENTS } from '../spec/index.js';
3
+ import { D as DefinedSurface, O as OUIBranded } from '../surface-runtime-Dj_nhd7r.js';
4
+ export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, M as MountedSurface, c as ObservationDefinition, S as SettleOptions, d as SurfaceDefinition, e as SurfaceRuntime, f as SurfaceRuntimeOptions, g as createSurfaceRuntime, h as defineSurface } from '../surface-runtime-Dj_nhd7r.js';
5
+ import { S as SocketLike, d as OUITransportConfig, c as OUITransport } from '../websocket-c5tIUWY5.js';
6
6
 
7
7
  /**
8
8
  * Compile-time validation for a createOUI configuration.
@@ -49,7 +49,11 @@ type IsEmpty<T extends readonly unknown[]> = T extends readonly [] ? true : fals
49
49
  type ValidateSurfaceIds<TIds extends readonly string[]> = IsEmpty<TIds> extends true ? OUIConfigError<"createOUI requires at least one surface. An instance with no surfaces registers nothing and dispatches nowhere."> : [DuplicateIds<TIds>] extends [never] ? unknown : OUIConfigError<`Duplicate surface id: "${DuplicateIds<TIds>}". Surface registration is keyed by id, so the second would silently replace the first.`>;
50
50
 
51
51
  /**
52
- * createOUI — the only supported way to instantiate OUI.
52
+ * createOUI — a fixed set of surfaces announced over one socket.
53
+ *
54
+ * For a client whose surfaces come and go (a React app, where a page's
55
+ * surfaces mount with the page), use `createSurfaceRuntime` instead: it keeps
56
+ * the client's own record of what is mounted and answers every request.
53
57
  *
54
58
  * WHY THIS EXISTS
55
59
  *
@@ -72,8 +76,8 @@ type ValidateSurfaceIds<TIds extends readonly string[]> = IsEmpty<TIds> extends
72
76
  * transport, because `OUITransport` values are branded and only this module
73
77
  * brands them.
74
78
  *
75
- * OUI owns the result path. Results return through the observation channel,
76
- * as `use-surface` already implements. An integrator cannot add a parallel
79
+ * OUI owns the result path. Every dispatch carries a requestId and is
80
+ * answered on OUI's result channel. An integrator cannot add a parallel
77
81
  * channel because it cannot construct a transport to add one to.
78
82
  *
79
83
  * The integrator owns content. Surfaces, action schemas, observation schemas
@@ -117,7 +121,10 @@ interface OUIInstance {
117
121
  readonly manifests: readonly OUISurface[];
118
122
  /** Register every surface and connect. */
119
123
  start(): Promise<void>;
120
- /** Deregister every surface and disconnect. */
124
+ /**
125
+ * Deregister every surface and detach OUI from the socket. The socket stays
126
+ * connected: the integrator owns it, and other code may share it.
127
+ */
121
128
  stop(): void;
122
129
  /** Look up a registered surface by id. */
123
130
  getSurface(id: string): DefinedSurface<never> | undefined;
@@ -1,5 +1,5 @@
1
- export { createOUI, defineSurface } from '../chunk-ILUTAHUJ.js';
2
- export { OUI_PROTOCOL_EVENTS } from '../chunk-CVUUSPF4.js';
3
- import '../chunk-YDMGV72W.js';
1
+ export { createOUI, createSurfaceRuntime, defineSurface } from '../chunk-TRNVXAB5.js';
2
+ export { OUI_PROTOCOL_EVENTS } from '../chunk-BMCL2K74.js';
3
+ import '../chunk-F3WKIRAU.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
package/dist/index.cjs CHANGED
@@ -1,40 +1,56 @@
1
1
  'use strict';
2
2
 
3
- var chunkHK7OXB2W_cjs = require('./chunk-HK7OXB2W.cjs');
4
- var chunk3DCIL4FV_cjs = require('./chunk-3DCIL4FV.cjs');
5
- var chunk2ON5IEXB_cjs = require('./chunk-2ON5IEXB.cjs');
6
- var chunk5TQ6AVQH_cjs = require('./chunk-5TQ6AVQH.cjs');
7
- var chunkMTMEW6MM_cjs = require('./chunk-MTMEW6MM.cjs');
3
+ var chunkKNWGQRXL_cjs = require('./chunk-KNWGQRXL.cjs');
4
+ var chunkZKM4XWAB_cjs = require('./chunk-ZKM4XWAB.cjs');
5
+ var chunkF3SKRAGU_cjs = require('./chunk-F3SKRAGU.cjs');
6
+ var chunkROGKEMLL_cjs = require('./chunk-ROGKEMLL.cjs');
7
+ var chunkDCVVTP3V_cjs = require('./chunk-DCVVTP3V.cjs');
8
8
 
9
9
 
10
10
 
11
11
  Object.defineProperty(exports, "createOUI", {
12
12
  enumerable: true,
13
- get: function () { return chunkHK7OXB2W_cjs.createOUI; }
13
+ get: function () { return chunkKNWGQRXL_cjs.createOUI; }
14
+ });
15
+ Object.defineProperty(exports, "createSurfaceRuntime", {
16
+ enumerable: true,
17
+ get: function () { return chunkKNWGQRXL_cjs.createSurfaceRuntime; }
14
18
  });
15
19
  Object.defineProperty(exports, "defineSurface", {
16
20
  enumerable: true,
17
- get: function () { return chunkHK7OXB2W_cjs.defineSurface; }
21
+ get: function () { return chunkKNWGQRXL_cjs.defineSurface; }
18
22
  });
19
23
  Object.defineProperty(exports, "OUI_PROTOCOL_EVENTS", {
20
24
  enumerable: true,
21
- get: function () { return chunk3DCIL4FV_cjs.OUI_PROTOCOL_EVENTS; }
25
+ get: function () { return chunkZKM4XWAB_cjs.OUI_PROTOCOL_EVENTS; }
26
+ });
27
+ Object.defineProperty(exports, "SurfaceRuntimeProvider", {
28
+ enumerable: true,
29
+ get: function () { return chunkF3SKRAGU_cjs.SurfaceRuntimeProvider; }
22
30
  });
23
31
  Object.defineProperty(exports, "useObservation", {
24
32
  enumerable: true,
25
- get: function () { return chunk2ON5IEXB_cjs.useObservation; }
33
+ get: function () { return chunkF3SKRAGU_cjs.useObservation; }
26
34
  });
27
35
  Object.defineProperty(exports, "useSurface", {
28
36
  enumerable: true,
29
- get: function () { return chunk2ON5IEXB_cjs.useSurface; }
37
+ get: function () { return chunkF3SKRAGU_cjs.useSurface; }
38
+ });
39
+ Object.defineProperty(exports, "useSurfaceHold", {
40
+ enumerable: true,
41
+ get: function () { return chunkF3SKRAGU_cjs.useSurfaceHold; }
42
+ });
43
+ Object.defineProperty(exports, "useSurfaceRuntime", {
44
+ enumerable: true,
45
+ get: function () { return chunkF3SKRAGU_cjs.useSurfaceRuntime; }
30
46
  });
31
47
  Object.defineProperty(exports, "createDirectTransportPair", {
32
48
  enumerable: true,
33
- get: function () { return chunk5TQ6AVQH_cjs.createDirectTransportPair; }
49
+ get: function () { return chunkROGKEMLL_cjs.createDirectTransportPair; }
34
50
  });
35
51
  Object.defineProperty(exports, "createWebSocketTransport", {
36
52
  enumerable: true,
37
- get: function () { return chunkMTMEW6MM_cjs.createWebSocketTransport; }
53
+ get: function () { return chunkDCVVTP3V_cjs.createWebSocketTransport; }
38
54
  });
39
55
  //# sourceMappingURL=index.cjs.map
40
56
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -1,6 +1,7 @@
1
- export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationUpdate, OUIProtocolEvent, OUISurface, OUISurfaceDeregistration, OUISurfaceRegistration, OUI_PROTOCOL_EVENTS } from './spec/index.cjs';
2
- export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, D as DefinedSurface, O as OUIBranded, c as ObservationDefinition, S as SurfaceDefinition, d as defineSurface } from './define-surface-D6XPtoqu.cjs';
1
+ export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationSnapshot, OUIObservationUpdate, OUIProtocolEvent, OUISurface, OUISurfaceDeregistration, OUISurfaceRegistration, OUISurfaceSnapshot, OUI_PROTOCOL_EVENTS } from './spec/index.cjs';
2
+ export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, D as DefinedSurface, M as MountedSurface, O as OUIBranded, c as ObservationDefinition, S as SettleOptions, d as SurfaceDefinition, e as SurfaceRuntime, f as SurfaceRuntimeOptions, g as createSurfaceRuntime, h as defineSurface } from './surface-runtime--2lZGB7Z.cjs';
3
3
  export { DuplicateIds, OUIConfig, OUIConfigError, OUIInstance, OwnedTransport, ValidateSurfaceIds, createOUI } from './core/index.cjs';
4
- export { UseSurfaceOptions, useObservation, useSurface } from './react/index.cjs';
5
- export { O as OUIActionHandler, a as OUIObservationHandler, b as OUITransport, c as OUITransportConfig, S as SocketLike, d as createWebSocketTransport } from './websocket-CrI0yRNo.cjs';
4
+ export { SurfaceRuntimeProvider, SurfaceRuntimeProviderProps, UseSurfaceOptions, UseSurfaceResult, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime } from './react/index.cjs';
5
+ export { O as OUIActionHandler, a as OUIObservationHandler, b as OUIResultHandler, c as OUITransport, d as OUITransportConfig, S as SocketLike, e as createWebSocketTransport } from './websocket-YfWILdZ4.cjs';
6
6
  export { createDirectTransportPair } from './transport/index.cjs';
7
+ import 'react';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationUpdate, OUIProtocolEvent, OUISurface, OUISurfaceDeregistration, OUISurfaceRegistration, OUI_PROTOCOL_EVENTS } from './spec/index.js';
2
- export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, D as DefinedSurface, O as OUIBranded, c as ObservationDefinition, S as SurfaceDefinition, d as defineSurface } from './define-surface-DXBop-uB.js';
1
+ export { JSONSchema, OUIAction, OUIActionPolling, OUIActionRequest, OUIActionResult, OUIActivation, OUIObservation, OUIObservationSnapshot, OUIObservationUpdate, OUIProtocolEvent, OUISurface, OUISurfaceDeregistration, OUISurfaceRegistration, OUISurfaceSnapshot, OUI_PROTOCOL_EVENTS } from './spec/index.js';
2
+ export { A as ActionDefinition, a as ActionHandlerResult, b as ActionPollingConfig, D as DefinedSurface, M as MountedSurface, O as OUIBranded, c as ObservationDefinition, S as SettleOptions, d as SurfaceDefinition, e as SurfaceRuntime, f as SurfaceRuntimeOptions, g as createSurfaceRuntime, h as defineSurface } from './surface-runtime-Dj_nhd7r.js';
3
3
  export { DuplicateIds, OUIConfig, OUIConfigError, OUIInstance, OwnedTransport, ValidateSurfaceIds, createOUI } from './core/index.js';
4
- export { UseSurfaceOptions, useObservation, useSurface } from './react/index.js';
5
- export { O as OUIActionHandler, a as OUIObservationHandler, b as OUITransport, c as OUITransportConfig, S as SocketLike, d as createWebSocketTransport } from './websocket-CiWvkaz_.js';
4
+ export { SurfaceRuntimeProvider, SurfaceRuntimeProviderProps, UseSurfaceOptions, UseSurfaceResult, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime } from './react/index.js';
5
+ export { O as OUIActionHandler, a as OUIObservationHandler, b as OUIResultHandler, c as OUITransport, d as OUITransportConfig, S as SocketLike, e as createWebSocketTransport } from './websocket-c5tIUWY5.js';
6
6
  export { createDirectTransportPair } from './transport/index.js';
7
+ import 'react';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- export { createOUI, defineSurface } from './chunk-ILUTAHUJ.js';
2
- export { OUI_PROTOCOL_EVENTS } from './chunk-CVUUSPF4.js';
3
- export { useObservation, useSurface } from './chunk-UIGRLZOX.js';
4
- export { createDirectTransportPair } from './chunk-O6EI77LD.js';
5
- export { createWebSocketTransport } from './chunk-YDMGV72W.js';
1
+ export { createOUI, createSurfaceRuntime, defineSurface } from './chunk-TRNVXAB5.js';
2
+ export { OUI_PROTOCOL_EVENTS } from './chunk-BMCL2K74.js';
3
+ export { SurfaceRuntimeProvider, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime } from './chunk-NYCJZQSP.js';
4
+ export { createDirectTransportPair } from './chunk-IIZ6HL2L.js';
5
+ export { createWebSocketTransport } from './chunk-F3WKIRAU.js';
6
6
  //# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map
@@ -1,16 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var chunk2ON5IEXB_cjs = require('../chunk-2ON5IEXB.cjs');
3
+ var chunkF3SKRAGU_cjs = require('../chunk-F3SKRAGU.cjs');
4
4
 
5
5
 
6
6
 
7
+ Object.defineProperty(exports, "SurfaceRuntimeProvider", {
8
+ enumerable: true,
9
+ get: function () { return chunkF3SKRAGU_cjs.SurfaceRuntimeProvider; }
10
+ });
7
11
  Object.defineProperty(exports, "useObservation", {
8
12
  enumerable: true,
9
- get: function () { return chunk2ON5IEXB_cjs.useObservation; }
13
+ get: function () { return chunkF3SKRAGU_cjs.useObservation; }
10
14
  });
11
15
  Object.defineProperty(exports, "useSurface", {
12
16
  enumerable: true,
13
- get: function () { return chunk2ON5IEXB_cjs.useSurface; }
17
+ get: function () { return chunkF3SKRAGU_cjs.useSurface; }
18
+ });
19
+ Object.defineProperty(exports, "useSurfaceHold", {
20
+ enumerable: true,
21
+ get: function () { return chunkF3SKRAGU_cjs.useSurfaceHold; }
22
+ });
23
+ Object.defineProperty(exports, "useSurfaceRuntime", {
24
+ enumerable: true,
25
+ get: function () { return chunkF3SKRAGU_cjs.useSurfaceRuntime; }
14
26
  });
15
27
  //# sourceMappingURL=index.cjs.map
16
28
  //# sourceMappingURL=index.cjs.map
@@ -1,62 +1,45 @@
1
- import { OUIActionRequest, OUISurface } from '../spec/index.cjs';
2
- import { D as DefinedSurface } from '../define-surface-D6XPtoqu.cjs';
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { OUIActionResult } from '../spec/index.cjs';
4
+ import { e as SurfaceRuntime, D as DefinedSurface } from '../surface-runtime--2lZGB7Z.cjs';
5
+ import '../websocket-YfWILdZ4.cjs';
3
6
 
4
- /**
5
- * Configuration for the useSurface hook.
6
- */
7
+ interface SurfaceRuntimeProviderProps {
8
+ runtime: SurfaceRuntime;
9
+ children?: ReactNode;
10
+ }
11
+ /** Makes one surface runtime available to every `useSurface` below it. */
12
+ declare function SurfaceRuntimeProvider({ runtime, children, }: SurfaceRuntimeProviderProps): react.FunctionComponentElement<react.ProviderProps<SurfaceRuntime | null>>;
13
+ /** The surface runtime from the nearest `SurfaceRuntimeProvider`. */
14
+ declare function useSurfaceRuntime(): SurfaceRuntime;
7
15
  interface UseSurfaceOptions<TContext> {
8
16
  /** The defined surface (from defineSurface()) */
9
17
  surface: DefinedSurface<TContext>;
10
- /** The context passed to action handlers (app state, utilities, etc.) */
18
+ /** Passed to action handlers. Read when an action runs, so it is always current. */
11
19
  context: TContext;
12
- /** Transport send function — how to send protocol events to the agent runtime */
13
- send: (event: {
14
- type: string;
15
- payload: unknown;
16
- }) => void;
17
- /** Whether the surface is currently active (respects activation conditions) */
20
+ /** Mount the surface only while true. Default true. */
18
21
  active?: boolean;
19
22
  }
23
+ interface UseSurfaceResult {
24
+ surfaceId: string;
25
+ /** Record an observation value on this surface. Unchanged values are ignored. */
26
+ pushObservation(observationId: string, value: unknown): void;
27
+ /** Run one of this surface's actions locally, exactly as a dispatched request would. */
28
+ execute(actionId: string, params?: Record<string, unknown>): Promise<OUIActionResult>;
29
+ }
20
30
  /**
21
- * useSurface — registers an OUI surface with the agent runtime and handles
22
- * incoming action requests by executing them locally and pushing observation
23
- * updates. Actions are dispatched one-way (no request/response correlation).
24
- *
25
- * After an action handler executes, if the action has a polling config, the
26
- * hook starts a polling loop that pushes observation updates until the
27
- * operation completes or times out.
28
- *
29
- * @example
30
- * ```tsx
31
- * function DataVizPage() {
32
- * const { state, updateState, goToStep } = useDataVizWizard();
33
- *
34
- * useSurface({
35
- * surface: datavizSurface,
36
- * context: { state, updateState, goToStep },
37
- * send: agentTransport.send,
38
- * active: true,
39
- * });
40
- *
41
- * return <DataVizWizard />;
42
- * }
43
- * ```
31
+ * Mount a surface into the client's surface runtime for as long as the
32
+ * component is mounted (and `active`). The runtime answers dispatched requests
33
+ * for it, so the component needs no listener of its own.
44
34
  */
45
- declare function useSurface<TContext>(options: UseSurfaceOptions<TContext>): {
46
- handleActionRequest: (request: OUIActionRequest) => Promise<void>;
47
- surfaceId: string;
48
- manifest: OUISurface;
49
- /** Manually stop polling for a specific action */
50
- stopPolling: (actionId: string) => void;
51
- /** Stop all active pollers */
52
- stopAllPolling: () => void;
53
- };
35
+ declare function useSurface<TContext>(options: UseSurfaceOptions<TContext>): UseSurfaceResult;
36
+ /** Keep an observation on a mounted surface equal to `value`. */
37
+ declare function useObservation(surface: Pick<UseSurfaceResult, "pushObservation">, observationId: string, value: unknown): void;
54
38
  /**
55
- * Helper to push an observation update to the agent runtime.
39
+ * Keep the UI unsettled while `busy` is true: an action's result waits for it.
40
+ * For work mounting cannot show, such as a route's code or a page's data still
41
+ * loading.
56
42
  */
57
- declare function useObservation(surfaceId: string, observationId: string, value: unknown, send: (event: {
58
- type: string;
59
- payload: unknown;
60
- }) => void): void;
43
+ declare function useSurfaceHold(busy: boolean): void;
61
44
 
62
- export { type UseSurfaceOptions, useObservation, useSurface };
45
+ export { SurfaceRuntimeProvider, type SurfaceRuntimeProviderProps, type UseSurfaceOptions, type UseSurfaceResult, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime };
@@ -1,62 +1,45 @@
1
- import { OUIActionRequest, OUISurface } from '../spec/index.js';
2
- import { D as DefinedSurface } from '../define-surface-DXBop-uB.js';
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { OUIActionResult } from '../spec/index.js';
4
+ import { e as SurfaceRuntime, D as DefinedSurface } from '../surface-runtime-Dj_nhd7r.js';
5
+ import '../websocket-c5tIUWY5.js';
3
6
 
4
- /**
5
- * Configuration for the useSurface hook.
6
- */
7
+ interface SurfaceRuntimeProviderProps {
8
+ runtime: SurfaceRuntime;
9
+ children?: ReactNode;
10
+ }
11
+ /** Makes one surface runtime available to every `useSurface` below it. */
12
+ declare function SurfaceRuntimeProvider({ runtime, children, }: SurfaceRuntimeProviderProps): react.FunctionComponentElement<react.ProviderProps<SurfaceRuntime | null>>;
13
+ /** The surface runtime from the nearest `SurfaceRuntimeProvider`. */
14
+ declare function useSurfaceRuntime(): SurfaceRuntime;
7
15
  interface UseSurfaceOptions<TContext> {
8
16
  /** The defined surface (from defineSurface()) */
9
17
  surface: DefinedSurface<TContext>;
10
- /** The context passed to action handlers (app state, utilities, etc.) */
18
+ /** Passed to action handlers. Read when an action runs, so it is always current. */
11
19
  context: TContext;
12
- /** Transport send function — how to send protocol events to the agent runtime */
13
- send: (event: {
14
- type: string;
15
- payload: unknown;
16
- }) => void;
17
- /** Whether the surface is currently active (respects activation conditions) */
20
+ /** Mount the surface only while true. Default true. */
18
21
  active?: boolean;
19
22
  }
23
+ interface UseSurfaceResult {
24
+ surfaceId: string;
25
+ /** Record an observation value on this surface. Unchanged values are ignored. */
26
+ pushObservation(observationId: string, value: unknown): void;
27
+ /** Run one of this surface's actions locally, exactly as a dispatched request would. */
28
+ execute(actionId: string, params?: Record<string, unknown>): Promise<OUIActionResult>;
29
+ }
20
30
  /**
21
- * useSurface — registers an OUI surface with the agent runtime and handles
22
- * incoming action requests by executing them locally and pushing observation
23
- * updates. Actions are dispatched one-way (no request/response correlation).
24
- *
25
- * After an action handler executes, if the action has a polling config, the
26
- * hook starts a polling loop that pushes observation updates until the
27
- * operation completes or times out.
28
- *
29
- * @example
30
- * ```tsx
31
- * function DataVizPage() {
32
- * const { state, updateState, goToStep } = useDataVizWizard();
33
- *
34
- * useSurface({
35
- * surface: datavizSurface,
36
- * context: { state, updateState, goToStep },
37
- * send: agentTransport.send,
38
- * active: true,
39
- * });
40
- *
41
- * return <DataVizWizard />;
42
- * }
43
- * ```
31
+ * Mount a surface into the client's surface runtime for as long as the
32
+ * component is mounted (and `active`). The runtime answers dispatched requests
33
+ * for it, so the component needs no listener of its own.
44
34
  */
45
- declare function useSurface<TContext>(options: UseSurfaceOptions<TContext>): {
46
- handleActionRequest: (request: OUIActionRequest) => Promise<void>;
47
- surfaceId: string;
48
- manifest: OUISurface;
49
- /** Manually stop polling for a specific action */
50
- stopPolling: (actionId: string) => void;
51
- /** Stop all active pollers */
52
- stopAllPolling: () => void;
53
- };
35
+ declare function useSurface<TContext>(options: UseSurfaceOptions<TContext>): UseSurfaceResult;
36
+ /** Keep an observation on a mounted surface equal to `value`. */
37
+ declare function useObservation(surface: Pick<UseSurfaceResult, "pushObservation">, observationId: string, value: unknown): void;
54
38
  /**
55
- * Helper to push an observation update to the agent runtime.
39
+ * Keep the UI unsettled while `busy` is true: an action's result waits for it.
40
+ * For work mounting cannot show, such as a route's code or a page's data still
41
+ * loading.
56
42
  */
57
- declare function useObservation(surfaceId: string, observationId: string, value: unknown, send: (event: {
58
- type: string;
59
- payload: unknown;
60
- }) => void): void;
43
+ declare function useSurfaceHold(busy: boolean): void;
61
44
 
62
- export { type UseSurfaceOptions, useObservation, useSurface };
45
+ export { SurfaceRuntimeProvider, type SurfaceRuntimeProviderProps, type UseSurfaceOptions, type UseSurfaceResult, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime };
@@ -1,3 +1,3 @@
1
- export { useObservation, useSurface } from '../chunk-UIGRLZOX.js';
1
+ export { SurfaceRuntimeProvider, useObservation, useSurface, useSurfaceHold, useSurfaceRuntime } from '../chunk-NYCJZQSP.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var chunk3DCIL4FV_cjs = require('../chunk-3DCIL4FV.cjs');
3
+ var chunkZKM4XWAB_cjs = require('../chunk-ZKM4XWAB.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "OUI_PROTOCOL_EVENTS", {
8
8
  enumerable: true,
9
- get: function () { return chunk3DCIL4FV_cjs.OUI_PROTOCOL_EVENTS; }
9
+ get: function () { return chunkZKM4XWAB_cjs.OUI_PROTOCOL_EVENTS; }
10
10
  });
11
11
  //# sourceMappingURL=index.cjs.map
12
12
  //# sourceMappingURL=index.cjs.map
@@ -127,7 +127,7 @@ interface OUIObservation {
127
127
  /** JSON Schema for the observation's value */
128
128
  schema: JSONSchema;
129
129
  /** How frequently this observation updates */
130
- updateFrequency?: 'realtime' | 'on-change' | 'polling';
130
+ updateFrequency?: "realtime" | "on-change" | "polling";
131
131
  }
132
132
  /**
133
133
  * Activation conditions — when a surface is available to the agent.
@@ -184,6 +184,34 @@ interface OUIActionResult {
184
184
  durationMs?: number;
185
185
  /** Timestamp of the result */
186
186
  timestamp: number;
187
+ /**
188
+ * The surfaces active on the client once the action's effects settled.
189
+ *
190
+ * An action can change what the agent is able to do next: navigating
191
+ * unmounts one page's surfaces and mounts another's. Without this, the agent
192
+ * would act on the capability set it had before the action, which is the
193
+ * set the action just replaced.
194
+ */
195
+ surfaces?: OUISurface[];
196
+ /** Latest observation values per surface once the action's effects settled. */
197
+ observations?: OUIObservationSnapshot;
198
+ /**
199
+ * False when the client's deadline passed before its UI settled, so
200
+ * `surfaces` and `observations` may still be changing. Absent or true
201
+ * otherwise.
202
+ */
203
+ settled?: boolean;
204
+ }
205
+ /** Latest observation values, keyed by surface id and then observation id. */
206
+ type OUIObservationSnapshot = Record<string, Record<string, unknown>>;
207
+ /**
208
+ * What a client can do right now: the surfaces it has mounted and their latest
209
+ * observation values. A client sends this to its agent runtime (for example,
210
+ * with each turn), and returns it on every action result.
211
+ */
212
+ interface OUISurfaceSnapshot {
213
+ surfaces: OUISurface[];
214
+ observations: OUIObservationSnapshot;
187
215
  }
188
216
  /**
189
217
  * An observation update pushed from the surface to the agent.
@@ -220,19 +248,19 @@ interface OUISurfaceDeregistration {
220
248
  * All protocol events exchanged between agent runtime and surfaces.
221
249
  */
222
250
  type OUIProtocolEvent = {
223
- type: 'surface:register';
251
+ type: "surface:register";
224
252
  payload: OUISurfaceRegistration;
225
253
  } | {
226
- type: 'surface:deregister';
254
+ type: "surface:deregister";
227
255
  payload: OUISurfaceDeregistration;
228
256
  } | {
229
- type: 'action:request';
257
+ type: "action:request";
230
258
  payload: OUIActionRequest;
231
259
  } | {
232
- type: 'action:result';
260
+ type: "action:result";
233
261
  payload: OUIActionResult;
234
262
  } | {
235
- type: 'observation:update';
263
+ type: "observation:update";
236
264
  payload: OUIObservationUpdate;
237
265
  };
238
266
  /**
@@ -246,4 +274,4 @@ declare const OUI_PROTOCOL_EVENTS: {
246
274
  readonly OBSERVATION_UPDATE: "observation:update";
247
275
  };
248
276
 
249
- export { type JSONSchema, type OUIAction, type OUIActionPolling, type OUIActionRequest, type OUIActionResult, type OUIActivation, type OUIObservation, type OUIObservationUpdate, type OUIProtocolEvent, type OUISurface, type OUISurfaceDeregistration, type OUISurfaceRegistration, OUI_PROTOCOL_EVENTS };
277
+ export { type JSONSchema, type OUIAction, type OUIActionPolling, type OUIActionRequest, type OUIActionResult, type OUIActivation, type OUIObservation, type OUIObservationSnapshot, type OUIObservationUpdate, type OUIProtocolEvent, type OUISurface, type OUISurfaceDeregistration, type OUISurfaceRegistration, type OUISurfaceSnapshot, OUI_PROTOCOL_EVENTS };