@automate.ax/api-contract 0.45.0 → 0.47.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/src/runtime.ts CHANGED
@@ -2,6 +2,7 @@ import { encodableSchema } from "@automate.ax/codec"
2
2
  import type { GatewayModelId } from "@ai-sdk/gateway"
3
3
  import { oc } from "@orpc/contract"
4
4
  import { z } from "zod"
5
+ import { e164PhoneNumberSchema } from "./schemas"
5
6
 
6
7
  /** Default model used by the platform Vercel AI Gateway account. */
7
8
  export const DEFAULT_GATEWAY_MODEL_ID =
@@ -12,7 +13,203 @@ const SIGNAL_FAILURE_SCHEMA = z.object({
12
13
  name: z.string(),
13
14
  })
14
15
 
15
- const TERMINAL_ACTION_STATUS_SCHEMA = z.enum(["closed", "failed", "succeeded"])
16
+ const OUTCOME_SEQUENCE_SCHEMA = z.number().int().positive()
17
+
18
+ const ACTION_INVOCATION_BASE_SCHEMA = z.object({
19
+ actionDependencyIds: z.string().array(),
20
+ description: z.string().nullable(),
21
+ eventDependencyIds: z.string().array(),
22
+ inputHash: z.string(),
23
+ name: z.string(),
24
+ signalDependencyIds: z.string().array(),
25
+ slot: z.number().int().nonnegative(),
26
+ })
27
+
28
+ const ACTION_INVOCATION_SCHEMA = z.union([
29
+ ACTION_INVOCATION_BASE_SCHEMA.extend({ status: z.literal("pending") }),
30
+ ACTION_INVOCATION_BASE_SCHEMA.extend({
31
+ reason: z.literal("closed-dependency"),
32
+ status: z.literal("skipped"),
33
+ }),
34
+ ACTION_INVOCATION_BASE_SCHEMA.extend({
35
+ failure: SIGNAL_FAILURE_SCHEMA,
36
+ reason: z.literal("failed-dependency"),
37
+ status: z.literal("skipped"),
38
+ }),
39
+ ])
40
+
41
+ const ACTION_RUN_INVOCATION_BASE_SCHEMA = ACTION_INVOCATION_BASE_SCHEMA.extend({
42
+ actionInvocationId: z.string(),
43
+ })
44
+
45
+ const ACTION_RUN_INVOCATION_SCHEMA = z.union([
46
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({ status: z.literal("pending") }),
47
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
48
+ failure: SIGNAL_FAILURE_SCHEMA,
49
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
50
+ status: z.literal("failed"),
51
+ }),
52
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
53
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
54
+ reason: z.literal("closed-dependency"),
55
+ status: z.literal("skipped"),
56
+ }),
57
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
58
+ failure: SIGNAL_FAILURE_SCHEMA,
59
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
60
+ reason: z.literal("failed-dependency"),
61
+ status: z.literal("skipped"),
62
+ }),
63
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
64
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
65
+ status: z.literal("succeeded"),
66
+ }),
67
+ ])
68
+
69
+ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
70
+ actionDependencyIds: z.string().array(),
71
+ eventDependencyIds: z.string().array(),
72
+ signalDependencyIds: z.string().array(),
73
+ slot: z.number().int().nonnegative(),
74
+ })
75
+
76
+ const CORRELATION_ENTRY_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
77
+ key: encodableSchema,
78
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
79
+ streamName: z.string().min(1),
80
+ streamNames: z.string().min(1).array().min(2),
81
+ value: encodableSchema,
82
+ })
83
+
84
+ const SIGNAL_INVOCATION_SCHEMA = z.union([
85
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
86
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA.optional(),
87
+ status: z.literal("closed"),
88
+ }),
89
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
90
+ failure: SIGNAL_FAILURE_SCHEMA,
91
+ status: z.literal("failed"),
92
+ }),
93
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
94
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA.optional(),
95
+ selectedIndex: z.number().int().nonnegative().optional(),
96
+ status: z.literal("open"),
97
+ }),
98
+ ])
99
+
100
+ const SIGNAL_BATCH_OUTCOME_BASE_SCHEMA =
101
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
102
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
103
+ signalInvocationId: z.string(),
104
+ })
105
+
106
+ const SIGNAL_BATCH_OUTCOME_SCHEMA = z.union([
107
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({
108
+ selectedIndex: z.number().int().nonnegative().optional(),
109
+ status: z.literal("open"),
110
+ }),
111
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("closed") }),
112
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({
113
+ failure: SIGNAL_FAILURE_SCHEMA,
114
+ status: z.literal("failed"),
115
+ }),
116
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("succeeded") }),
117
+ ])
118
+
119
+ const ACTION_VALUE_OUTCOME_SCHEMA = z.union([
120
+ z.object({
121
+ actionInvocationId: z.string(),
122
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
123
+ slot: z.number().int(),
124
+ status: z.literal("failed"),
125
+ failure: SIGNAL_FAILURE_SCHEMA,
126
+ }),
127
+ z.object({
128
+ actionInvocationId: z.string(),
129
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
130
+ reason: z.literal("closed-dependency"),
131
+ slot: z.number().int(),
132
+ status: z.literal("skipped"),
133
+ }),
134
+ z.object({
135
+ actionInvocationId: z.string(),
136
+ failure: SIGNAL_FAILURE_SCHEMA,
137
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
138
+ reason: z.literal("failed-dependency"),
139
+ slot: z.number().int(),
140
+ status: z.literal("skipped"),
141
+ }),
142
+ z.object({
143
+ actionInvocationId: z.string(),
144
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
145
+ output: encodableSchema,
146
+ slot: z.number().int(),
147
+ status: z.literal("succeeded"),
148
+ }),
149
+ ])
150
+
151
+ const SIGNAL_VALUE_OUTCOME_BASE_SCHEMA = z.object({
152
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
153
+ signalInvocationId: z.string(),
154
+ slot: z.number().int(),
155
+ })
156
+
157
+ const SIGNAL_VALUE_OUTCOME_SCHEMA = z.union([
158
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
159
+ selectedIndex: z.number().int().nonnegative().optional(),
160
+ status: z.literal("open"),
161
+ }),
162
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("closed") }),
163
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
164
+ failure: SIGNAL_FAILURE_SCHEMA,
165
+ status: z.literal("failed"),
166
+ }),
167
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
168
+ output: encodableSchema,
169
+ status: z.literal("succeeded"),
170
+ }),
171
+ ])
172
+
173
+ const RUNTIME_VALUE_CONTEXT_SCHEMA = z.object({
174
+ actionOutputs: ACTION_VALUE_OUTCOME_SCHEMA.array(),
175
+ contextId: z.string(),
176
+ events: z
177
+ .object({
178
+ automationEventId: z.string(),
179
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
180
+ payload: encodableSchema,
181
+ slot: z.number().int(),
182
+ })
183
+ .array(),
184
+ signalOutputs: SIGNAL_VALUE_OUTCOME_SCHEMA.array(),
185
+ })
186
+
187
+ const RUNTIME_RUN_CONTEXT_SCHEMA = z.object({
188
+ actions: ACTION_RUN_INVOCATION_SCHEMA.array(),
189
+ contextId: z.string(),
190
+ events: z
191
+ .object({
192
+ automationEventId: z.string(),
193
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
194
+ slot: z.number().int(),
195
+ })
196
+ .array(),
197
+ signalOutputs: SIGNAL_BATCH_OUTCOME_SCHEMA.array(),
198
+ })
199
+
200
+ const TARGET_ACTION_SCHEMA = z.union([
201
+ z.object({
202
+ context: RUNTIME_VALUE_CONTEXT_SCHEMA,
203
+ id: z.string(),
204
+ slot: z.number().int(),
205
+ status: z.literal("pending"),
206
+ }),
207
+ z.object({
208
+ id: z.string(),
209
+ slot: z.number().int(),
210
+ status: z.enum(["failed", "skipped", "succeeded"]),
211
+ }),
212
+ ])
16
213
 
