@ouispec/contract 0.1.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.
- package/INTEGRATOR-GUIDE.md +729 -0
- package/LICENSE +21 -0
- package/README.md +10 -0
- package/dist/codegen.d.ts +71 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +195 -0
- package/dist/codegen.js.map +1 -0
- package/dist/generated/contract.d.ts +1286 -0
- package/dist/generated/contract.d.ts.map +1 -0
- package/dist/generated/contract.js +14 -0
- package/dist/generated/contract.js.map +1 -0
- package/dist/generated/schemas.d.ts +111 -0
- package/dist/generated/schemas.d.ts.map +1 -0
- package/dist/generated/schemas.js +3256 -0
- package/dist/generated/schemas.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/render-contract.d.ts +47 -0
- package/dist/render-contract.d.ts.map +1 -0
- package/dist/render-contract.js +123 -0
- package/dist/render-contract.js.map +1 -0
- package/dist/render-guide.d.ts +4 -0
- package/dist/render-guide.d.ts.map +1 -0
- package/dist/render-guide.js +132 -0
- package/dist/render-guide.js.map +1 -0
- package/dist/schema-document.d.ts +7 -0
- package/dist/schema-document.d.ts.map +1 -0
- package/dist/schema-document.js +2 -0
- package/dist/schema-document.js.map +1 -0
- package/dist/validate.d.ts +22 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +89 -0
- package/dist/validate.js.map +1 -0
- package/package.json +65 -0
- package/schemas/action-effect.json +113 -0
- package/schemas/agent-binding.json +58 -0
- package/schemas/approvals.json +249 -0
- package/schemas/control-kind-registration.json +187 -0
- package/schemas/control-table.json +276 -0
- package/schemas/event-declarations.json +316 -0
- package/schemas/generated-knowledge.json +58 -0
- package/schemas/json-schema.json +153 -0
- package/schemas/oui-config.json +178 -0
- package/schemas/oui-manifest.json +346 -0
- package/schemas/room-catalog-data.json +455 -0
- package/schemas/tier2-mapping.json +195 -0
|
@@ -0,0 +1,1286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract major. A breaking change to any schema of the contract bumps it, and it is in
|
|
3
|
+
* every `$id`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MANIFEST_VERSION = 1;
|
|
6
|
+
/**
|
|
7
|
+
* Where the contract’s schemas are identified: each `$id` is this followed by the file name.
|
|
8
|
+
*/
|
|
9
|
+
export declare const CONTRACT_SCHEMA_BASE = "https://schemas.closurestudio.ai/oui/v1/";
|
|
10
|
+
/**
|
|
11
|
+
* The subset of JSON Schema (draft 2020-12) every capability declares its input and values in.
|
|
12
|
+
* It is what assistant tool inputs are written in, so a declared or derived schema is used as
|
|
13
|
+
* is. `x-unit` names the unit a number is in: `px`, `%`, `°`.
|
|
14
|
+
*/
|
|
15
|
+
export interface JsonSchema {
|
|
16
|
+
type?: JsonSchemaType | readonly JsonSchemaType[];
|
|
17
|
+
description?: string;
|
|
18
|
+
enum?: readonly (string | number | boolean | null)[];
|
|
19
|
+
const?: string | number | boolean | null;
|
|
20
|
+
properties?: Readonly<Record<string, JsonSchema>>;
|
|
21
|
+
required?: readonly string[];
|
|
22
|
+
additionalProperties?: boolean | JsonSchema;
|
|
23
|
+
items?: JsonSchema;
|
|
24
|
+
minItems?: number;
|
|
25
|
+
maxItems?: number;
|
|
26
|
+
/** No two items are the same. */
|
|
27
|
+
uniqueItems?: boolean;
|
|
28
|
+
minimum?: number;
|
|
29
|
+
maximum?: number;
|
|
30
|
+
multipleOf?: number;
|
|
31
|
+
minLength?: number;
|
|
32
|
+
maxLength?: number;
|
|
33
|
+
pattern?: string;
|
|
34
|
+
format?: string;
|
|
35
|
+
oneOf?: readonly JsonSchema[];
|
|
36
|
+
anyOf?: readonly JsonSchema[];
|
|
37
|
+
default?: unknown;
|
|
38
|
+
/** The unit a number is in: `px`, `%`, `°`. */
|
|
39
|
+
'x-unit'?: string;
|
|
40
|
+
/**
|
|
41
|
+
* How many allowed values a shortened `enum` leaves out. Only in the page state, where a
|
|
42
|
+
* row's options are summarised; a tool's input schema always lists every value.
|
|
43
|
+
*/
|
|
44
|
+
'x-enum-omitted'?: number;
|
|
45
|
+
}
|
|
46
|
+
/** A JSON Schema type name. */
|
|
47
|
+
export type JsonSchemaType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
|
|
48
|
+
/**
|
|
49
|
+
* What using an action does (ADR-0226 §2.6): one vocabulary for a design-system control's
|
|
50
|
+
* binding, a room catalog's entry and a generated API tool, so a page control, a room action
|
|
51
|
+
* and an API call are told apart by what they change, never by where they are declared.
|
|
52
|
+
*
|
|
53
|
+
* | Effect | What it changes | ADR-0210 access |
|
|
54
|
+
* |---|---|---|
|
|
55
|
+
* | `view`, `selection`, `navigate`, `open` | What is shown | read |
|
|
56
|
+
* | `edit` | The document, one undo step | write |
|
|
57
|
+
* | `file` | Imports or exports a file | write |
|
|
58
|
+
* | `mutate` | Backend data, through an API operation | write |
|
|
59
|
+
* | `job` | Starts work that outlives the call, settled on its outcome | write |
|
|
60
|
+
* | `transaction` | An irreversible external act: an order, a payment, a send, a publish | write, approved |
|
|
61
|
+
*
|
|
62
|
+
* A `transaction`, and any `write` declared `destructive`, runs only on an approval the person
|
|
63
|
+
* gave, bound to the call (ADR-0228).
|
|
64
|
+
*/
|
|
65
|
+
export type ActionEffect = SimpleEffect | {
|
|
66
|
+
kind: 'navigate';
|
|
67
|
+
to: string;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'open';
|
|
70
|
+
container: string;
|
|
71
|
+
} | {
|
|
72
|
+
kind: 'mutate';
|
|
73
|
+
operation: string;
|
|
74
|
+
} | {
|
|
75
|
+
kind: 'job';
|
|
76
|
+
estimatedDuration?: string;
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
} | {
|
|
79
|
+
kind: 'transaction';
|
|
80
|
+
operation?: string;
|
|
81
|
+
estimatedDuration?: string;
|
|
82
|
+
timeoutMs?: number;
|
|
83
|
+
approvalMinutes?: number;
|
|
84
|
+
};
|
|
85
|
+
/** An effect that needs nothing but its name. */
|
|
86
|
+
export type SimpleEffect = 'view' | 'selection' | 'edit' | 'file';
|
|
87
|
+
/**
|
|
88
|
+
* The effect kinds, in the order of the table above. The vocabulary, what each one may change,
|
|
89
|
+
* and what needs the person's approval are OUI's (`oui-spec`).
|
|
90
|
+
*/
|
|
91
|
+
export type ActionEffectKind = 'view' | 'selection' | 'navigate' | 'open' | 'edit' | 'file' | 'mutate' | 'job' | 'transaction';
|
|
92
|
+
/**
|
|
93
|
+
* Whether an effect only changes what is shown (`read`), or changes something (`write`), as
|
|
94
|
+
* ADR-0210 names it. An action that declares no effect is a `write`.
|
|
95
|
+
*/
|
|
96
|
+
export type EffectAccess = 'read' | 'write';
|
|
97
|
+
/**
|
|
98
|
+
* Where an action whose effect is `job` or `transaction` is (plan §2.3, #205/#209):
|
|
99
|
+
*
|
|
100
|
+
* - `started`: the handler returned; the job is tracked from this moment, so an outcome that
|
|
101
|
+
* arrives before the first poll is kept.
|
|
102
|
+
* - `running`: still going; the runtime polls the app's `JobTracker`.
|
|
103
|
+
* - `complete`: the job's declared completion arrived; the result exists.
|
|
104
|
+
* - `failed`: its declared failure arrived; the result never will.
|
|
105
|
+
* - `timeout`: it did not finish within `timeoutMs`. A failure, never a late success.
|
|
106
|
+
* - `unverified`: no `JobTracker`, or no job id to follow: the work was started but cannot be
|
|
107
|
+
* confirmed from the page.
|
|
108
|
+
*/
|
|
109
|
+
export type JobStatus = 'started' | 'running' | 'complete' | 'failed' | 'timeout' | 'unverified';
|
|
110
|
+
/**
|
|
111
|
+
* A job's end, as the assistant is told it. `complete` means the result exists; `failed` that
|
|
112
|
+
* it never will. A `complete` outcome carries the declared result fields beside its job id.
|
|
113
|
+
*/
|
|
114
|
+
export type JobOutcome = {
|
|
115
|
+
status: 'complete';
|
|
116
|
+
jobId: string;
|
|
117
|
+
[key: string]: unknown;
|
|
118
|
+
} | {
|
|
119
|
+
status: 'failed';
|
|
120
|
+
jobId: string;
|
|
121
|
+
error: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* What an action that settles on a job reports, from its first answer to its last: `started`
|
|
125
|
+
* (with the job id when the handler gave one), `running` while it polls, then the `JobOutcome`,
|
|
126
|
+
* or `unverified`. A `timeout` is reported as the error `TIMEOUT`, never as data.
|
|
127
|
+
*/
|
|
128
|
+
export type JobSettlement = {
|
|
129
|
+
status: 'started';
|
|
130
|
+
jobId?: string;
|
|
131
|
+
[key: string]: unknown;
|
|
132
|
+
} | {
|
|
133
|
+
status: 'running';
|
|
134
|
+
jobId: string;
|
|
135
|
+
} | JobOutcome | {
|
|
136
|
+
status: 'unverified';
|
|
137
|
+
message: string;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* The semantic binding a design-system control carries (ADR-0220 §2.2): what the control means,
|
|
141
|
+
* in the user's terms, declared where the page uses it, as its `agent` prop.
|
|
142
|
+
*
|
|
143
|
+
* It uses a room catalog entry's vocabulary (id, title and description; `ActionEffect`;
|
|
144
|
+
* `destructive`), so to the generator a page control and a room entry look the same. What is
|
|
145
|
+
* never written: the input schema, which is derived from the control's own props, and where the
|
|
146
|
+
* control is, which the generator derives from the page's component tree.
|
|
147
|
+
*
|
|
148
|
+
* **Every value is a build-time constant** (#203). The generator reads bindings from source
|
|
149
|
+
* without running it, so each value is a literal, a `const` it can follow, a property of a
|
|
150
|
+
* constant object, a template literal or `+` over those, or a single-literal type read through
|
|
151
|
+
* the type checker. A value built by a call (`t('save')`, `format(...)`) is refused, naming the
|
|
152
|
+
* binding. A field's build-time `hint` and `placeholder` are added to its tool description the
|
|
153
|
+
* same way.
|
|
154
|
+
*/
|
|
155
|
+
export interface AgentBinding {
|
|
156
|
+
/**
|
|
157
|
+
* Stable, globally unique, dotted and lower-kebab: `voices.library`, `voices.detail.engine`.
|
|
158
|
+
* The first segment is the area. The tool name is the id with `.` and `-` as `_`, at most 64
|
|
159
|
+
* characters.
|
|
160
|
+
*/
|
|
161
|
+
id: string;
|
|
162
|
+
/** Defaults to the control's visible label or aria-label. */
|
|
163
|
+
title?: string;
|
|
164
|
+
/** What using it does, for someone who cannot see the screen. */
|
|
165
|
+
description: string;
|
|
166
|
+
/**
|
|
167
|
+
* What using it does: what reach paths, data and verification are derived from (ADR-0226
|
|
168
|
+
* §2.6).
|
|
169
|
+
*/
|
|
170
|
+
effect?: ActionEffect;
|
|
171
|
+
/**
|
|
172
|
+
* It removes or replaces something the person made; running it needs the person's approval
|
|
173
|
+
* (ADR-0228).
|
|
174
|
+
*/
|
|
175
|
+
destructive?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* It changes what the person is working in (their account, project or role) rather than their
|
|
178
|
+
* work; the assistant asks before using it.
|
|
179
|
+
*/
|
|
180
|
+
confirm?: boolean;
|
|
181
|
+
/** Set when the control is one of a list's rows: which row. */
|
|
182
|
+
item?: AgentItem;
|
|
183
|
+
}
|
|
184
|
+
/** One of several of the same control rendered from a list: which one it is. */
|
|
185
|
+
export interface AgentItem {
|
|
186
|
+
/** The id of what the row shows (a voice id, a project id). */
|
|
187
|
+
key: string;
|
|
188
|
+
/** What the row is called on screen (the voice's name). */
|
|
189
|
+
title: string;
|
|
190
|
+
/**
|
|
191
|
+
* What this row is, when the rows' meanings are only known at run time (a model's parameters,
|
|
192
|
+
* from its manifest). Shown with the row in the page state.
|
|
193
|
+
*/
|
|
194
|
+
description?: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* On a control the assistant must never operate — purely decorative, or chrome that duplicates
|
|
198
|
+
* a bound control. The reason is required and is reviewed like any other declaration.
|
|
199
|
+
*/
|
|
200
|
+
export interface NonAgentBinding {
|
|
201
|
+
nonAgent: string;
|
|
202
|
+
}
|
|
203
|
+
/** The `agent` prop of a single-purpose control. */
|
|
204
|
+
export type AgentProp = AgentBinding | NonAgentBinding;
|
|
205
|
+
/**
|
|
206
|
+
* A control kind a design system adds (ADR-0226 §2.6). `ControlKind` is closed: a design system
|
|
207
|
+
* adds a kind only by registering it, under an `x-` name. The registration ships in the design
|
|
208
|
+
* system's control table (`$kinds`), where the generator reads it, and the design system
|
|
209
|
+
* registers it at run time with `registerControlKind`, so the browser and the generator derive
|
|
210
|
+
* the same schema.
|
|
211
|
+
*/
|
|
212
|
+
export interface ControlKindRegistration {
|
|
213
|
+
kind: RegisteredControlKind;
|
|
214
|
+
/** What using it does, as a tool description starts: "Set the price range of". */
|
|
215
|
+
verb: string;
|
|
216
|
+
deriveSchema: KindSchemaDerivation;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The built-in control kinds, closed:
|
|
220
|
+
*
|
|
221
|
+
* - `button`: press it (buttons, toolbar buttons, menu items, a row's action).
|
|
222
|
+
* - `toggle`: set it on or off (switches, checkboxes).
|
|
223
|
+
* - `text`: type into it (inputs, text areas).
|
|
224
|
+
* - `number`: set a number (sliders, scrub fields).
|
|
225
|
+
* - `choice`: choose one of its options (selects, radio groups, preset tiles).
|
|
226
|
+
* - `multi-choice`: choose any of its options (multi-selects, checkbox groups, filter chips).
|
|
227
|
+
* - `color`: set a colour or paint (colour pickers, swatches).
|
|
228
|
+
* - `font`: choose a family and style (font pickers).
|
|
229
|
+
* - `tabs`: select a tab.
|
|
230
|
+
* - `date`: set a date.
|
|
231
|
+
* - `date-range`: set a start and an end date.
|
|
232
|
+
* - `dialog`: close it. Opening is its trigger's.
|
|
233
|
+
*/
|
|
234
|
+
export type ControlKind = 'button' | 'toggle' | 'text' | 'number' | 'choice' | 'multi-choice' | 'color' | 'font' | 'tabs' | 'date' | 'date-range' | 'dialog';
|
|
235
|
+
/**
|
|
236
|
+
* A kind a design system registers: `x-` and lower-kebab, so it never collides with a built-in
|
|
237
|
+
* one.
|
|
238
|
+
*/
|
|
239
|
+
export type RegisteredControlKind = `x-${string}`;
|
|
240
|
+
/** A built-in kind, or one a design system registers. */
|
|
241
|
+
export type AnyControlKind = ControlKind | RegisteredControlKind;
|
|
242
|
+
/** A key of `SchemaProps`: a prop a control's value schema is derived from. */
|
|
243
|
+
export type SchemaPropName = 'min' | 'max' | 'step' | 'unit' | 'wrap' | 'options' | 'minLength' | 'maxLength' | 'pattern' | 'inputType' | 'paintKinds' | 'allowNone' | 'clearable';
|
|
244
|
+
/** One option of a choice, tab set or menu, as the control shows it. */
|
|
245
|
+
export interface ControlOption {
|
|
246
|
+
value: string | number;
|
|
247
|
+
title: string;
|
|
248
|
+
disabled?: boolean;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* The props a control's input schema is derived from, by the one derivation
|
|
252
|
+
* (`deriveInputSchema`) the browser runs on live props and the generator on the props it reads
|
|
253
|
+
* statically. A live schema may narrow the generated one but never widen it.
|
|
254
|
+
*/
|
|
255
|
+
export interface SchemaProps {
|
|
256
|
+
min?: number;
|
|
257
|
+
max?: number;
|
|
258
|
+
step?: number;
|
|
259
|
+
unit?: string;
|
|
260
|
+
/** Wraps past either end: an angle, where 181° is −179°. */
|
|
261
|
+
wrap?: boolean;
|
|
262
|
+
options?: readonly ControlOption[];
|
|
263
|
+
minLength?: number;
|
|
264
|
+
maxLength?: number;
|
|
265
|
+
pattern?: string;
|
|
266
|
+
/** An input's `type`: `email`, `url`, `number`, `password`… */
|
|
267
|
+
inputType?: string;
|
|
268
|
+
/** The paint kinds a colour control offers: `solid`, `linear`, `radial`. */
|
|
269
|
+
paintKinds?: readonly string[];
|
|
270
|
+
/** A colour control can be set to no paint. */
|
|
271
|
+
allowNone?: boolean;
|
|
272
|
+
/** A choice that can be cleared (a toggleable tile grid). */
|
|
273
|
+
clearable?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* How a registered kind's value schema follows from a control's props, as data, so the browser
|
|
277
|
+
* and the generator derive it with the same function: the schema, and which of its keywords
|
|
278
|
+
* each prop sets, by JSON Pointer. `options` sets a keyword to the values of the options that
|
|
279
|
+
* are not disabled.
|
|
280
|
+
*
|
|
281
|
+
* ```json
|
|
282
|
+
* { "schema": { "type": "object", "properties": { "low": { "type": "number" }, "high": { "type": "number" } } },
|
|
283
|
+
* "props": { "/properties/low/minimum": "min", "/properties/high/maximum": "max" } }
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
export interface KindSchemaDerivation {
|
|
287
|
+
schema: JsonSchema;
|
|
288
|
+
props?: Readonly<Record<string, SchemaPropName>>;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* A design-system package's control table as it ships (`agent-controls.json`, ADR-0226 §2.2
|
|
292
|
+
* rule 4): each interactive export's `ControlDescriptor` by export name, and under `$kinds` the
|
|
293
|
+
* control kinds the design system registers, if any. The package declares the table next to its
|
|
294
|
+
* controls, writes it at build time, and names it in its `package.json` under
|
|
295
|
+
* `oui.agentControls` (`closure.agentControls` is read during the transition; declaring both is
|
|
296
|
+
* an error). The conformance kit holds every listed component to registering with the kind
|
|
297
|
+
* declared here.
|
|
298
|
+
*/
|
|
299
|
+
export interface ControlTableFile {
|
|
300
|
+
/** The control kinds this design system registers. */
|
|
301
|
+
$kinds?: readonly ControlKindRegistration[];
|
|
302
|
+
[key: string]: ControlDescriptor | readonly ControlKindRegistration[] | undefined;
|
|
303
|
+
}
|
|
304
|
+
/** A design-system package's controls, by export name: the table without its `$kinds`. */
|
|
305
|
+
export type ControlTable = Readonly<Record<string, ControlDescriptor>>;
|
|
306
|
+
/**
|
|
307
|
+
* One slot of a composite: its kind and the callback it binds. `callback` absent: the slot is
|
|
308
|
+
* always interactive (a toast host's toasts, whatever the page passes). `rows`: the slot
|
|
309
|
+
* registers once per row the control renders (a table's rows, a filter bar's pills), so its
|
|
310
|
+
* action takes an `item`. `defaults`: what the slot always registers, over the component's (a
|
|
311
|
+
* table's sort can be cleared), so the declared schema is as wide as the live one.
|
|
312
|
+
*/
|
|
313
|
+
export interface SlotDescriptor {
|
|
314
|
+
kind: AnyControlKind;
|
|
315
|
+
callback?: string;
|
|
316
|
+
rows?: boolean;
|
|
317
|
+
defaults?: SchemaProps;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* An array prop whose entries carry their own `agent` (toolbar items, menu items, selection
|
|
321
|
+
* actions).
|
|
322
|
+
*/
|
|
323
|
+
export interface EntriesDescriptor {
|
|
324
|
+
prop: string;
|
|
325
|
+
kind: AnyControlKind;
|
|
326
|
+
callback: string;
|
|
327
|
+
titleKey: string;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* How the generator reads one design-system component where a page uses it: what kind of
|
|
331
|
+
* control it is, which of its props make it interactive, and where its schema, options, slots
|
|
332
|
+
* and nested bindings come from. The component itself registers through `useAgentBinding` with
|
|
333
|
+
* the same kind.
|
|
334
|
+
*/
|
|
335
|
+
export interface ControlDescriptor {
|
|
336
|
+
/**
|
|
337
|
+
* What a binding on the component itself makes. Absent when it binds only per slot or per
|
|
338
|
+
* entry.
|
|
339
|
+
*/
|
|
340
|
+
kind?: AnyControlKind;
|
|
341
|
+
/**
|
|
342
|
+
* Props whose presence makes a use interactive — a use with one of them must be bound. Empty:
|
|
343
|
+
* always.
|
|
344
|
+
*/
|
|
345
|
+
callbacks: readonly string[];
|
|
346
|
+
/**
|
|
347
|
+
* Props the schema is derived from, by `SchemaProps` key: the prop of the component each
|
|
348
|
+
* comes from.
|
|
349
|
+
*/
|
|
350
|
+
schemaProps?: SchemaPropSources;
|
|
351
|
+
/** Where the options come from: the prop, and the keys of each option's value and title. */
|
|
352
|
+
options?: OptionsSource;
|
|
353
|
+
/** A composite with several callbacks: slot name → its kind and the callback it binds. */
|
|
354
|
+
slots?: Readonly<Record<string, SlotDescriptor>>;
|
|
355
|
+
entries?: EntriesDescriptor;
|
|
356
|
+
/**
|
|
357
|
+
* The control registers one binding per row it renders (a selectable grid), so its action
|
|
358
|
+
* takes an `item`.
|
|
359
|
+
*/
|
|
360
|
+
rows?: boolean;
|
|
361
|
+
/**
|
|
362
|
+
* A container: a dialog whose prop says whether it shows, or a tab set whose prop selects a
|
|
363
|
+
* panel.
|
|
364
|
+
*/
|
|
365
|
+
container?: {
|
|
366
|
+
kind: 'dialog' | 'tabs';
|
|
367
|
+
stateProp: string;
|
|
368
|
+
};
|
|
369
|
+
/**
|
|
370
|
+
* What the schema props are when the page leaves them out, as the component defaults them.
|
|
371
|
+
* The declared schema is the widest the control can take; the live one may only narrow it.
|
|
372
|
+
*/
|
|
373
|
+
defaults?: SchemaProps;
|
|
374
|
+
/**
|
|
375
|
+
* It shows facts rather than taking input (a clip's parameters): a binding on it names what
|
|
376
|
+
* it shows, and the page reports its facts by label. Its facts are the array prop
|
|
377
|
+
* `itemsProp`, each labelled by `labelKey`. Not a control, so a use without a binding is not
|
|
378
|
+
* unbound.
|
|
379
|
+
*/
|
|
380
|
+
display?: {
|
|
381
|
+
itemsProp: string;
|
|
382
|
+
labelKey: string;
|
|
383
|
+
};
|
|
384
|
+
/** Props that give a default title, in order. `children` means the element's text. */
|
|
385
|
+
titleProps: readonly string[];
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Where a control's options come from: the prop that holds them, and the keys of each option's
|
|
389
|
+
* value and title.
|
|
390
|
+
*/
|
|
391
|
+
export interface OptionsSource {
|
|
392
|
+
prop: string;
|
|
393
|
+
value: string;
|
|
394
|
+
title: string;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* What a package declares to the generator under the `oui` key of its `package.json` (ADR-0226
|
|
398
|
+
* §2.2): its control table, its room catalog, and the components only the person may use.
|
|
399
|
+
* During the transition the generator and the kit also read `closure.agentControls` and
|
|
400
|
+
* `closure.agentCatalog`; a package declaring a key under both `oui` and `closure` is an error.
|
|
401
|
+
*/
|
|
402
|
+
export interface OuiPackageDeclaration {
|
|
403
|
+
/** The path of the package's control table, relative to the package. */
|
|
404
|
+
agentControls?: string;
|
|
405
|
+
agentCatalog?: AgentCatalogManifestEntry;
|
|
406
|
+
/**
|
|
407
|
+
* Export name → why only the person may use it, such as the approval card (ADR-0228). The
|
|
408
|
+
* generator refuses an `agent` binding on one.
|
|
409
|
+
*/
|
|
410
|
+
personOnly?: Readonly<Record<string, string>>;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Props a control's schema is derived from, by `SchemaProps` key (every key but `options`,
|
|
414
|
+
* which `OptionsSource` gives): the prop of the component each comes from.
|
|
415
|
+
*/
|
|
416
|
+
export interface SchemaPropSources {
|
|
417
|
+
min?: string;
|
|
418
|
+
max?: string;
|
|
419
|
+
step?: string;
|
|
420
|
+
unit?: string;
|
|
421
|
+
wrap?: string;
|
|
422
|
+
minLength?: string;
|
|
423
|
+
maxLength?: string;
|
|
424
|
+
pattern?: string;
|
|
425
|
+
inputType?: string;
|
|
426
|
+
paintKinds?: string;
|
|
427
|
+
allowNone?: string;
|
|
428
|
+
clearable?: string;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* A tier 2 mapping (ADR-0226 §2.3): how an app binds the controls of a third-party design
|
|
432
|
+
* system it does not own (MUI, Mantine, shadcn/Radix). It is a declaration, not handler code:
|
|
433
|
+
* `oui generate` emits one module per mapping into `<out>/bound/`. Each wrapper accepts
|
|
434
|
+
* `agent`, calls `useAgentBinding` with the app's own callback, returns that callback's result
|
|
435
|
+
* (§2.2 rule 3), and renders the third-party component unchanged. The emitted module ships its
|
|
436
|
+
* own control table and is treated exactly like a tier 1 package. On an enforced page,
|
|
437
|
+
* importing a mapped component straight from the third-party package fails the build.
|
|
438
|
+
*/
|
|
439
|
+
export interface Tier2Mapping {
|
|
440
|
+
$schema?: string;
|
|
441
|
+
/** The third-party package the controls are imported from (`@mantine/core`). */
|
|
442
|
+
package: string;
|
|
443
|
+
/** Each mapped export, by its export name in that package. */
|
|
444
|
+
controls: Readonly<Record<string, Tier2Control>>;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Where the new value is in the callback's arguments: `{ "arg": 0 }` for Mantine's
|
|
448
|
+
* `onChange(value)`, `{ "arg": 1 }` for MUI's `onChange(event, value)`, and `{ "arg": 0,
|
|
449
|
+
* "path": "target.value" }` for a native-style event. The wrapper builds those arguments when
|
|
450
|
+
* the assistant sets the value, and reads them back when the person does.
|
|
451
|
+
*/
|
|
452
|
+
export interface ValueFrom {
|
|
453
|
+
/** The argument's position. */
|
|
454
|
+
arg: number;
|
|
455
|
+
/** A dotted path into that argument. */
|
|
456
|
+
path?: string;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* One part of a control exported under a namespace: the export path of that part
|
|
460
|
+
* (`Select.Root`, `Select.Item`, `Tabs.Tab`). A path is an export of the package, or one member
|
|
461
|
+
* of one (one dot at most).
|
|
462
|
+
*/
|
|
463
|
+
export interface Tier2Part {
|
|
464
|
+
/**
|
|
465
|
+
* The part's export path: an export of the package, or one member of it, dotted
|
|
466
|
+
* (`Select.Item`).
|
|
467
|
+
*/
|
|
468
|
+
export: string;
|
|
469
|
+
/** On an item part: the prop that is the option's value. */
|
|
470
|
+
valueProp?: string;
|
|
471
|
+
/**
|
|
472
|
+
* On an item part: the props, in order, that give the option's title. `children` means its
|
|
473
|
+
* text.
|
|
474
|
+
*/
|
|
475
|
+
titleProps?: readonly string[];
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* One mapped control. The bound wrapper reports the component's `disabled` prop, so a control
|
|
479
|
+
* the page disables is not offered (a disabled job control is still followed until its job
|
|
480
|
+
* settles).
|
|
481
|
+
*/
|
|
482
|
+
export interface Tier2Control {
|
|
483
|
+
kind: AnyControlKind;
|
|
484
|
+
/**
|
|
485
|
+
* Props whose presence makes a use interactive. The first is the one a binding runs: for a
|
|
486
|
+
* value, with the arguments `valueFrom` describes; for a button or a dialog, with an
|
|
487
|
+
* event-shaped argument whose `isTrusted` is false.
|
|
488
|
+
*/
|
|
489
|
+
callbacks: readonly string[];
|
|
490
|
+
/** Required for every kind that takes a value (all but `button` and `dialog`). */
|
|
491
|
+
valueFrom?: ValueFrom;
|
|
492
|
+
/**
|
|
493
|
+
* The prop that shows the value. The generator reports every use of the control that does not
|
|
494
|
+
* pass it: there the handler would run, but the control would not show the new value.
|
|
495
|
+
*/
|
|
496
|
+
controlled?: string;
|
|
497
|
+
/** Where the options come from: the prop, and the keys of each option's value and title. */
|
|
498
|
+
options?: OptionsSource;
|
|
499
|
+
/** Props that give a default title, in order. `children` means the element's text. */
|
|
500
|
+
titleProps?: readonly string[];
|
|
501
|
+
/** Props the value schema is derived from, by `SchemaProps` key. */
|
|
502
|
+
schemaProps?: SchemaPropSources;
|
|
503
|
+
/** What the schema props are when the app leaves them out, as the component defaults them. */
|
|
504
|
+
defaults?: SchemaProps;
|
|
505
|
+
/**
|
|
506
|
+
* A control exported under a namespace (Radix `Switch.Root`) or made of parts (Radix
|
|
507
|
+
* `Select.Root` / `Select.Item`, Mantine `Tabs` / `Tabs.Tab`): its `root`, which takes the
|
|
508
|
+
* callbacks, and, when the options are the items it renders, its `item`. The bound module
|
|
509
|
+
* keeps every other member of each namespace (`Select.Trigger`, `Tabs.List`).
|
|
510
|
+
*/
|
|
511
|
+
parts?: {
|
|
512
|
+
root: Tier2Part;
|
|
513
|
+
item?: Tier2Part;
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* A room catalog as plain data (ADR-0220 §2.3, tier 3 of ADR-0226): what a room with its own
|
|
518
|
+
* editing model — a canvas, a chart, a timeline, a player — declares about everything a person
|
|
519
|
+
* can do in it, so the assistant's actions and knowledge are generated from the room's code.
|
|
520
|
+
* Every declaration, none of the functions: a room's package writes it as `agent-catalog.json`
|
|
521
|
+
* (named in `package.json` under `oui.agentCatalog`) so a build-time generator reads the
|
|
522
|
+
* catalog without loading React or the room's code; an app's own catalog is read through the
|
|
523
|
+
* app's Vite config.
|
|
524
|
+
*
|
|
525
|
+
* - **actions**: its operations, each carried out through the room's own reducer and commands,
|
|
526
|
+
* with a JSON schema for the input;
|
|
527
|
+
* - **fields**: its inspector's fields, each with its value's schema, unit, range, its
|
|
528
|
+
* animation where the room has a timeline, and which kinds of thing it applies to;
|
|
529
|
+
* - **commands**: its keymap, each command with its keys and what it does;
|
|
530
|
+
* - **observations**: what the host reports about the room's state, including the problems it
|
|
531
|
+
* has drawing it.
|
|
532
|
+
*
|
|
533
|
+
* A room derives each action's input from the schema its reducer already validates with
|
|
534
|
+
* (`z.toJSONSchema`) and re-checks input with the same schema before applying it.
|
|
535
|
+
*/
|
|
536
|
+
export interface RoomCatalogData {
|
|
537
|
+
/** The room's id: the surface id its assistant surface is published under (`room:<id>`). */
|
|
538
|
+
room: string;
|
|
539
|
+
title: string;
|
|
540
|
+
/** What the room is for, in one or two sentences. */
|
|
541
|
+
description: string;
|
|
542
|
+
actions: readonly RoomActionData[];
|
|
543
|
+
fields: readonly RoomFieldData[];
|
|
544
|
+
commands: readonly RoomCommand[];
|
|
545
|
+
observations: readonly RoomObservation[];
|
|
546
|
+
/**
|
|
547
|
+
* The kinds of problem it reports, in its own vocabulary. Default: the generic `problems`
|
|
548
|
+
* schema.
|
|
549
|
+
*/
|
|
550
|
+
problems?: readonly RoomProblemKind[];
|
|
551
|
+
/** Tasks its tools carry out together, which only the room knows. */
|
|
552
|
+
recipes?: readonly RoomRecipe[];
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* What every catalog entry says about itself. Knowledge is generated from these words alone.
|
|
556
|
+
*/
|
|
557
|
+
export interface RoomEntryInfo {
|
|
558
|
+
/** Stable, kebab-case, unique among the room's entries of its kind. */
|
|
559
|
+
id: string;
|
|
560
|
+
/** What the UI calls it: a button's label, a field's label, a command's name. */
|
|
561
|
+
title: string;
|
|
562
|
+
/** What it does, in a sentence or two, in the room's own terms. */
|
|
563
|
+
description: string;
|
|
564
|
+
/** Where a person does it: the tool, panel, button, key or gesture. */
|
|
565
|
+
control: string;
|
|
566
|
+
}
|
|
567
|
+
/** One operation of the room, without its `run`. */
|
|
568
|
+
export interface RoomActionData extends RoomEntryInfo {
|
|
569
|
+
kind: 'action';
|
|
570
|
+
/**
|
|
571
|
+
* An object schema: a tool's input is one, never a union at its top level. Its property
|
|
572
|
+
* descriptions are the parameters' documentation.
|
|
573
|
+
*/
|
|
574
|
+
input: JsonSchema;
|
|
575
|
+
/**
|
|
576
|
+
* What it changes: the document (`edit`), the selection, the view, files, backend data, a
|
|
577
|
+
* job, a transaction.
|
|
578
|
+
*/
|
|
579
|
+
effect: ActionEffect;
|
|
580
|
+
/**
|
|
581
|
+
* It removes or replaces something the person made; running it needs the person's approval
|
|
582
|
+
* (ADR-0228).
|
|
583
|
+
*/
|
|
584
|
+
destructive?: boolean;
|
|
585
|
+
}
|
|
586
|
+
/** Which inspector section a field is in, as the inspector titles it. */
|
|
587
|
+
export interface RoomSection {
|
|
588
|
+
id: string;
|
|
589
|
+
title: string;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* A field's animation, in a room with a timeline. Animation is a capability, not a requirement
|
|
593
|
+
* (ADR-0226 §2.6).
|
|
594
|
+
*/
|
|
595
|
+
export interface RoomFieldAnimation {
|
|
596
|
+
/** Set at the playhead, it is a keyframe there when the property is animated. */
|
|
597
|
+
keyframeable: boolean;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* One inspector field, without its `read` and `write`: what it shows for the selection, and
|
|
601
|
+
* what setting it does.
|
|
602
|
+
*/
|
|
603
|
+
export interface RoomFieldData extends RoomEntryInfo {
|
|
604
|
+
kind: 'field';
|
|
605
|
+
section: RoomSection;
|
|
606
|
+
/**
|
|
607
|
+
* The kinds of thing it applies to, in the room's vocabulary (`text`, `shape`, `artboard`…).
|
|
608
|
+
*/
|
|
609
|
+
appliesTo: readonly string[];
|
|
610
|
+
/**
|
|
611
|
+
* The value's schema: its type, range (`minimum`/`maximum`), options (`enum`) and unit
|
|
612
|
+
* (`x-unit`).
|
|
613
|
+
*/
|
|
614
|
+
value: JsonSchema;
|
|
615
|
+
/** How it animates, in a room with a timeline. A room without one leaves it out. */
|
|
616
|
+
animation?: RoomFieldAnimation;
|
|
617
|
+
/** Deprecated since oui-bindings 0.8: `animation: { keyframeable }`. Read for one minor. */
|
|
618
|
+
keyframeable?: boolean;
|
|
619
|
+
}
|
|
620
|
+
/** One keymap command: what its key does. */
|
|
621
|
+
export interface RoomCommand extends RoomEntryInfo {
|
|
622
|
+
kind: 'command';
|
|
623
|
+
/** The group the room lists it under: tools, objects, edit, view. */
|
|
624
|
+
group: string;
|
|
625
|
+
/** Its keys as a person reads them (`⇧⌘G`). Empty when it has none. */
|
|
626
|
+
keys: readonly string[];
|
|
627
|
+
/**
|
|
628
|
+
* `reserved`: its key is kept for a feature that is not built; it does nothing. Never
|
|
629
|
+
* offered.
|
|
630
|
+
*/
|
|
631
|
+
status: 'available' | 'reserved';
|
|
632
|
+
/** Options the command takes beyond the selection (a nudge's direction). */
|
|
633
|
+
options?: JsonSchema;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Something the room reports about its state: the document, what is selected, or the problems
|
|
637
|
+
* it has drawing it. The host pushes the value; the catalog declares what it means.
|
|
638
|
+
*/
|
|
639
|
+
export interface RoomObservation {
|
|
640
|
+
id: string;
|
|
641
|
+
description: string;
|
|
642
|
+
schema: JsonSchema;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* One kind of problem a room or page reports, in its own vocabulary (`missing-font`,
|
|
646
|
+
* `order-rejected`): the kind, and what it means.
|
|
647
|
+
*/
|
|
648
|
+
export interface RoomProblemKind {
|
|
649
|
+
kind: string;
|
|
650
|
+
description: string;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* A task the room's own tools carry out together, declared by the room because only it knows
|
|
654
|
+
* the task (animating a property, placing an order). The generator turns it into a knowledge
|
|
655
|
+
* recipe and ends it with reading what the room reports.
|
|
656
|
+
*
|
|
657
|
+
* In `name`, `trigger` and each step, `{room}` is the room's title, and these name the tool
|
|
658
|
+
* that does a step, checked against the catalog when the knowledge is generated:
|
|
659
|
+
* - `{action:<id>}`: the action's tool;
|
|
660
|
+
* - `{command:<id>}`: the command, run with the `run-command` action;
|
|
661
|
+
* - `{field:<id>}`: the field, set with the `set-properties` action;
|
|
662
|
+
* - `{keyframeable}`: the ids of the fields that animate.
|
|
663
|
+
*/
|
|
664
|
+
export interface RoomRecipe {
|
|
665
|
+
name: string;
|
|
666
|
+
trigger: string;
|
|
667
|
+
steps: readonly string[];
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* A problem a room or page has drawing or reading what the person is working on: a face it
|
|
671
|
+
* cannot load, text it therefore does not draw, an asset that failed, something an import could
|
|
672
|
+
* not reproduce. Reported in a `problems` observation, so an assistant sees what the person
|
|
673
|
+
* sees in the banners.
|
|
674
|
+
*/
|
|
675
|
+
export interface RoomProblem {
|
|
676
|
+
/** `missing-font`, `font-error`, `unsupported-import`, `asset-failed`, `access-required`… */
|
|
677
|
+
kind: string;
|
|
678
|
+
/** The room's own words for it, as its banner says it. */
|
|
679
|
+
message: string;
|
|
680
|
+
/** Ids of the things not drawn because of it. */
|
|
681
|
+
hides?: readonly string[];
|
|
682
|
+
/**
|
|
683
|
+
* How the person resolves it in the room: an action of this catalog, and the choices it
|
|
684
|
+
* offers.
|
|
685
|
+
*/
|
|
686
|
+
resolve?: {
|
|
687
|
+
action: string;
|
|
688
|
+
choices?: readonly Readonly<Record<string, unknown>>[];
|
|
689
|
+
};
|
|
690
|
+
/** Anything else that names the problem precisely (the face, the element). */
|
|
691
|
+
detail?: Readonly<Record<string, unknown>>;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* What running a catalog entry or a bound control did: its data, or why it could not be done,
|
|
695
|
+
* in words a person would read. `pending` says the work outlives the call: a job was started
|
|
696
|
+
* and is done only when its completion arrives (an action whose effect is `job` or
|
|
697
|
+
* `transaction`). Every binding's `run` returns what the consumer's callback returned (ADR-0226
|
|
698
|
+
* §2.2 rule 3, #209), so a handler's `{ ok, pending: { jobId } }` reaches the runtime.
|
|
699
|
+
*/
|
|
700
|
+
export type RoomResult = {
|
|
701
|
+
ok: true;
|
|
702
|
+
data?: Readonly<Record<string, unknown>>;
|
|
703
|
+
pending?: {
|
|
704
|
+
jobId: string;
|
|
705
|
+
};
|
|
706
|
+
} | {
|
|
707
|
+
ok: false;
|
|
708
|
+
code: string;
|
|
709
|
+
message: string;
|
|
710
|
+
};
|
|
711
|
+
/**
|
|
712
|
+
* Where a room package names its catalog, under `oui.agentCatalog` in its `package.json`
|
|
713
|
+
* (`closure.agentCatalog` is read during the transition). `hosts` are the exported components
|
|
714
|
+
* that mount the room (and register it); a page that renders one has the room's surface.
|
|
715
|
+
*
|
|
716
|
+
* ```json
|
|
717
|
+
* "oui": { "agentCatalog": { "path": "./dist/agent-catalog.json", "hosts": ["VectorStudioRoom"] } }
|
|
718
|
+
* ```
|
|
719
|
+
*/
|
|
720
|
+
export interface AgentCatalogManifestEntry {
|
|
721
|
+
path: string;
|
|
722
|
+
hosts: string[];
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* What the generator emits for each build (`oui-manifest.json`, ADR-0220 §2.4–2.5): every
|
|
726
|
+
* surface, action and observation the build's UI offers. The runtime (`connectBindings`) offers
|
|
727
|
+
* the intersection of the manifest and the handlers mounted right now, so an action the build
|
|
728
|
+
* declares is a tool only while its control, or its room, is on screen. CI regenerates it and
|
|
729
|
+
* diffs it (`oui generate --check`).
|
|
730
|
+
*/
|
|
731
|
+
export interface OuiManifest {
|
|
732
|
+
/**
|
|
733
|
+
* The contract major (`MANIFEST_VERSION`). A breaking change to any of these schemas bumps
|
|
734
|
+
* it.
|
|
735
|
+
*/
|
|
736
|
+
version: 1;
|
|
737
|
+
/**
|
|
738
|
+
* A hash of everything else in the manifest and the knowledge: the build's identity to the
|
|
739
|
+
* assistant.
|
|
740
|
+
*/
|
|
741
|
+
buildId: string;
|
|
742
|
+
surfaces: readonly ManifestSurface[];
|
|
743
|
+
}
|
|
744
|
+
/** One step of the way a person reaches a capability. */
|
|
745
|
+
export type ReachStep = {
|
|
746
|
+
kind: 'route';
|
|
747
|
+
path: string;
|
|
748
|
+
title: string;
|
|
749
|
+
nav?: string;
|
|
750
|
+
} | {
|
|
751
|
+
kind: 'tab';
|
|
752
|
+
binding: string;
|
|
753
|
+
value: string | number;
|
|
754
|
+
title: string;
|
|
755
|
+
} | {
|
|
756
|
+
kind: 'dialog';
|
|
757
|
+
binding?: string;
|
|
758
|
+
title: string;
|
|
759
|
+
openedBy: readonly string[];
|
|
760
|
+
} | {
|
|
761
|
+
kind: 'panel';
|
|
762
|
+
title: string;
|
|
763
|
+
openedBy: readonly string[];
|
|
764
|
+
} | {
|
|
765
|
+
kind: 'menu';
|
|
766
|
+
title: string;
|
|
767
|
+
} | {
|
|
768
|
+
kind: 'room';
|
|
769
|
+
room: string;
|
|
770
|
+
where: string;
|
|
771
|
+
selection?: readonly string[];
|
|
772
|
+
};
|
|
773
|
+
/**
|
|
774
|
+
* Where an action comes from: a bound control, a room's catalog entry, or the generated
|
|
775
|
+
* navigation.
|
|
776
|
+
*/
|
|
777
|
+
export type ManifestActionSource = 'control' | 'room-action' | 'navigation';
|
|
778
|
+
/** One action a surface offers: one tool. */
|
|
779
|
+
export interface ManifestAction {
|
|
780
|
+
/** The tool name: unique across the build. */
|
|
781
|
+
name: string;
|
|
782
|
+
/** The binding id, or `<room>/<kind>/<entry>` for a room's. */
|
|
783
|
+
id: string;
|
|
784
|
+
source: ManifestActionSource;
|
|
785
|
+
/** The control kind, for a control: a built-in one, or one its design system registers. */
|
|
786
|
+
control?: AnyControlKind;
|
|
787
|
+
title: string;
|
|
788
|
+
description: string;
|
|
789
|
+
/** The tool's input: one object schema, never a union at its top level. */
|
|
790
|
+
input: JsonSchema;
|
|
791
|
+
/**
|
|
792
|
+
* What running it does. A `job` or `transaction` settles on its outcome (`JobSettlement`); a
|
|
793
|
+
* `transaction`, or a destructive `write`, runs only on the person's approval of the exact
|
|
794
|
+
* call.
|
|
795
|
+
*/
|
|
796
|
+
effect?: ActionEffect;
|
|
797
|
+
destructive?: boolean;
|
|
798
|
+
/**
|
|
799
|
+
* It changes what the person is working in (account, project, role): the assistant asks
|
|
800
|
+
* first.
|
|
801
|
+
*/
|
|
802
|
+
confirm?: boolean;
|
|
803
|
+
/** One of a list's rows: the action takes the row as `item`. */
|
|
804
|
+
itemized?: boolean;
|
|
805
|
+
/** How a person gets to it, from the page. */
|
|
806
|
+
reach: readonly ReachStep[];
|
|
807
|
+
/** The source file that declares it, relative to the app. */
|
|
808
|
+
declaredIn?: string;
|
|
809
|
+
}
|
|
810
|
+
/** One observation a surface reports: its id, what it means, and its value's schema. */
|
|
811
|
+
export interface ManifestObservation {
|
|
812
|
+
id: string;
|
|
813
|
+
description: string;
|
|
814
|
+
schema: JsonSchema;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* A page, a room on a page, a component shared by pages, the app's frame around the pages
|
|
818
|
+
* (`shell`, from `oui.config.json`'s `shell` entries), or the app's pages themselves: going to
|
|
819
|
+
* one by address (`navigation`).
|
|
820
|
+
*/
|
|
821
|
+
export type ManifestSurfaceKind = 'page' | 'room' | 'shared' | 'shell' | 'navigation';
|
|
822
|
+
/** One surface: what it offers, where it can be mounted, and what it reports. */
|
|
823
|
+
export interface ManifestSurface {
|
|
824
|
+
/**
|
|
825
|
+
* `page:VoicesPage`, `room:vector-studio`, `shared:MoveToProjectModal`, `shell:StudioShell`,
|
|
826
|
+
* `app:navigation`.
|
|
827
|
+
*/
|
|
828
|
+
id: string;
|
|
829
|
+
kind: ManifestSurfaceKind;
|
|
830
|
+
title: string;
|
|
831
|
+
description: string;
|
|
832
|
+
/** The route patterns where it can be mounted. */
|
|
833
|
+
routes: readonly string[];
|
|
834
|
+
actions: readonly ManifestAction[];
|
|
835
|
+
observations: readonly ManifestObservation[];
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* The knowledge the generator emits with the manifest (`oui-knowledge.json`, ADR-0220 §2.5),
|
|
839
|
+
* from the same declarations: the map of the app, every page in full with its relationships and
|
|
840
|
+
* recipes, and the app's frame. No word of it is written by hand. Each turn carries the part
|
|
841
|
+
* for the page the person is on (`resolveKnowledge`): the map, the frame parts around that
|
|
842
|
+
* page, the page in full, and one paragraph for each adjacent page.
|
|
843
|
+
*/
|
|
844
|
+
export interface GeneratedKnowledge {
|
|
845
|
+
/** The contract major (`MANIFEST_VERSION`). */
|
|
846
|
+
version: 1;
|
|
847
|
+
/** The manifest's build id: the two are one build. */
|
|
848
|
+
buildId: string;
|
|
849
|
+
/** Every page, one line each: the map of the app. */
|
|
850
|
+
overview: KnowledgeEntry;
|
|
851
|
+
pages: readonly PageKnowledge[];
|
|
852
|
+
/**
|
|
853
|
+
* The app's frame around the pages (`shell` surfaces), each part with the route patterns it
|
|
854
|
+
* frames.
|
|
855
|
+
*/
|
|
856
|
+
frames?: readonly PageKnowledge[];
|
|
857
|
+
}
|
|
858
|
+
/** One block of knowledge, as the assistant's prompt shows it. */
|
|
859
|
+
export interface KnowledgeEntry {
|
|
860
|
+
title: string;
|
|
861
|
+
content: string;
|
|
862
|
+
}
|
|
863
|
+
/** A task recipe the UI implies, as the assistant's prompt shows a workflow. */
|
|
864
|
+
export interface KnowledgeRecipe {
|
|
865
|
+
name: string;
|
|
866
|
+
trigger: string;
|
|
867
|
+
steps: readonly string[];
|
|
868
|
+
}
|
|
869
|
+
/** What the assistant knows of one page, or one part of the app's frame. */
|
|
870
|
+
export interface PageKnowledge {
|
|
871
|
+
/** The page surface this describes. */
|
|
872
|
+
surface: string;
|
|
873
|
+
routes: readonly string[];
|
|
874
|
+
/** One paragraph: what the page is for, for when the user is elsewhere. */
|
|
875
|
+
summary: KnowledgeEntry;
|
|
876
|
+
/** Everything the page and its rooms offer, where each thing is, and its parameters. */
|
|
877
|
+
detail: KnowledgeEntry;
|
|
878
|
+
/**
|
|
879
|
+
* Relationships derived from types: which fields apply to what, which animate, what leads
|
|
880
|
+
* where.
|
|
881
|
+
*/
|
|
882
|
+
relationships: KnowledgeEntry | null;
|
|
883
|
+
recipes: readonly KnowledgeRecipe[];
|
|
884
|
+
/** Page surfaces this page leads to or is reached from. */
|
|
885
|
+
adjacent: readonly string[];
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* `oui.config.json` at the app's root (ADR-0226 §2.4): where the app keeps its routes,
|
|
889
|
+
* navigation and output, which design systems and mappings its controls come from, where its
|
|
890
|
+
* API is described, and which of its pages are not yet bound. Paths are relative to the file.
|
|
891
|
+
* It is required and explicit: nothing an app depends on has a default, so a misconfigured app
|
|
892
|
+
* fails here, naming the setting, instead of generating an assistant that can do nothing. A
|
|
893
|
+
* setting the generator does not know is an error.
|
|
894
|
+
*/
|
|
895
|
+
export interface OuiConfigFile {
|
|
896
|
+
/** This schema's URL, for editors. */
|
|
897
|
+
$schema?: string;
|
|
898
|
+
$comment?: string;
|
|
899
|
+
/** The tsconfig the app's source compiles with. */
|
|
900
|
+
tsconfig: string;
|
|
901
|
+
/**
|
|
902
|
+
* The file whose routes decide where the app can go: `<Route>` elements (nested paths are
|
|
903
|
+
* joined to their parent, `index` routes kept, `React.lazy` followed) or a data router
|
|
904
|
+
* (`createBrowserRouter([...])`).
|
|
905
|
+
*/
|
|
906
|
+
routes: string;
|
|
907
|
+
/**
|
|
908
|
+
* Components a route's element is wrapped in that are never the page (`Suspense`,
|
|
909
|
+
* `ErrorBoundary`). Default none.
|
|
910
|
+
*/
|
|
911
|
+
routeWrappers?: readonly string[];
|
|
912
|
+
/**
|
|
913
|
+
* Files holding the navigation entries (`{ label, route, group }` object literals). Default
|
|
914
|
+
* none.
|
|
915
|
+
*/
|
|
916
|
+
nav?: readonly string[];
|
|
917
|
+
/** Where generated output goes. */
|
|
918
|
+
out: string;
|
|
919
|
+
/**
|
|
920
|
+
* Design-system packages whose controls carry bindings (tier 1). Each must resolve from the
|
|
921
|
+
* app and name its control table in its `package.json` (`oui.agentControls`). `[]`: every
|
|
922
|
+
* control is tier 2 or in a room.
|
|
923
|
+
*/
|
|
924
|
+
designSystem: readonly string[];
|
|
925
|
+
/**
|
|
926
|
+
* Tier 2 mappings (`tier2-mapping.json`), one per third-party design system the app does not
|
|
927
|
+
* own, by path. `oui generate` emits a bound module per mapping into `<out>/bound/` (named
|
|
928
|
+
* after the package: `@mantine/core` → `mantine-core.ts`, with its control table beside it),
|
|
929
|
+
* and reads every use of a bound control as it reads a tier 1 control. On an enforced page,
|
|
930
|
+
* importing a mapped control straight from its package is an error naming the bound import. A
|
|
931
|
+
* package is in `designSystem` or mapped, never both. Default none.
|
|
932
|
+
*/
|
|
933
|
+
mappings?: readonly string[];
|
|
934
|
+
/**
|
|
935
|
+
* The API's OpenAPI 3 document, by module path, as the installed API client ships it
|
|
936
|
+
* (`@traidr/api-client/openapi.json`) — never a sibling checkout path, so the generator reads
|
|
937
|
+
* exactly the spec of the client version the app installs; or a path inside the app. Every
|
|
938
|
+
* `mutate` effect names one of its `operationId`s. `null`: the app declares no API, and a
|
|
939
|
+
* `mutate` effect is an error.
|
|
940
|
+
*/
|
|
941
|
+
apiSpec: string | null;
|
|
942
|
+
/**
|
|
943
|
+
* Page components whose interactive controls are not all bound yet. It may only get shorter:
|
|
944
|
+
* the generator fails for a listed page that is fully bound, so the list cannot rot. Every
|
|
945
|
+
* other page is enforced. Default none.
|
|
946
|
+
*/
|
|
947
|
+
unbound?: readonly string[];
|
|
948
|
+
/**
|
|
949
|
+
* Room catalogs the app itself declares (tier 3, a page's own editor), each loaded through
|
|
950
|
+
* the app's own Vite config so its modules resolve as the app build resolves them: the app
|
|
951
|
+
* needs `vite` among its own dependencies. Only their declarations are read. Default none.
|
|
952
|
+
*/
|
|
953
|
+
appCatalogs?: readonly AppCatalogEntry[];
|
|
954
|
+
/**
|
|
955
|
+
* The app's frame: components mounted around the pages rather than by a route (a sidebar, a
|
|
956
|
+
* top bar, a phone tab bar, a toast host). Each becomes a `shell:` surface offered on the
|
|
957
|
+
* routes it frames, and its controls are enforced as a page's are, unless listed in
|
|
958
|
+
* `unbound`. Default none.
|
|
959
|
+
*/
|
|
960
|
+
shell?: readonly ShellEntry[];
|
|
961
|
+
}
|
|
962
|
+
/** One part of the app's frame. */
|
|
963
|
+
export interface ShellEntry {
|
|
964
|
+
/** The module, relative to the app root. */
|
|
965
|
+
module: string;
|
|
966
|
+
/** The export that is the frame's component. */
|
|
967
|
+
export: string;
|
|
968
|
+
/** The route patterns it frames. Default every route (`*`). */
|
|
969
|
+
routes?: readonly string[];
|
|
970
|
+
}
|
|
971
|
+
/** A room catalog the app declares. */
|
|
972
|
+
export interface AppCatalogEntry {
|
|
973
|
+
/** The module, relative to the app root. */
|
|
974
|
+
module: string;
|
|
975
|
+
/** The export that is the catalog. */
|
|
976
|
+
export: string;
|
|
977
|
+
/** App components whose use puts the room on a page. */
|
|
978
|
+
hosts: readonly string[];
|
|
979
|
+
}
|
|
980
|
+
/** SHA-256 of the RFC 8785 canonical JSON of a call's arguments, lowercase hex. */
|
|
981
|
+
export type ArgsHash = string;
|
|
982
|
+
/**
|
|
983
|
+
* Where the person confirmed. In a UI only a click on the card counts (`ui`); in a conversation
|
|
984
|
+
* channel, the verbatim readback and an affirmative next turn (ADR-0210 §2.6).
|
|
985
|
+
*/
|
|
986
|
+
export type ApprovalChannel = 'ui' | 'voice' | 'phone' | 'sms' | 'chat';
|
|
987
|
+
export type ApprovalDecision = 'approve' | 'decline';
|
|
988
|
+
/**
|
|
989
|
+
* One argument of the call, as the person reads it: its declared label and its value in words.
|
|
990
|
+
*/
|
|
991
|
+
export interface ApprovalPreviewArgument {
|
|
992
|
+
/** The argument's name in the call. */
|
|
993
|
+
name: string;
|
|
994
|
+
/** Its label, from the action's input schema. */
|
|
995
|
+
label: string;
|
|
996
|
+
/** Its value, as text. */
|
|
997
|
+
value: string;
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* What the person is asked to approve. Every word comes from the action's declaration (its
|
|
1001
|
+
* title, description and input schema labels), never from the model (ADR-0228 §2.2).
|
|
1002
|
+
*/
|
|
1003
|
+
export interface ApprovalPreview {
|
|
1004
|
+
title: string;
|
|
1005
|
+
/** What running it does, from the declaration. */
|
|
1006
|
+
consequence?: string;
|
|
1007
|
+
arguments: Array<ApprovalPreviewArgument>;
|
|
1008
|
+
/**
|
|
1009
|
+
* One sentence composed from the fields above, read or sent verbatim on a conversation
|
|
1010
|
+
* channel.
|
|
1011
|
+
*/
|
|
1012
|
+
readback: string;
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* The effect the approval is for: the action's declared effect kind (ADR-0226 §2.6,
|
|
1016
|
+
* `transaction` for an irreversible external act), or `write` when it declares none.
|
|
1017
|
+
*/
|
|
1018
|
+
export type ApprovalEffect = string;
|
|
1019
|
+
/**
|
|
1020
|
+
* A call waiting for the person's approval, as the worker stores it (`POST
|
|
1021
|
+
* /internal/approvals`).
|
|
1022
|
+
*/
|
|
1023
|
+
export interface PendingApprovalInput {
|
|
1024
|
+
/** Equals the tool call id. */
|
|
1025
|
+
approvalId: string;
|
|
1026
|
+
toolCallId: string;
|
|
1027
|
+
conversationId: string;
|
|
1028
|
+
turnId: string;
|
|
1029
|
+
/** The user whose turn made the call: the only one who may decide it. */
|
|
1030
|
+
userId: string;
|
|
1031
|
+
tool: string;
|
|
1032
|
+
args: {
|
|
1033
|
+
[key: string]: unknown;
|
|
1034
|
+
};
|
|
1035
|
+
/** `argsHash(args)`; the store checks it. */
|
|
1036
|
+
argsHash: ArgsHash;
|
|
1037
|
+
effect: ApprovalEffect;
|
|
1038
|
+
destructive: boolean;
|
|
1039
|
+
/**
|
|
1040
|
+
* Whether the arguments may be written to logs. They are only when the declaration says they
|
|
1041
|
+
* are not sensitive.
|
|
1042
|
+
*/
|
|
1043
|
+
argsSensitive: boolean;
|
|
1044
|
+
/** Epoch ms, at most 30 minutes away (`MAX_APPROVAL_TTL_MS`). */
|
|
1045
|
+
expiresAt: number;
|
|
1046
|
+
preview: ApprovalPreview;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* `agent:approval_required`: the worker stopped the turn at a call that needs the person's
|
|
1050
|
+
* approval. The approval card renders it.
|
|
1051
|
+
*/
|
|
1052
|
+
export interface ApprovalRequiredEvent {
|
|
1053
|
+
turnId: string;
|
|
1054
|
+
conversationId: string;
|
|
1055
|
+
approvalId: string;
|
|
1056
|
+
tool: string;
|
|
1057
|
+
effect: ApprovalEffect;
|
|
1058
|
+
destructive: boolean;
|
|
1059
|
+
preview: ApprovalPreview;
|
|
1060
|
+
expiresAt: number;
|
|
1061
|
+
timestamp: number;
|
|
1062
|
+
}
|
|
1063
|
+
/** `approval:decide`, from the person's own socket: the card's click. */
|
|
1064
|
+
export interface ApprovalDecidePayload {
|
|
1065
|
+
approvalId: string;
|
|
1066
|
+
decision: ApprovalDecision;
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Why an approval was refused:
|
|
1070
|
+
*
|
|
1071
|
+
* - `unknown`: no such pending approval: never stored, already declined or redeemed, or expired
|
|
1072
|
+
* and gone.
|
|
1073
|
+
* - `forbidden`: another user's approval, or another conversation's.
|
|
1074
|
+
* - `expired`.
|
|
1075
|
+
* - `decided`: already decided.
|
|
1076
|
+
* - `used`: already redeemed.
|
|
1077
|
+
* - `invalid`: not a token this environment signed, or malformed.
|
|
1078
|
+
* - `mismatch`: signed, but not for the stored call.
|
|
1079
|
+
* - `channel`: a decision from a channel that may not make it.
|
|
1080
|
+
*/
|
|
1081
|
+
export type ApprovalRefusalReason = 'unknown' | 'forbidden' | 'expired' | 'decided' | 'used' | 'invalid' | 'mismatch' | 'channel';
|
|
1082
|
+
export interface ApprovalRefusal {
|
|
1083
|
+
ok: false;
|
|
1084
|
+
reason: ApprovalRefusalReason;
|
|
1085
|
+
error: string;
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* The answer to a decision. An approval's token goes only to the decider: the socket that
|
|
1089
|
+
* clicked, or the engine that asked.
|
|
1090
|
+
*/
|
|
1091
|
+
export type ApprovalDecideResult = {
|
|
1092
|
+
ok: true;
|
|
1093
|
+
decision: 'approve';
|
|
1094
|
+
approvalId: string;
|
|
1095
|
+
/** The single-use token the continuation turn redeems. */
|
|
1096
|
+
token: string;
|
|
1097
|
+
/** What the browser checks a UI action's params against before it runs it. */
|
|
1098
|
+
argsHash: ArgsHash;
|
|
1099
|
+
expiresAt: number;
|
|
1100
|
+
channel: ApprovalChannel;
|
|
1101
|
+
} | {
|
|
1102
|
+
ok: true;
|
|
1103
|
+
decision: 'decline';
|
|
1104
|
+
approvalId: string;
|
|
1105
|
+
} | ApprovalRefusal;
|
|
1106
|
+
/** The token's claims: a compact JWS (HS256), signed with the environment's approval key. */
|
|
1107
|
+
export interface ApprovalTokenClaims {
|
|
1108
|
+
/** The approval id, which is the tool call id. */
|
|
1109
|
+
aid: string;
|
|
1110
|
+
/** The user. */
|
|
1111
|
+
sub: string;
|
|
1112
|
+
/** The conversation. */
|
|
1113
|
+
cid: string;
|
|
1114
|
+
tool: string;
|
|
1115
|
+
/** The args hash. */
|
|
1116
|
+
ah: ArgsHash;
|
|
1117
|
+
/** The effect. */
|
|
1118
|
+
eff: ApprovalEffect;
|
|
1119
|
+
/** Where the user confirmed. */
|
|
1120
|
+
ch: ApprovalChannel;
|
|
1121
|
+
/** Issued at, epoch seconds. */
|
|
1122
|
+
iat: number;
|
|
1123
|
+
/** Expires at, epoch seconds. */
|
|
1124
|
+
exp: number;
|
|
1125
|
+
/** A nonce. */
|
|
1126
|
+
jti: string;
|
|
1127
|
+
}
|
|
1128
|
+
/** What redeeming a token returns: the stored call, exactly, for the worker to run. */
|
|
1129
|
+
export interface ApprovedCall {
|
|
1130
|
+
approvalId: string;
|
|
1131
|
+
toolCallId: string;
|
|
1132
|
+
conversationId: string;
|
|
1133
|
+
turnId: string;
|
|
1134
|
+
userId: string;
|
|
1135
|
+
tool: string;
|
|
1136
|
+
args: {
|
|
1137
|
+
[key: string]: unknown;
|
|
1138
|
+
};
|
|
1139
|
+
argsHash: ArgsHash;
|
|
1140
|
+
effect: ApprovalEffect;
|
|
1141
|
+
destructive: boolean;
|
|
1142
|
+
channel: ApprovalChannel;
|
|
1143
|
+
}
|
|
1144
|
+
export type ApprovalRedeemResult = {
|
|
1145
|
+
ok: true;
|
|
1146
|
+
call: ApprovedCall;
|
|
1147
|
+
} | ApprovalRefusal;
|
|
1148
|
+
/** An approval's state, for the turn that follows a decision. */
|
|
1149
|
+
export interface ApprovalStatus {
|
|
1150
|
+
approvalId: string;
|
|
1151
|
+
status: 'pending' | 'approved' | 'declined';
|
|
1152
|
+
tool: string;
|
|
1153
|
+
title: string;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* What a turn that follows a decision carries, outside the message text: the token to redeem,
|
|
1157
|
+
* or that the person declined.
|
|
1158
|
+
*/
|
|
1159
|
+
export type ApprovalContinuation = {
|
|
1160
|
+
approvalId: string;
|
|
1161
|
+
decision: 'approve';
|
|
1162
|
+
token: string;
|
|
1163
|
+
} | {
|
|
1164
|
+
approvalId: string;
|
|
1165
|
+
decision: 'decline';
|
|
1166
|
+
};
|
|
1167
|
+
/**
|
|
1168
|
+
* What a UI action request carries when it runs an approved call (`OUIActionApproval`): the
|
|
1169
|
+
* browser runs a `transaction` or destructive action only when this matches a grant this tab
|
|
1170
|
+
* received from its own card click (ADR-0228 §2.2.6).
|
|
1171
|
+
*/
|
|
1172
|
+
export interface ActionRequestApproval {
|
|
1173
|
+
approvalId: string;
|
|
1174
|
+
/** `argsHash(params)` of the request the user approved. */
|
|
1175
|
+
argsHash: ArgsHash;
|
|
1176
|
+
}
|
|
1177
|
+
/**
|
|
1178
|
+
* What the person's approval click gives this tab's OUI runtime (`runtime.grantApproval`,
|
|
1179
|
+
* `OUIApprovalGrant`): the request it approved, until it expires.
|
|
1180
|
+
*/
|
|
1181
|
+
export interface ApprovalGrant {
|
|
1182
|
+
approvalId: string;
|
|
1183
|
+
argsHash: ArgsHash;
|
|
1184
|
+
/** Epoch ms after which the grant no longer admits anything. */
|
|
1185
|
+
expiresAt: number;
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Every event a product emits over realtime: its payload schema, the rooms it is published to,
|
|
1189
|
+
* its correlation fields and its role in a job (ADR-0227 §2.4).
|
|
1190
|
+
*/
|
|
1191
|
+
export interface EventDeclarationDocument {
|
|
1192
|
+
$schema?: string;
|
|
1193
|
+
/** The version of this document's format. */
|
|
1194
|
+
version: 1;
|
|
1195
|
+
/** Who declares these events. */
|
|
1196
|
+
product: string;
|
|
1197
|
+
description?: string;
|
|
1198
|
+
/** Payload shapes the events share, referenced as `#/$defs/<Name>`. */
|
|
1199
|
+
$defs?: Readonly<Record<string, EventPayloadSchema>>;
|
|
1200
|
+
/** Every room these events go to, by name. */
|
|
1201
|
+
rooms: Readonly<Record<string, RoomDeclaration>>;
|
|
1202
|
+
/** Every event, by its name on the wire. */
|
|
1203
|
+
events: Readonly<Record<string, EventDeclaration>>;
|
|
1204
|
+
}
|
|
1205
|
+
/** The JSON Schema types a payload may use. */
|
|
1206
|
+
export type JsonType = 'object' | 'array' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
|
|
1207
|
+
/**
|
|
1208
|
+
* A JSON Schema (draft 2020-12). A payload may use any keyword; the platform reads `$ref` (to
|
|
1209
|
+
* the document's `$defs`), `allOf`, `type`, `properties` and `required` to find the fields it
|
|
1210
|
+
* correlates and reports on, and validates the rest with a full validator.
|
|
1211
|
+
*/
|
|
1212
|
+
export interface EventPayloadSchema {
|
|
1213
|
+
$ref?: string;
|
|
1214
|
+
/** A JSON Schema type name, or a list of them. */
|
|
1215
|
+
type?: JsonType | readonly JsonType[];
|
|
1216
|
+
description?: string;
|
|
1217
|
+
properties?: Readonly<Record<string, EventPayloadSchema>>;
|
|
1218
|
+
required?: readonly string[];
|
|
1219
|
+
/** `false`, or the schema every other property follows. */
|
|
1220
|
+
additionalProperties?: boolean | EventPayloadSchema;
|
|
1221
|
+
items?: EventPayloadSchema;
|
|
1222
|
+
enum?: readonly unknown[];
|
|
1223
|
+
const?: unknown;
|
|
1224
|
+
allOf?: readonly EventPayloadSchema[];
|
|
1225
|
+
anyOf?: readonly EventPayloadSchema[];
|
|
1226
|
+
oneOf?: readonly EventPayloadSchema[];
|
|
1227
|
+
[key: string]: unknown;
|
|
1228
|
+
}
|
|
1229
|
+
export interface RoomDeclaration {
|
|
1230
|
+
/**
|
|
1231
|
+
* The room's name with `{placeholder}`s for its ids, e.g. `generation:{jobId}`. An id is
|
|
1232
|
+
* letters, digits, `_` and `-`.
|
|
1233
|
+
*/
|
|
1234
|
+
pattern: string;
|
|
1235
|
+
description?: string;
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* What an event is for, as the platform acts on it:
|
|
1239
|
+
* - `completion`: a job of kind `completes` produced its result. A wait on the job ends well.
|
|
1240
|
+
* - `failure`: a job of kind `completes` ended without a result. A wait on the job ends with
|
|
1241
|
+
* its reason.
|
|
1242
|
+
* - `progress`: a job is still running. Nothing waits on it: resolving a wait on progress
|
|
1243
|
+
* reports a running job as done.
|
|
1244
|
+
* - `notice`: anything else a client is told.
|
|
1245
|
+
*/
|
|
1246
|
+
export type EventRole = 'completion' | 'failure' | 'progress' | 'notice';
|
|
1247
|
+
/** Where a settling event says why a job failed. */
|
|
1248
|
+
export interface FailureReason {
|
|
1249
|
+
/** The payload field carrying the reason. */
|
|
1250
|
+
field: string;
|
|
1251
|
+
/** What the reason is when the field is absent. */
|
|
1252
|
+
fallback: string;
|
|
1253
|
+
}
|
|
1254
|
+
export interface EventDeclaration {
|
|
1255
|
+
description: string;
|
|
1256
|
+
/**
|
|
1257
|
+
* The payload's JSON Schema: an object. `$ref`s point into the document's `$defs`. Every
|
|
1258
|
+
* correlation, result and reason field is one of its properties.
|
|
1259
|
+
*/
|
|
1260
|
+
payload: EventPayloadSchema;
|
|
1261
|
+
/**
|
|
1262
|
+
* The name generated code gives the payload type. Default: the event name in PascalCase
|
|
1263
|
+
* (`generation:completed` → `GenerationCompleted`).
|
|
1264
|
+
*/
|
|
1265
|
+
typeName?: string;
|
|
1266
|
+
/**
|
|
1267
|
+
* The rooms the event is published to: names from the document's `rooms`, or `turn` for the
|
|
1268
|
+
* room of the agent turn it belongs to (the host names that room in each turn).
|
|
1269
|
+
*/
|
|
1270
|
+
rooms: readonly string[];
|
|
1271
|
+
/**
|
|
1272
|
+
* The payload fields that say which job, or which resource, the event is about (e.g.
|
|
1273
|
+
* `jobId`). A completion or failure has exactly one.
|
|
1274
|
+
*/
|
|
1275
|
+
correlation: readonly string[];
|
|
1276
|
+
role: EventRole;
|
|
1277
|
+
/** For a completion or failure: the kind of job it settles. */
|
|
1278
|
+
completes?: string;
|
|
1279
|
+
/**
|
|
1280
|
+
* For a completion: the payload fields that are the job's result, as a follower reports them.
|
|
1281
|
+
*/
|
|
1282
|
+
result?: readonly string[];
|
|
1283
|
+
/** For a failure: where its reason is. */
|
|
1284
|
+
reason?: FailureReason;
|
|
1285
|
+
}
|
|
1286
|
+
//# sourceMappingURL=contract.d.ts.map
|