@otto-code/protocol 0.6.7 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-labels.d.ts +21 -0
- package/dist/agent-labels.js +66 -0
- package/dist/agent-types.d.ts +55 -0
- package/dist/agent-types.js +14 -0
- package/dist/generated/validation/ws-outbound.aot.js +38262 -31722
- package/dist/git-hosting.d.ts +2 -0
- package/dist/git-hosting.js +6 -0
- package/dist/messages.d.ts +7196 -430
- package/dist/messages.js +1872 -37
- package/dist/model-tiers.js +2 -0
- package/dist/orchestration.d.ts +172 -0
- package/dist/orchestration.js +226 -0
- package/dist/provider-config.d.ts +3 -1
- package/dist/provider-config.js +3 -0
- package/dist/validation/ws-outbound-schema-metadata.d.ts +1085 -15
- package/dist/widgets/bridge.d.ts +59 -0
- package/dist/widgets/bridge.js +87 -0
- package/dist/widgets/document.d.ts +18 -0
- package/dist/widgets/document.js +261 -0
- package/dist/widgets/icons.d.ts +20 -0
- package/dist/widgets/icons.js +90 -0
- package/dist/widgets/theme.d.ts +37 -0
- package/dist/widgets/theme.js +149 -0
- package/dist/widgets/types.d.ts +78 -0
- package/dist/widgets/types.js +88 -0
- package/package.json +1 -1
package/dist/model-tiers.js
CHANGED
|
@@ -24,6 +24,8 @@ export const KNOWN_MODEL_TIERS = {
|
|
|
24
24
|
// Opus variants are "deep", non-1M Opus and Sonnet are "standard", Haiku is
|
|
25
25
|
// "fast". Fable (1M, most powerful) is "deep".
|
|
26
26
|
"claude-fable-5": "deep",
|
|
27
|
+
"claude-opus-5[1m]": "deep",
|
|
28
|
+
"claude-opus-5": "standard",
|
|
27
29
|
"claude-opus-4-8[1m]": "deep",
|
|
28
30
|
"claude-opus-4-8": "standard",
|
|
29
31
|
"claude-opus-4-7[1m]": "deep",
|
package/dist/orchestration.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ export declare const RunPhaseCandidateSchema: z.ZodObject<{
|
|
|
67
67
|
summary: z.ZodOptional<z.ZodString>;
|
|
68
68
|
}, z.core.$loose>>;
|
|
69
69
|
summary: z.ZodOptional<z.ZodString>;
|
|
70
|
+
outputFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
70
71
|
}, z.core.$loose>;
|
|
71
72
|
export type RunPhaseCandidate = z.infer<typeof RunPhaseCandidateSchema>;
|
|
72
73
|
export declare const RunPhaseSchema: z.ZodObject<{
|
|
@@ -93,12 +94,18 @@ export declare const RunPhaseSchema: z.ZodObject<{
|
|
|
93
94
|
summary: z.ZodOptional<z.ZodString>;
|
|
94
95
|
}, z.core.$loose>>;
|
|
95
96
|
summary: z.ZodOptional<z.ZodString>;
|
|
97
|
+
outputFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
96
98
|
}, z.core.$loose>>>;
|
|
97
99
|
notes: z.ZodOptional<z.ZodString>;
|
|
100
|
+
skipReason: z.ZodOptional<z.ZodString>;
|
|
101
|
+
retryAttempts: z.ZodOptional<z.ZodNumber>;
|
|
102
|
+
timedOut: z.ZodOptional<z.ZodBoolean>;
|
|
98
103
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
99
104
|
completedAt: z.ZodOptional<z.ZodString>;
|
|
100
105
|
}, z.core.$loose>;
|
|
101
106
|
export type RunPhase = z.infer<typeof RunPhaseSchema>;
|
|
107
|
+
export declare const GRAPH_SKIP_REASONS: readonly ["condition", "upstream-skipped", "upstream-failed", "canceled"];
|
|
108
|
+
export type GraphSkipReason = (typeof GRAPH_SKIP_REASONS)[number];
|
|
102
109
|
export declare const RunSchema: z.ZodObject<{
|
|
103
110
|
id: z.ZodString;
|
|
104
111
|
title: z.ZodString;
|
|
@@ -133,8 +140,12 @@ export declare const RunSchema: z.ZodObject<{
|
|
|
133
140
|
summary: z.ZodOptional<z.ZodString>;
|
|
134
141
|
}, z.core.$loose>>;
|
|
135
142
|
summary: z.ZodOptional<z.ZodString>;
|
|
143
|
+
outputFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
136
144
|
}, z.core.$loose>>>;
|
|
137
145
|
notes: z.ZodOptional<z.ZodString>;
|
|
146
|
+
skipReason: z.ZodOptional<z.ZodString>;
|
|
147
|
+
retryAttempts: z.ZodOptional<z.ZodNumber>;
|
|
148
|
+
timedOut: z.ZodOptional<z.ZodBoolean>;
|
|
138
149
|
startedAt: z.ZodOptional<z.ZodString>;
|
|
139
150
|
completedAt: z.ZodOptional<z.ZodString>;
|
|
140
151
|
}, z.core.$loose>>>;
|
|
@@ -162,6 +173,30 @@ export declare const GraphInputSchema: z.ZodObject<{
|
|
|
162
173
|
defaultValue: z.ZodOptional<z.ZodString>;
|
|
163
174
|
}, z.core.$loose>;
|
|
164
175
|
export type GraphInput = z.infer<typeof GraphInputSchema>;
|
|
176
|
+
export declare const PromptTemplateSchema: z.ZodObject<{
|
|
177
|
+
id: z.ZodString;
|
|
178
|
+
name: z.ZodString;
|
|
179
|
+
description: z.ZodOptional<z.ZodString>;
|
|
180
|
+
content: z.ZodString;
|
|
181
|
+
variables: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
182
|
+
key: z.ZodString;
|
|
183
|
+
label: z.ZodString;
|
|
184
|
+
description: z.ZodOptional<z.ZodString>;
|
|
185
|
+
multiline: z.ZodOptional<z.ZodBoolean>;
|
|
186
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
187
|
+
defaultValue: z.ZodOptional<z.ZodString>;
|
|
188
|
+
}, z.core.$loose>>>;
|
|
189
|
+
snippet: z.ZodOptional<z.ZodBoolean>;
|
|
190
|
+
builtIn: z.ZodOptional<z.ZodBoolean>;
|
|
191
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
192
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
193
|
+
}, z.core.$loose>;
|
|
194
|
+
export type PromptTemplate = z.infer<typeof PromptTemplateSchema>;
|
|
195
|
+
export declare const NodePromptTemplateRefSchema: z.ZodObject<{
|
|
196
|
+
templateId: z.ZodString;
|
|
197
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
198
|
+
}, z.core.$loose>;
|
|
199
|
+
export type NodePromptTemplateRef = z.infer<typeof NodePromptTemplateRefSchema>;
|
|
165
200
|
export declare const GRAPH_NODE_KINDS: readonly ["orchestrator", "agent"];
|
|
166
201
|
export type GraphNodeKind = (typeof GRAPH_NODE_KINDS)[number];
|
|
167
202
|
export declare const GraphNodeLoopSchema: z.ZodObject<{
|
|
@@ -173,6 +208,47 @@ export declare const GraphNodeLoopSchema: z.ZodObject<{
|
|
|
173
208
|
}, z.core.$loose>>;
|
|
174
209
|
}, z.core.$loose>;
|
|
175
210
|
export type GraphNodeLoop = z.infer<typeof GraphNodeLoopSchema>;
|
|
211
|
+
export declare const GRAPH_OUTPUT_FIELD_TYPES: readonly ["string", "number", "boolean", "array"];
|
|
212
|
+
export type GraphOutputFieldType = (typeof GRAPH_OUTPUT_FIELD_TYPES)[number];
|
|
213
|
+
export declare const GraphOutputFieldSchema: z.ZodObject<{
|
|
214
|
+
key: z.ZodString;
|
|
215
|
+
type: z.ZodString;
|
|
216
|
+
description: z.ZodOptional<z.ZodString>;
|
|
217
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
218
|
+
}, z.core.$loose>;
|
|
219
|
+
export type GraphOutputField = z.infer<typeof GraphOutputFieldSchema>;
|
|
220
|
+
export declare const GraphNodeOutputSchema: z.ZodObject<{
|
|
221
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
222
|
+
key: z.ZodString;
|
|
223
|
+
type: z.ZodString;
|
|
224
|
+
description: z.ZodOptional<z.ZodString>;
|
|
225
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
226
|
+
}, z.core.$loose>>;
|
|
227
|
+
}, z.core.$loose>;
|
|
228
|
+
export type GraphNodeOutput = z.infer<typeof GraphNodeOutputSchema>;
|
|
229
|
+
export declare const GRAPH_QUERY_TOOL_KINDS: readonly ["command", "http-get", "file-read"];
|
|
230
|
+
export type GraphQueryToolKind = (typeof GRAPH_QUERY_TOOL_KINDS)[number];
|
|
231
|
+
export declare const GraphQueryToolSchema: z.ZodObject<{
|
|
232
|
+
name: z.ZodString;
|
|
233
|
+
description: z.ZodString;
|
|
234
|
+
kind: z.ZodString;
|
|
235
|
+
parameters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
236
|
+
key: z.ZodString;
|
|
237
|
+
type: z.ZodString;
|
|
238
|
+
description: z.ZodOptional<z.ZodString>;
|
|
239
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
240
|
+
}, z.core.$loose>>>;
|
|
241
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
242
|
+
url: z.ZodOptional<z.ZodString>;
|
|
243
|
+
path: z.ZodOptional<z.ZodString>;
|
|
244
|
+
}, z.core.$loose>;
|
|
245
|
+
export type GraphQueryTool = z.infer<typeof GraphQueryToolSchema>;
|
|
246
|
+
export declare const GraphNodeRetrySchema: z.ZodObject<{
|
|
247
|
+
maxAttempts: z.ZodNumber;
|
|
248
|
+
backoffMs: z.ZodNumber;
|
|
249
|
+
multiplier: z.ZodOptional<z.ZodNumber>;
|
|
250
|
+
}, z.core.$loose>;
|
|
251
|
+
export type GraphNodeRetry = z.infer<typeof GraphNodeRetrySchema>;
|
|
176
252
|
export declare const GraphNodeSchema: z.ZodObject<{
|
|
177
253
|
id: z.ZodString;
|
|
178
254
|
kind: z.ZodString;
|
|
@@ -180,6 +256,10 @@ export declare const GraphNodeSchema: z.ZodObject<{
|
|
|
180
256
|
role: z.ZodOptional<z.ZodString>;
|
|
181
257
|
prompt: z.ZodOptional<z.ZodString>;
|
|
182
258
|
promptFromInput: z.ZodOptional<z.ZodString>;
|
|
259
|
+
promptTemplate: z.ZodOptional<z.ZodObject<{
|
|
260
|
+
templateId: z.ZodString;
|
|
261
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
262
|
+
}, z.core.$loose>>;
|
|
183
263
|
autonomous: z.ZodOptional<z.ZodBoolean>;
|
|
184
264
|
loop: z.ZodOptional<z.ZodObject<{
|
|
185
265
|
times: z.ZodOptional<z.ZodNumber>;
|
|
@@ -189,6 +269,36 @@ export declare const GraphNodeSchema: z.ZodObject<{
|
|
|
189
269
|
max: z.ZodNumber;
|
|
190
270
|
}, z.core.$loose>>;
|
|
191
271
|
}, z.core.$loose>>;
|
|
272
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
273
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
274
|
+
key: z.ZodString;
|
|
275
|
+
type: z.ZodString;
|
|
276
|
+
description: z.ZodOptional<z.ZodString>;
|
|
277
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
278
|
+
}, z.core.$loose>>;
|
|
279
|
+
}, z.core.$loose>>;
|
|
280
|
+
access: z.ZodOptional<z.ZodString>;
|
|
281
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
282
|
+
queryTools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
283
|
+
name: z.ZodString;
|
|
284
|
+
description: z.ZodString;
|
|
285
|
+
kind: z.ZodString;
|
|
286
|
+
parameters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
287
|
+
key: z.ZodString;
|
|
288
|
+
type: z.ZodString;
|
|
289
|
+
description: z.ZodOptional<z.ZodString>;
|
|
290
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
291
|
+
}, z.core.$loose>>>;
|
|
292
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
293
|
+
url: z.ZodOptional<z.ZodString>;
|
|
294
|
+
path: z.ZodOptional<z.ZodString>;
|
|
295
|
+
}, z.core.$loose>>>;
|
|
296
|
+
retry: z.ZodOptional<z.ZodObject<{
|
|
297
|
+
maxAttempts: z.ZodNumber;
|
|
298
|
+
backoffMs: z.ZodNumber;
|
|
299
|
+
multiplier: z.ZodOptional<z.ZodNumber>;
|
|
300
|
+
}, z.core.$loose>>;
|
|
301
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
192
302
|
model: z.ZodOptional<z.ZodString>;
|
|
193
303
|
position: z.ZodOptional<z.ZodObject<{
|
|
194
304
|
x: z.ZodNumber;
|
|
@@ -196,10 +306,21 @@ export declare const GraphNodeSchema: z.ZodObject<{
|
|
|
196
306
|
}, z.core.$loose>>;
|
|
197
307
|
}, z.core.$loose>;
|
|
198
308
|
export type GraphNode = z.infer<typeof GraphNodeSchema>;
|
|
309
|
+
export declare const GraphEdgeConditionSchema: z.ZodObject<{
|
|
310
|
+
expression: z.ZodString;
|
|
311
|
+
}, z.core.$loose>;
|
|
312
|
+
export type GraphEdgeCondition = z.infer<typeof GraphEdgeConditionSchema>;
|
|
199
313
|
export declare const GraphEdgeSchema: z.ZodObject<{
|
|
200
314
|
id: z.ZodOptional<z.ZodString>;
|
|
201
315
|
from: z.ZodString;
|
|
202
316
|
to: z.ZodString;
|
|
317
|
+
fromPort: z.ZodOptional<z.ZodString>;
|
|
318
|
+
toPort: z.ZodOptional<z.ZodString>;
|
|
319
|
+
when: z.ZodOptional<z.ZodObject<{
|
|
320
|
+
expression: z.ZodString;
|
|
321
|
+
}, z.core.$loose>>;
|
|
322
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
323
|
+
label: z.ZodOptional<z.ZodString>;
|
|
203
324
|
}, z.core.$loose>;
|
|
204
325
|
export type GraphEdge = z.infer<typeof GraphEdgeSchema>;
|
|
205
326
|
export declare const OrchestrationGraphSchema: z.ZodObject<{
|
|
@@ -221,6 +342,10 @@ export declare const OrchestrationGraphSchema: z.ZodObject<{
|
|
|
221
342
|
role: z.ZodOptional<z.ZodString>;
|
|
222
343
|
prompt: z.ZodOptional<z.ZodString>;
|
|
223
344
|
promptFromInput: z.ZodOptional<z.ZodString>;
|
|
345
|
+
promptTemplate: z.ZodOptional<z.ZodObject<{
|
|
346
|
+
templateId: z.ZodString;
|
|
347
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
348
|
+
}, z.core.$loose>>;
|
|
224
349
|
autonomous: z.ZodOptional<z.ZodBoolean>;
|
|
225
350
|
loop: z.ZodOptional<z.ZodObject<{
|
|
226
351
|
times: z.ZodOptional<z.ZodNumber>;
|
|
@@ -230,6 +355,36 @@ export declare const OrchestrationGraphSchema: z.ZodObject<{
|
|
|
230
355
|
max: z.ZodNumber;
|
|
231
356
|
}, z.core.$loose>>;
|
|
232
357
|
}, z.core.$loose>>;
|
|
358
|
+
output: z.ZodOptional<z.ZodObject<{
|
|
359
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
360
|
+
key: z.ZodString;
|
|
361
|
+
type: z.ZodString;
|
|
362
|
+
description: z.ZodOptional<z.ZodString>;
|
|
363
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
364
|
+
}, z.core.$loose>>;
|
|
365
|
+
}, z.core.$loose>>;
|
|
366
|
+
access: z.ZodOptional<z.ZodString>;
|
|
367
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
368
|
+
queryTools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
369
|
+
name: z.ZodString;
|
|
370
|
+
description: z.ZodString;
|
|
371
|
+
kind: z.ZodString;
|
|
372
|
+
parameters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
373
|
+
key: z.ZodString;
|
|
374
|
+
type: z.ZodString;
|
|
375
|
+
description: z.ZodOptional<z.ZodString>;
|
|
376
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
377
|
+
}, z.core.$loose>>>;
|
|
378
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
379
|
+
url: z.ZodOptional<z.ZodString>;
|
|
380
|
+
path: z.ZodOptional<z.ZodString>;
|
|
381
|
+
}, z.core.$loose>>>;
|
|
382
|
+
retry: z.ZodOptional<z.ZodObject<{
|
|
383
|
+
maxAttempts: z.ZodNumber;
|
|
384
|
+
backoffMs: z.ZodNumber;
|
|
385
|
+
multiplier: z.ZodOptional<z.ZodNumber>;
|
|
386
|
+
}, z.core.$loose>>;
|
|
387
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
233
388
|
model: z.ZodOptional<z.ZodString>;
|
|
234
389
|
position: z.ZodOptional<z.ZodObject<{
|
|
235
390
|
x: z.ZodNumber;
|
|
@@ -240,6 +395,13 @@ export declare const OrchestrationGraphSchema: z.ZodObject<{
|
|
|
240
395
|
id: z.ZodOptional<z.ZodString>;
|
|
241
396
|
from: z.ZodString;
|
|
242
397
|
to: z.ZodString;
|
|
398
|
+
fromPort: z.ZodOptional<z.ZodString>;
|
|
399
|
+
toPort: z.ZodOptional<z.ZodString>;
|
|
400
|
+
when: z.ZodOptional<z.ZodObject<{
|
|
401
|
+
expression: z.ZodString;
|
|
402
|
+
}, z.core.$loose>>;
|
|
403
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
404
|
+
label: z.ZodOptional<z.ZodString>;
|
|
243
405
|
}, z.core.$loose>>>;
|
|
244
406
|
builtIn: z.ZodOptional<z.ZodBoolean>;
|
|
245
407
|
createdAt: z.ZodOptional<z.ZodString>;
|
|
@@ -247,4 +409,14 @@ export declare const OrchestrationGraphSchema: z.ZodObject<{
|
|
|
247
409
|
}, z.core.$loose>;
|
|
248
410
|
export type OrchestrationGraph = z.infer<typeof OrchestrationGraphSchema>;
|
|
249
411
|
export declare function validateOrchestrationGraph(graph: OrchestrationGraph): string[];
|
|
412
|
+
/**
|
|
413
|
+
* Advisory findings: things that are almost certainly authoring mistakes but
|
|
414
|
+
* leave the graph executable. Separate from `validateOrchestrationGraph`
|
|
415
|
+
* because that one is the daemon's hard gate — anything it returns stops a run,
|
|
416
|
+
* and none of these should.
|
|
417
|
+
*
|
|
418
|
+
* Expression *syntax* is not checked here: the JSONata parser is daemon-side,
|
|
419
|
+
* so this stays dependency-free for the client bundle.
|
|
420
|
+
*/
|
|
421
|
+
export declare function reviewOrchestrationGraph(graph: OrchestrationGraph): string[];
|
|
250
422
|
//# sourceMappingURL=orchestration.d.ts.map
|
package/dist/orchestration.js
CHANGED
|
@@ -141,6 +141,9 @@ export const RunPhaseCandidateSchema = z
|
|
|
141
141
|
// The candidate's final message (synthesis input); may be large — clients
|
|
142
142
|
// truncate for display.
|
|
143
143
|
summary: z.string().optional(),
|
|
144
|
+
// Validated output fields, when the node declared them (GraphNode.output).
|
|
145
|
+
// Values only — anything large belongs in a file the next node reads.
|
|
146
|
+
outputFields: z.record(z.string(), z.unknown()).optional(),
|
|
144
147
|
})
|
|
145
148
|
.passthrough();
|
|
146
149
|
export const RunPhaseSchema = z
|
|
@@ -159,10 +162,29 @@ export const RunPhaseSchema = z
|
|
|
159
162
|
candidates: z.array(RunPhaseCandidateSchema).optional(),
|
|
160
163
|
// Free-text runtime notes (why it blocked, which cap tripped, gap named).
|
|
161
164
|
notes: z.string().optional(),
|
|
165
|
+
// Machine-readable reason a phase is "skipped" — the human sentence stays in
|
|
166
|
+
// `notes`. Absent on a skipped phase means an older daemon wrote it (read it
|
|
167
|
+
// as "upstream-failed", the only skip that existed then). Open vocabulary,
|
|
168
|
+
// plain string on the wire; known values in GRAPH_SKIP_REASONS.
|
|
169
|
+
skipReason: z.string().optional(),
|
|
170
|
+
// How many extra attempts a node's retry policy spent (0/absent = none).
|
|
171
|
+
retryAttempts: z.number().int().min(0).optional(),
|
|
172
|
+
// True when the phase's last attempt ended at its time limit rather than
|
|
173
|
+
// by failing on its own — a different diagnosis, so a different flag.
|
|
174
|
+
timedOut: z.boolean().optional(),
|
|
162
175
|
startedAt: z.string().optional(),
|
|
163
176
|
completedAt: z.string().optional(),
|
|
164
177
|
})
|
|
165
178
|
.passthrough();
|
|
179
|
+
// Why a phase is "skipped" (see RunPhase.skipReason). A skip is never an error:
|
|
180
|
+
// "condition" means an edge's condition routed around this node, the other two
|
|
181
|
+
// mean an upstream node was itself skipped or failed. Plain string on the wire.
|
|
182
|
+
export const GRAPH_SKIP_REASONS = [
|
|
183
|
+
"condition",
|
|
184
|
+
"upstream-skipped",
|
|
185
|
+
"upstream-failed",
|
|
186
|
+
"canceled",
|
|
187
|
+
];
|
|
166
188
|
export const RunSchema = z
|
|
167
189
|
.object({
|
|
168
190
|
id: z.string().min(1),
|
|
@@ -228,6 +250,38 @@ export const GraphInputSchema = z
|
|
|
228
250
|
defaultValue: z.string().optional(),
|
|
229
251
|
})
|
|
230
252
|
.passthrough();
|
|
253
|
+
// ── Prompt templates ────────────────────────────────────────────────────────
|
|
254
|
+
// Host-level reusable prompts, stored like Graphs. A template with
|
|
255
|
+
// `snippet: true` is meant to be included by other templates rather than bound
|
|
256
|
+
// to a node directly — the shared "how to submit your output" block is the
|
|
257
|
+
// motivating case, since repeating it in every node is both duplication and
|
|
258
|
+
// tokens on every dispatch.
|
|
259
|
+
export const PromptTemplateSchema = z
|
|
260
|
+
.object({
|
|
261
|
+
id: z.string().min(1),
|
|
262
|
+
name: z.string().min(1),
|
|
263
|
+
description: z.string().optional(),
|
|
264
|
+
// EJS source. Rendered with HTML escaping disabled — these are prompts,
|
|
265
|
+
// not markup, and characters like & must survive verbatim.
|
|
266
|
+
content: z.string(),
|
|
267
|
+
// Variables the template expects, so the designer can render a binding
|
|
268
|
+
// form instead of asking the author to remember them.
|
|
269
|
+
variables: z.array(GraphInputSchema).optional(),
|
|
270
|
+
snippet: z.boolean().optional(),
|
|
271
|
+
builtIn: z.boolean().optional(),
|
|
272
|
+
createdAt: z.string().optional(),
|
|
273
|
+
updatedAt: z.string().optional(),
|
|
274
|
+
})
|
|
275
|
+
.passthrough();
|
|
276
|
+
// A node's binding to a stored template. A value is a literal, `$inputs.<key>`
|
|
277
|
+
// (a declared graph input), or `$output.<nodeId>.<field>` (an upstream node's
|
|
278
|
+
// output field).
|
|
279
|
+
export const NodePromptTemplateRefSchema = z
|
|
280
|
+
.object({
|
|
281
|
+
templateId: z.string().min(1),
|
|
282
|
+
variables: z.record(z.string(), z.string()).optional(),
|
|
283
|
+
})
|
|
284
|
+
.passthrough();
|
|
231
285
|
// Node kinds (open vocabulary): "orchestrator" — the single root that hosts
|
|
232
286
|
// the orchestration chat and anchors the Visualizer; "agent" — a worker node.
|
|
233
287
|
export const GRAPH_NODE_KINDS = ["orchestrator", "agent"];
|
|
@@ -249,6 +303,69 @@ export const GraphNodeLoopSchema = z
|
|
|
249
303
|
.optional(),
|
|
250
304
|
})
|
|
251
305
|
.passthrough();
|
|
306
|
+
// ── Output fields (the value plane) ─────────────────────────────────────────
|
|
307
|
+
// What a node declares it will produce. Plain JSON descriptors, never a
|
|
308
|
+
// serialized Zod schema: they have to be three things at once — wire-safe, a
|
|
309
|
+
// form the designer can render, and compilable to both Zod (validation) and
|
|
310
|
+
// JSON Schema (the submit_output tool's input). `type` is an open string
|
|
311
|
+
// vocabulary so a new type can never break an old parser.
|
|
312
|
+
export const GRAPH_OUTPUT_FIELD_TYPES = ["string", "number", "boolean", "array"];
|
|
313
|
+
export const GraphOutputFieldSchema = z
|
|
314
|
+
.object({
|
|
315
|
+
key: z.string().min(1),
|
|
316
|
+
type: z.string().min(1),
|
|
317
|
+
// Shown to the node's agent as the field's description — this is the whole
|
|
318
|
+
// instruction it gets about what to put here, so it earns its place.
|
|
319
|
+
description: z.string().optional(),
|
|
320
|
+
// Absent ⇒ required. You declared the field; producing it is the contract.
|
|
321
|
+
required: z.boolean().optional(),
|
|
322
|
+
})
|
|
323
|
+
.passthrough();
|
|
324
|
+
export const GraphNodeOutputSchema = z
|
|
325
|
+
.object({
|
|
326
|
+
fields: z.array(GraphOutputFieldSchema),
|
|
327
|
+
})
|
|
328
|
+
.passthrough();
|
|
329
|
+
// ── Query tools (per-node read-only lookups) ────────────────────────────────
|
|
330
|
+
// Author-defined tools that exist only inside one node's session, so a node can
|
|
331
|
+
// be given exactly the lookup it needs instead of the whole workspace.
|
|
332
|
+
//
|
|
333
|
+
// Three kinds, all read-only by construction:
|
|
334
|
+
// command argv array only — no shell, so no operators and no injection
|
|
335
|
+
// surface. A pipeline belongs in a script the tool points at.
|
|
336
|
+
// http-get GET only, no author-supplied headers (credentials can't leak
|
|
337
|
+
// into a graph template).
|
|
338
|
+
// file-read path must resolve inside the run's cwd.
|
|
339
|
+
export const GRAPH_QUERY_TOOL_KINDS = ["command", "http-get", "file-read"];
|
|
340
|
+
export const GraphQueryToolSchema = z
|
|
341
|
+
.object({
|
|
342
|
+
// Tool name the agent calls. Namespaced at registration so it can never
|
|
343
|
+
// shadow a built-in Otto tool.
|
|
344
|
+
name: z.string().min(1),
|
|
345
|
+
description: z.string().min(1),
|
|
346
|
+
kind: z.string().min(1),
|
|
347
|
+
// Declared parameters, reusing the output-field descriptor shape.
|
|
348
|
+
parameters: z.array(GraphOutputFieldSchema).optional(),
|
|
349
|
+
// kind "command": the executable plus its arguments, each argument a
|
|
350
|
+
// separate entry. `{{param}}` substitutes a declared parameter's value as
|
|
351
|
+
// one argument — never as a fragment the shell could re-split.
|
|
352
|
+
command: z.array(z.string()).optional(),
|
|
353
|
+
// kind "http-get": the URL, with `{{param}}` substitution (encoded).
|
|
354
|
+
url: z.string().optional(),
|
|
355
|
+
// kind "file-read": workspace-relative path, with `{{param}}` substitution.
|
|
356
|
+
path: z.string().optional(),
|
|
357
|
+
})
|
|
358
|
+
.passthrough();
|
|
359
|
+
// Bounded re-dispatch with exponential backoff. `maxAttempts` counts the first
|
|
360
|
+
// try, so 1 means "no retry" and is allowed (a designer default that hasn't
|
|
361
|
+
// been changed yet shouldn't be a validation error).
|
|
362
|
+
export const GraphNodeRetrySchema = z
|
|
363
|
+
.object({
|
|
364
|
+
maxAttempts: z.number().int().min(1).max(10),
|
|
365
|
+
backoffMs: z.number().int().min(0).max(600000),
|
|
366
|
+
multiplier: z.number().min(1).max(4).optional(),
|
|
367
|
+
})
|
|
368
|
+
.passthrough();
|
|
252
369
|
export const GraphNodeSchema = z
|
|
253
370
|
.object({
|
|
254
371
|
id: z.string().min(1),
|
|
@@ -261,16 +378,60 @@ export const GraphNodeSchema = z
|
|
|
261
378
|
prompt: z.string().optional(),
|
|
262
379
|
// Key of a declared input whose value joins (or forms) the prompt.
|
|
263
380
|
promptFromInput: z.string().optional(),
|
|
381
|
+
// Load this node's prompt from a stored template instead of `prompt`.
|
|
382
|
+
// Resolution failure falls back to `prompt`, so a deleted template
|
|
383
|
+
// degrades a node rather than breaking a graph.
|
|
384
|
+
promptTemplate: NodePromptTemplateRefSchema.optional(),
|
|
264
385
|
// Leaf-only: the node may orchestrate its own agents (full otto toolset
|
|
265
386
|
// minus start_run). Non-autonomous nodes get no orchestration tools at all.
|
|
266
387
|
autonomous: z.boolean().optional(),
|
|
267
388
|
loop: GraphNodeLoopSchema.optional(),
|
|
389
|
+
// Declared output fields. Present ⇒ the node's agent gets a submit_output
|
|
390
|
+
// tool it must call, its result is validated, and downstream nodes receive
|
|
391
|
+
// the fields as data instead of re-reading prose. Absent ⇒ today exactly.
|
|
392
|
+
output: GraphNodeOutputSchema.optional(),
|
|
393
|
+
// How much of the workspace this node's agent may touch: "none" (no
|
|
394
|
+
// filesystem), "read", or "write". Absent ⇒ "write", today's behaviour.
|
|
395
|
+
//
|
|
396
|
+
// Enforced by withholding tools at spawn, never by asking the model — and a
|
|
397
|
+
// provider that can't enforce it refuses the node at compile time rather
|
|
398
|
+
// than running it with full access. Open string vocabulary; known values in
|
|
399
|
+
// WORKSPACE_ACCESS_LEVELS (protocol/agent-types).
|
|
400
|
+
access: z.string().optional(),
|
|
401
|
+
// Per-node Otto tool allowlist, by group (see OTTO_TOOL_GROUPS). Absent ⇒
|
|
402
|
+
// whatever the node's tool policy already allows. Present ⇒ only these
|
|
403
|
+
// groups, intersected with that policy and the daemon-wide allowlist — a
|
|
404
|
+
// node can narrow its own authority, never widen it.
|
|
405
|
+
//
|
|
406
|
+
// Narrowing is a cost lever as much as a safety one: the tool catalog is
|
|
407
|
+
// paid for in input tokens on every request the node's agent makes, and a
|
|
408
|
+
// smaller catalog measurably helps smaller models stay on task.
|
|
409
|
+
tools: z.array(z.string().min(1)).optional(),
|
|
410
|
+
// Read-only lookups available only inside this node's session.
|
|
411
|
+
queryTools: z.array(GraphQueryToolSchema).optional(),
|
|
412
|
+
// Resilience against transient failure. Distinct from `loop`, which is
|
|
413
|
+
// quality iteration: a loop re-runs work that succeeded but wasn't good
|
|
414
|
+
// enough; a retry re-runs work that never completed. Retry wraps the whole
|
|
415
|
+
// node including its loop, and every attempt is charged to the run's agent
|
|
416
|
+
// cap — a retry is never a private allowance.
|
|
417
|
+
retry: GraphNodeRetrySchema.optional(),
|
|
418
|
+
// Wall-clock ceiling for one attempt of this node. On expiry the agent is
|
|
419
|
+
// really cancelled (not merely stopped being awaited) and the node fails,
|
|
420
|
+
// which its retry policy may then catch.
|
|
421
|
+
timeoutMs: z.number().int().min(1000).max(21600000).optional(),
|
|
268
422
|
// Explicit model override (otherwise the resolved personality/team decides).
|
|
269
423
|
model: z.string().optional(),
|
|
270
424
|
// Designer canvas layout.
|
|
271
425
|
position: z.object({ x: z.number(), y: z.number() }).passthrough().optional(),
|
|
272
426
|
})
|
|
273
427
|
.passthrough();
|
|
428
|
+
// An edge condition. Kept as a wrapper object rather than a bare string so a
|
|
429
|
+
// future evaluation dialect can be named without a second field.
|
|
430
|
+
export const GraphEdgeConditionSchema = z
|
|
431
|
+
.object({
|
|
432
|
+
expression: z.string().min(1),
|
|
433
|
+
})
|
|
434
|
+
.passthrough();
|
|
274
435
|
// A directed edge: `from`'s final output becomes labeled input material for
|
|
275
436
|
// `to`. Fan-in is an all-inputs barrier held by the daemon — agents never know
|
|
276
437
|
// about waiting.
|
|
@@ -279,6 +440,30 @@ export const GraphEdgeSchema = z
|
|
|
279
440
|
id: z.string().min(1).optional(),
|
|
280
441
|
from: z.string().min(1),
|
|
281
442
|
to: z.string().min(1),
|
|
443
|
+
// Named ports. Absent ⇒ "output" → "input", which is every edge today, so
|
|
444
|
+
// existing graphs parse and execute identically. Reserved ahead of the
|
|
445
|
+
// control nodes that need more than one outcome (a gate's approved/rejected,
|
|
446
|
+
// a check's pass/fail): adding two optional fields now is free, and adding a
|
|
447
|
+
// second port later would mean changing the canvas, the schema and the
|
|
448
|
+
// engine's value routing at once.
|
|
449
|
+
fromPort: z.string().min(1).optional(),
|
|
450
|
+
toPort: z.string().min(1).optional(),
|
|
451
|
+
// Condition: a JSONata expression evaluated against the upstream node's
|
|
452
|
+
// output fields once it settles (falling back to its prose as `output`
|
|
453
|
+
// when it declared none). Truthy ⇒ this edge delivers; falsy ⇒ the edge is
|
|
454
|
+
// inactive and its target is skipped with reason "condition". Absent ⇒
|
|
455
|
+
// always delivers, which is every edge today.
|
|
456
|
+
//
|
|
457
|
+
// The condition lives on the edge rather than inside a node so the branch
|
|
458
|
+
// is visible as a labelled wire — the graph shows its own control flow.
|
|
459
|
+
when: GraphEdgeConditionSchema.optional(),
|
|
460
|
+
// Which of the upstream node's output fields this edge carries. Absent ⇒
|
|
461
|
+
// all of them. Selection only, never renaming: downstream is a prompt, not
|
|
462
|
+
// a typed function signature, so remapping keys would buy nothing and
|
|
463
|
+
// cost the reader the ability to trace a value by name.
|
|
464
|
+
fields: z.array(z.string().min(1)).optional(),
|
|
465
|
+
// Display-only label for the wire.
|
|
466
|
+
label: z.string().optional(),
|
|
282
467
|
})
|
|
283
468
|
.passthrough();
|
|
284
469
|
export const OrchestrationGraphSchema = z
|
|
@@ -347,6 +532,28 @@ function validateGraphEdges(graph, nodeIds) {
|
|
|
347
532
|
}
|
|
348
533
|
return problems;
|
|
349
534
|
}
|
|
535
|
+
/**
|
|
536
|
+
* Advisory findings: things that are almost certainly authoring mistakes but
|
|
537
|
+
* leave the graph executable. Separate from `validateOrchestrationGraph`
|
|
538
|
+
* because that one is the daemon's hard gate — anything it returns stops a run,
|
|
539
|
+
* and none of these should.
|
|
540
|
+
*
|
|
541
|
+
* Expression *syntax* is not checked here: the JSONata parser is daemon-side,
|
|
542
|
+
* so this stays dependency-free for the client bundle.
|
|
543
|
+
*/
|
|
544
|
+
export function reviewOrchestrationGraph(graph) {
|
|
545
|
+
const warnings = [];
|
|
546
|
+
for (const edge of graph.edges ?? []) {
|
|
547
|
+
if (!edge.when?.expression?.trim()) {
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
const source = graph.nodes.find((node) => node.id === edge.from);
|
|
551
|
+
if (source && !source.output?.fields?.length) {
|
|
552
|
+
warnings.push(`The edge from "${source.title}" has a condition, but "${source.title}" declares no output fields — the condition can only test its prose as \`output\`.`);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return warnings;
|
|
556
|
+
}
|
|
350
557
|
// Cycle check (loops are node-level annotations, never cyclic edges): Kahn.
|
|
351
558
|
function hasGraphCycle(graph, outgoing, incoming) {
|
|
352
559
|
const indegree = new Map();
|
|
@@ -390,6 +597,25 @@ function validateGraphNode(node, declaredInputs) {
|
|
|
390
597
|
}
|
|
391
598
|
}
|
|
392
599
|
problems.push(...validateGraphNodeLoop(node));
|
|
600
|
+
problems.push(...validateGraphNodeOutput(node));
|
|
601
|
+
return problems;
|
|
602
|
+
}
|
|
603
|
+
function validateGraphNodeOutput(node) {
|
|
604
|
+
if (!node.output) {
|
|
605
|
+
return [];
|
|
606
|
+
}
|
|
607
|
+
const fields = node.output.fields ?? [];
|
|
608
|
+
if (fields.length === 0) {
|
|
609
|
+
return [`Node "${node.title}" declares output fields but lists none.`];
|
|
610
|
+
}
|
|
611
|
+
const problems = [];
|
|
612
|
+
const seen = new Set();
|
|
613
|
+
for (const field of fields) {
|
|
614
|
+
if (seen.has(field.key)) {
|
|
615
|
+
problems.push(`Node "${node.title}" declares the output field "${field.key}" twice.`);
|
|
616
|
+
}
|
|
617
|
+
seen.add(field.key);
|
|
618
|
+
}
|
|
393
619
|
return problems;
|
|
394
620
|
}
|
|
395
621
|
function validateGraphNodeLoop(node) {
|
|
@@ -40,7 +40,7 @@ export declare const ProviderProfileModelSchema: z.ZodObject<{
|
|
|
40
40
|
* of these groups; omitting the selection means all groups. Kept deliberately
|
|
41
41
|
* coarse — users pick groups, not individual tools.
|
|
42
42
|
*/
|
|
43
|
-
export declare const OTTO_TOOL_GROUPS: readonly ["preview", "browser", "web", "agents", "terminals", "schedules", "artifacts", "workspace"];
|
|
43
|
+
export declare const OTTO_TOOL_GROUPS: readonly ["preview", "browser", "web", "agents", "terminals", "schedules", "artifacts", "widgets", "workspace"];
|
|
44
44
|
export type OttoToolGroup = (typeof OTTO_TOOL_GROUPS)[number];
|
|
45
45
|
/**
|
|
46
46
|
* Map a tool name to its group. Covers both Otto's catalog tools and the
|
|
@@ -148,6 +148,7 @@ export declare const ProviderOverrideSchema: z.ZodObject<{
|
|
|
148
148
|
agents: "agents";
|
|
149
149
|
terminals: "terminals";
|
|
150
150
|
schedules: "schedules";
|
|
151
|
+
widgets: "widgets";
|
|
151
152
|
workspace: "workspace";
|
|
152
153
|
}>>>;
|
|
153
154
|
mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -221,6 +222,7 @@ export declare const ProviderOverridesSchema: z.ZodRecord<z.ZodString, z.ZodObje
|
|
|
221
222
|
agents: "agents";
|
|
222
223
|
terminals: "terminals";
|
|
223
224
|
schedules: "schedules";
|
|
225
|
+
widgets: "widgets";
|
|
224
226
|
workspace: "workspace";
|
|
225
227
|
}>>>;
|
|
226
228
|
mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
|
package/dist/provider-config.js
CHANGED
|
@@ -48,6 +48,7 @@ export const OTTO_TOOL_GROUPS = [
|
|
|
48
48
|
"terminals",
|
|
49
49
|
"schedules",
|
|
50
50
|
"artifacts",
|
|
51
|
+
"widgets",
|
|
51
52
|
"workspace",
|
|
52
53
|
];
|
|
53
54
|
/**
|
|
@@ -68,6 +69,8 @@ export function ottoToolGroupForName(name) {
|
|
|
68
69
|
return "schedules";
|
|
69
70
|
if (name.includes("artifact"))
|
|
70
71
|
return "artifacts";
|
|
72
|
+
if (name === "show_widget" || name === "widget_contract")
|
|
73
|
+
return "widgets";
|
|
71
74
|
if (name.includes("worktree") || name.includes("workspace"))
|
|
72
75
|
return "workspace";
|
|
73
76
|
return "agents";
|