17
214
  const GENERATION_WARNING_SCHEMA = z.discriminatedUnion("type", [
18
215
  z.object({
@@ -153,24 +350,25 @@ export const runtimeContract = {
153
350
  commit: oc
154
351
  .input(
155
352
  z.object({
156
- actionInvocations: z
157
- .object({
158
- actionDependencyIds: z.string().array(),
159
- description: z.string().nullable(),
160
- eventDependencyIds: z.string().array(),
161
- inputHash: z.string(),
162
- name: z.string(),
163
- slot: z.number().int().nonnegative(),
164
- })
165
- .array()
166
- .default([]),
353
+ actionInvocations: ACTION_INVOCATION_SCHEMA.array().default([]),
354
+ correlationEntries: CORRELATION_ENTRY_SCHEMA.array().default([]),
355
+ settled: z.boolean().default(true),
356
+ signalInvocations: SIGNAL_INVOCATION_SCHEMA.array().default([]),
167
357
  }),
168
358
  )
169
359
  .output(z.void()),
170
- completeInvocation: oc
360
+ completeAction: oc
171
361
  .input(
172
- z.discriminatedUnion("status", [
173
- z.object({ status: z.literal("closed") }),
362
+ z.union([
363
+ z.object({
364
+ reason: z.literal("closed-dependency"),
365
+ status: z.literal("skipped"),
366
+ }),
367
+ z.object({
368
+ failure: SIGNAL_FAILURE_SCHEMA,
369
+ reason: z.literal("failed-dependency"),
370
+ status: z.literal("skipped"),
371
+ }),
174
372
  z.object({
175
373
  failure: SIGNAL_FAILURE_SCHEMA,
176
374
  status: z.literal("failed"),
@@ -185,67 +383,16 @@ export const runtimeContract = {
185
383
  generate: oc
186
384
  .input(RUNTIME_GENERATION_INPUT_SCHEMA)
187
385
  .output(generationResultSchema),
188
- loadInvocation: oc.output(
386
+ load: oc.output(
189
387
  z.object({
190
- context: z.object({
191
- actionOutputs: z
192
- .discriminatedUnion("status", [
193
- z.object({
194
- actionInvocationId: z.string(),
195
- slot: z.number().int(),
196
- status: z.literal("closed"),
197
- }),
198
- z.object({
199
- actionInvocationId: z.string(),
200
- failure: SIGNAL_FAILURE_SCHEMA,
201
- slot: z.number().int(),
202
- status: z.literal("failed"),
203
- }),
204
- z.object({
205
- actionInvocationId: z.string(),
206
- output: encodableSchema,
207
- slot: z.number().int(),
208
- status: z.literal("succeeded"),
209
- }),
210
- ])
211
- .array(),
212
- contextId: z.string(),
213
- events: z
214
- .object({
215
- automationEventId: z.string(),
216
- payload: encodableSchema,
217
- slot: z.number().int(),
218
- })
219
- .array(),
220
- }),
221
- id: z.string(),
222
- slot: z.number().int(),
223
- }),
224
- ),
225
- nextBatch: oc.output(
226
- z.object({
227
- context: z.object({
228
- actionOutputs: z
229
- .object({
230
- actionDependencyIds: z.string().array(),
231
- actionInvocationId: z.string(),
232
- eventDependencyIds: z.string().array(),
233
- inputHash: z.string(),
234
- name: z.string(),
235
- slot: z.number().int(),
236
- status: TERMINAL_ACTION_STATUS_SCHEMA,
237
- })
238
- .array(),
239
- contextId: z.string(),
240
- events: z
241
- .object({
242
- automationEventId: z.string(),
243
- slot: z.number().int(),
244
- })
245
- .array(),
246
- }),
388
+ context: RUNTIME_RUN_CONTEXT_SCHEMA,
389
+ finalAttempt: z.boolean(),
390
+ targetAction: TARGET_ACTION_SCHEMA.optional(),
247
391
  }),
248
392
  ),
393
+ loadValues: oc
394
+ .input(SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.omit({ slot: true }))
395
+ .output(RUNTIME_VALUE_CONTEXT_SCHEMA),
249
396
  resolveAccountInput: oc
250
397
  .input(
251
398
  z.strictObject({
@@ -284,4 +431,17 @@ export const runtimeContract = {
284
431
  id: z.string().nullable(),
285
432
  }),
286
433
  ),
434
+ sendSms: oc
435
+ .input(
436
+ z.object({
437
+ deliveryIndex: z.number().int().nonnegative().default(0),
438
+ text: z.string().trim().min(1).max(1_000),
439
+ to: z.union([e164PhoneNumberSchema, z.literal("*")]).default("*"),
440
+ }),
441
+ )
442
+ .output(
443
+ z.object({
444
+ ids: z.string().array(),
445
+ }),
446
+ ),
287
447
  }
package/src/schemas.ts CHANGED
@@ -1,3 +1,9 @@
1
1
  import { z } from "zod"
2
2
 
3
3
  export const reasonableNameSchema = z.string().min(1).max(255).trim()
4
+
5
+ /** Canonical E.164 phone number accepted by SMS boundaries. */
6
+ export const e164PhoneNumberSchema = z
7
+ .string()
8
+ .trim()
9
+ .regex(/^\+[1-9]\d{1,14}$/, "Use an E.164 phone number such as +12065550123.")