@decocms/bindings 1.4.0 → 1.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/bindings",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "check": "tsc --noEmit",
@@ -29,6 +29,13 @@ export interface RegisterEmptyStateParams {
29
29
  component: ReactNode;
30
30
  }
31
31
 
32
+ export interface RegisterSettingsSidebarItemParams {
33
+ key: string;
34
+ icon: ReactNode;
35
+ label: string;
36
+ to: string;
37
+ }
38
+
32
39
  export interface PluginSetupContext {
33
40
  parentRoute: AnyRoute;
34
41
  routing: {
@@ -37,6 +44,9 @@ export interface PluginSetupContext {
37
44
  };
38
45
  registerRootSidebarItem: (params: RegisterRootSidebarItemParams) => void;
39
46
  registerSidebarGroup: (params: RegisterSidebarGroupParams) => void;
47
+ registerSettingsSidebarItem: (
48
+ params: RegisterSettingsSidebarItemParams,
49
+ ) => void;
40
50
  registerPluginRoutes: (route: AnyRoute[]) => void;
41
51
  }
42
52
 
@@ -21,22 +21,22 @@ export const ToolCallActionSchema = z.object({
21
21
  transformCode: z
22
22
  .string()
23
23
  .optional()
24
- .describe(`Pure TypeScript function for data transformation of the tool call result. Must be a TypeScript file that declares the Output interface and exports a default function: \`interface Output { ... } export default async function(input): Output { ... }\`
25
- The input will match with the tool call outputSchema. If transformCode is not provided, the tool call result will be used as the step output.
24
+ .describe(`Pure TypeScript function for data transformation of the tool call result. Must be a TypeScript file that declares the Output interface and exports a default function: \`interface Output { ... } export default async function(stepInput): Output { ... }\`
25
+ The stepInput will match with the tool call outputSchema. If transformCode is not provided, the tool call result will be used as the step output.
26
26
  Providing an transformCode is recommended because it both allows you to transform the data and validate it against a JSON Schema - tools are ephemeral and may return unexpected data.`),
27
27
  });
28
28
  export type ToolCallAction = z.infer<typeof ToolCallActionSchema>;
29
29
 
30
30
  export const CodeActionSchema = z.object({
31
31
  code: z.string().describe(
32
- `Pure TypeScript function for data transformation. Useful to merge data from multiple steps and transform it. Must be a TypeScript file that declares the Output interface and exports a default function: \`interface Output { ... } export default async function(input): Output { ... }\`
33
- The input is the resolved value of the references in the input field. Example:
32
+ `Pure TypeScript function for data transformation. Useful to merge data from multiple steps and transform it. Must be a TypeScript file that declares the Output interface and exports a default function: \`interface Output { ... } export default async function(stepInput): Output { ... }\`
33
+ The stepInput is the resolved value of the references in the input field. Example:
34
34
  {
35
35
  "input": {
36
36
  "name": "@Step_1.name",
37
37
  "age": "@Step_2.age"
38
38
  },
39
- "code": "export default function(input): Output { return { result: \`\${input.name} is \${input.age} years old.\` } }"
39
+ "code": "export default function(stepInput): Output { return { result: \`\${stepInput.name} is \${stepInput.age} years old.\` } }"
40
40
  }
41
41
  `,
42
42
  ),
@@ -66,19 +66,60 @@ export type StepAction = z.infer<typeof StepActionSchema>;
66
66
  /**
67
67
  * Step Config Schema - Optional configuration for retry, timeout, and looping
68
68
  */
69
+ /**
70
+ * Step Condition Schema - Structured condition for bail and future `when` support.
71
+ * Evaluates a resolved @ref against an optional operator.
72
+ * If no operator is specified, checks for truthiness.
73
+ */
74
+ export const StepConditionSchema = z.object({
75
+ ref: z
76
+ .string()
77
+ .describe(
78
+ "@ref to resolve and evaluate, e.g. '@validate.shouldStop' or '@input.skipProcessing'",
79
+ ),
80
+ eq: z
81
+ .unknown()
82
+ .optional()
83
+ .describe("Step bails if resolved value equals this"),
84
+ neq: z
85
+ .unknown()
86
+ .optional()
87
+ .describe("Step bails if resolved value does NOT equal this"),
88
+ gt: z
89
+ .number()
90
+ .optional()
91
+ .describe("Step bails if resolved value is greater than this"),
92
+ lt: z
93
+ .number()
94
+ .optional()
95
+ .describe("Step bails if resolved value is less than this"),
96
+ });
97
+ export type StepCondition = z.infer<typeof StepConditionSchema>;
98
+
69
99
  export const StepConfigSchema = z.object({
70
100
  maxAttempts: z
71
101
  .number()
102
+ .int()
103
+ .min(1)
104
+ .max(10)
72
105
  .optional()
73
106
  .describe("Max retry attempts on failure (default: 1, no retries)"),
74
107
  backoffMs: z
75
108
  .number()
109
+ .int()
110
+ .min(100)
111
+ .max(60_000)
76
112
  .optional()
77
113
  .describe("Initial delay between retries in ms (doubles each attempt)"),
78
114
  timeoutMs: z
79
115
  .number()
116
+ .int()
117
+ .min(100)
118
+ .max(86_400_000)
80
119
  .optional()
81
- .describe("Max execution time in ms before step fails (default: 30000)"),
120
+ .describe(
121
+ "Max execution time in ms before step fails (default: 30000). Upper bound 24h.",
122
+ ),
82
123
  onError: z
83
124
  .enum(["fail", "continue"])
84
125
  .optional()
@@ -102,16 +143,21 @@ export type StepConfig = z.infer<typeof StepConfigSchema>;
102
143
  * - @ctx.execution_id → current workflow execution ID
103
144
  */
104
145
 
105
- type JsonSchema = {
146
+ export type JsonSchema = {
106
147
  type?: string;
107
- properties?: Record<string, unknown>;
148
+ properties?: Record<string, JsonSchema>;
108
149
  required?: string[];
109
150
  description?: string;
110
151
  additionalProperties?: boolean | Record<string, unknown>;
111
152
  additionalItems?: boolean | Record<string, unknown>;
112
153
  items?: JsonSchema;
154
+ format?: string;
155
+ enum?: string[];
156
+ maxLength?: number;
157
+ anyOf?: JsonSchema[];
158
+ [key: string]: unknown;
113
159
  };
114
- const JsonSchemaSchema: z.ZodType<JsonSchema> = z.lazy(() =>
160
+ export const JsonSchemaSchema: z.ZodType<JsonSchema> = z.lazy(() =>
115
161
  z
116
162
  .object({
117
163
  type: z.string().optional(),
@@ -127,7 +173,7 @@ const JsonSchemaSchema: z.ZodType<JsonSchema> = z.lazy(() =>
127
173
  items: JsonSchemaSchema.optional(),
128
174
  })
129
175
  .passthrough(),
130
- );
176
+ ) as unknown as z.ZodType<JsonSchema>;
131
177
 
132
178
  /**
133
179
  * Step names that are reserved by the @ref system and cannot be used as step names.
@@ -170,6 +216,12 @@ export const StepSchema = z.object({
170
216
  .describe("max parallel iterations. default is 1 (sequential)"),
171
217
  })
172
218
  .optional(),
219
+ bail: z
220
+ .union([z.literal(true), StepConditionSchema])
221
+ .optional()
222
+ .describe(
223
+ "Early return: if true, the workflow exits with this step's output on successful completion. If a condition object, the workflow exits only when the condition is met. Bail is ignored on step error.",
224
+ ),
173
225
  });
174
226
 
175
227
  export type Step = z.infer<typeof StepSchema>;
@@ -324,6 +376,10 @@ export const WorkflowSchema = BaseCollectionEntitySchema.extend({
324
376
  .optional()
325
377
  .describe("Human-readable summary of what this workflow does"),
326
378
 
379
+ input_schema: JsonSchemaSchema.optional().describe(
380
+ "Optional JSON Schema describing the expected input for this workflow.",
381
+ ),
382
+
327
383
  steps: z
328
384
  .array(StepSchema)
329
385
  .describe(
@@ -370,7 +426,7 @@ export const DEFAULT_TOOL_STEP: Omit<Step, "name"> = {
370
426
  interface Input {
371
427
 
372
428
  }
373
- export default function(input) { return input.result }`,
429
+ export default function(stepInput) { return stepInput.result }`,
374
430
  },
375
431
  input: {
376
432
  modelId: "anthropic/claude-4.5-haiku",
@@ -399,10 +455,10 @@ export const DEFAULT_CODE_STEP: Step = {
399
455
  interface Output {
400
456
  result: unknown;
401
457
  }
402
-
403
- export default async function(input: Input): Promise<Output> {
458
+
459
+ export default async function(stepInput: Input): Promise<Output> {
404
460
  return {
405
- result: input.example
461
+ result: stepInput.example
406
462
  }
407
463
  }`,
408
464
  },
@@ -477,6 +533,7 @@ export const WORKFLOW_EXECUTION_BINDING = createCollectionBindings(
477
533
  export interface DAGStep {
478
534
  name: string;
479
535
  input?: unknown;
536
+ bail?: true | StepCondition;
480
537
  }
481
538
 
482
539
  /**
@@ -491,7 +548,7 @@ export function getAllRefs(input: unknown): string[] {
491
548
 
492
549
  function traverse(value: unknown) {
493
550
  if (typeof value === "string") {
494
- const matches = value.match(/@(\w+)/g);
551
+ const matches = value.match(/@([a-zA-Z_][a-zA-Z0-9_-]*)/g);
495
552
  if (matches) {
496
553
  refs.push(...matches.map((m) => m.substring(1))); // Remove @ prefix
497
554
  }
@@ -523,13 +580,13 @@ export function getStepDependencies(
523
580
  function traverse(value: unknown) {
524
581
  if (typeof value === "string") {
525
582
  // Match @stepName or @stepName.something patterns
526
- const matches = value.match(/@(\w+)/g);
583
+ const matches = value.match(/@([a-zA-Z_][a-zA-Z0-9_-]*)/g);
527
584
  if (matches) {
528
585
  for (const match of matches) {
529
586
  const refName = match.substring(1); // Remove @
530
587
  // Only count as dependency if it references another step
531
588
  // (not "item", "index", "input" from forEach or workflow input)
532
- if (allStepNames.has(refName)) {
589
+ if (allStepNames.has(refName) && refName !== step.name) {
533
590
  deps.push(refName);
534
591
  }
535
592
  }
@@ -542,6 +599,12 @@ export function getStepDependencies(
542
599
  }
543
600
 
544
601
  traverse(step.input);
602
+
603
+ // Extract dependency from bail condition ref
604
+ if (step.bail && step.bail !== true) {
605
+ traverse(step.bail.ref);
606
+ }
607
+
545
608
  return [...new Set(deps)];
546
609
  }
547
610