@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/dist/runtime.js CHANGED
@@ -1,13 +1,194 @@
1
1
  import { encodableSchema } from "@automate.ax/codec";
2
2
  import { oc } from "@orpc/contract";
3
3
  import { z } from "zod";
4
+ import { e164PhoneNumberSchema } from "./schemas.js";
4
5
  /** Default model used by the platform Vercel AI Gateway account. */
5
6
  export const DEFAULT_GATEWAY_MODEL_ID = "openai/gpt-4.1-nano";
6
7
  const SIGNAL_FAILURE_SCHEMA = z.object({
7
8
  message: z.string(),
8
9
  name: z.string(),
9
10
  });
10
- const TERMINAL_ACTION_STATUS_SCHEMA = z.enum(["closed", "failed", "succeeded"]);
11
+ const OUTCOME_SEQUENCE_SCHEMA = z.number().int().positive();
12
+ const ACTION_INVOCATION_BASE_SCHEMA = z.object({
13
+ actionDependencyIds: z.string().array(),
14
+ description: z.string().nullable(),
15
+ eventDependencyIds: z.string().array(),
16
+ inputHash: z.string(),
17
+ name: z.string(),
18
+ signalDependencyIds: z.string().array(),
19
+ slot: z.number().int().nonnegative(),
20
+ });
21
+ const ACTION_INVOCATION_SCHEMA = z.union([
22
+ ACTION_INVOCATION_BASE_SCHEMA.extend({ status: z.literal("pending") }),
23
+ ACTION_INVOCATION_BASE_SCHEMA.extend({
24
+ reason: z.literal("closed-dependency"),
25
+ status: z.literal("skipped"),
26
+ }),
27
+ ACTION_INVOCATION_BASE_SCHEMA.extend({
28
+ failure: SIGNAL_FAILURE_SCHEMA,
29
+ reason: z.literal("failed-dependency"),
30
+ status: z.literal("skipped"),
31
+ }),
32
+ ]);
33
+ const ACTION_RUN_INVOCATION_BASE_SCHEMA = ACTION_INVOCATION_BASE_SCHEMA.extend({
34
+ actionInvocationId: z.string(),
35
+ });
36
+ const ACTION_RUN_INVOCATION_SCHEMA = z.union([
37
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({ status: z.literal("pending") }),
38
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
39
+ failure: SIGNAL_FAILURE_SCHEMA,
40
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
41
+ status: z.literal("failed"),
42
+ }),
43
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
44
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
45
+ reason: z.literal("closed-dependency"),
46
+ status: z.literal("skipped"),
47
+ }),
48
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
49
+ failure: SIGNAL_FAILURE_SCHEMA,
50
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
51
+ reason: z.literal("failed-dependency"),
52
+ status: z.literal("skipped"),
53
+ }),
54
+ ACTION_RUN_INVOCATION_BASE_SCHEMA.extend({
55
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
56
+ status: z.literal("succeeded"),
57
+ }),
58
+ ]);
59
+ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
60
+ actionDependencyIds: z.string().array(),
61
+ eventDependencyIds: z.string().array(),
62
+ signalDependencyIds: z.string().array(),
63
+ slot: z.number().int().nonnegative(),
64
+ });
65
+ const CORRELATION_ENTRY_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
66
+ key: encodableSchema,
67
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
68
+ streamName: z.string().min(1),
69
+ streamNames: z.string().min(1).array().min(2),
70
+ value: encodableSchema,
71
+ });
72
+ const SIGNAL_INVOCATION_SCHEMA = z.union([
73
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
74
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA.optional(),
75
+ status: z.literal("closed"),
76
+ }),
77
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
78
+ failure: SIGNAL_FAILURE_SCHEMA,
79
+ status: z.literal("failed"),
80
+ }),
81
+ SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
82
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA.optional(),
83
+ selectedIndex: z.number().int().nonnegative().optional(),
84
+ status: z.literal("open"),
85
+ }),
86
+ ]);
87
+ const SIGNAL_BATCH_OUTCOME_BASE_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
88
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
89
+ signalInvocationId: z.string(),
90
+ });
91
+ const SIGNAL_BATCH_OUTCOME_SCHEMA = z.union([
92
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({
93
+ selectedIndex: z.number().int().nonnegative().optional(),
94
+ status: z.literal("open"),
95
+ }),
96
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("closed") }),
97
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({
98
+ failure: SIGNAL_FAILURE_SCHEMA,
99
+ status: z.literal("failed"),
100
+ }),
101
+ SIGNAL_BATCH_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("succeeded") }),
102
+ ]);
103
+ const ACTION_VALUE_OUTCOME_SCHEMA = z.union([
104
+ z.object({
105
+ actionInvocationId: z.string(),
106
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
107
+ slot: z.number().int(),
108
+ status: z.literal("failed"),
109
+ failure: SIGNAL_FAILURE_SCHEMA,
110
+ }),
111
+ z.object({
112
+ actionInvocationId: z.string(),
113
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
114
+ reason: z.literal("closed-dependency"),
115
+ slot: z.number().int(),
116
+ status: z.literal("skipped"),
117
+ }),
118
+ z.object({
119
+ actionInvocationId: z.string(),
120
+ failure: SIGNAL_FAILURE_SCHEMA,
121
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
122
+ reason: z.literal("failed-dependency"),
123
+ slot: z.number().int(),
124
+ status: z.literal("skipped"),
125
+ }),
126
+ z.object({
127
+ actionInvocationId: z.string(),
128
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
129
+ output: encodableSchema,
130
+ slot: z.number().int(),
131
+ status: z.literal("succeeded"),
132
+ }),
133
+ ]);
134
+ const SIGNAL_VALUE_OUTCOME_BASE_SCHEMA = z.object({
135
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
136
+ signalInvocationId: z.string(),
137
+ slot: z.number().int(),
138
+ });
139
+ const SIGNAL_VALUE_OUTCOME_SCHEMA = z.union([
140
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
141
+ selectedIndex: z.number().int().nonnegative().optional(),
142
+ status: z.literal("open"),
143
+ }),
144
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({ status: z.literal("closed") }),
145
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
146
+ failure: SIGNAL_FAILURE_SCHEMA,
147
+ status: z.literal("failed"),
148
+ }),
149
+ SIGNAL_VALUE_OUTCOME_BASE_SCHEMA.extend({
150
+ output: encodableSchema,
151
+ status: z.literal("succeeded"),
152
+ }),
153
+ ]);
154
+ const RUNTIME_VALUE_CONTEXT_SCHEMA = z.object({
155
+ actionOutputs: ACTION_VALUE_OUTCOME_SCHEMA.array(),
156
+ contextId: z.string(),
157
+ events: z
158
+ .object({
159
+ automationEventId: z.string(),
160
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
161
+ payload: encodableSchema,
162
+ slot: z.number().int(),
163
+ })
164
+ .array(),
165
+ signalOutputs: SIGNAL_VALUE_OUTCOME_SCHEMA.array(),
166
+ });
167
+ const RUNTIME_RUN_CONTEXT_SCHEMA = z.object({
168
+ actions: ACTION_RUN_INVOCATION_SCHEMA.array(),
169
+ contextId: z.string(),
170
+ events: z
171
+ .object({
172
+ automationEventId: z.string(),
173
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
174
+ slot: z.number().int(),
175
+ })
176
+ .array(),
177
+ signalOutputs: SIGNAL_BATCH_OUTCOME_SCHEMA.array(),
178
+ });
179
+ const TARGET_ACTION_SCHEMA = z.union([
180
+ z.object({
181
+ context: RUNTIME_VALUE_CONTEXT_SCHEMA,
182
+ id: z.string(),
183
+ slot: z.number().int(),
184
+ status: z.literal("pending"),
185
+ }),
186
+ z.object({
187
+ id: z.string(),
188
+ slot: z.number().int(),
189
+ status: z.enum(["failed", "skipped", "succeeded"]),
190
+ }),
191
+ ]);
11
192
  const GENERATION_WARNING_SCHEMA = z.discriminatedUnion("type", [
12
193
  z.object({
13
194
  details: z.string().optional(),
@@ -126,22 +307,23 @@ const RUNTIME_GENERATION_INPUT_SCHEMA = z.union([
126
307
  export const runtimeContract = {
127
308
  commit: oc
128
309
  .input(z.object({
129
- actionInvocations: z
130
- .object({
131
- actionDependencyIds: z.string().array(),
132
- description: z.string().nullable(),
133
- eventDependencyIds: z.string().array(),
134
- inputHash: z.string(),
135
- name: z.string(),
136
- slot: z.number().int().nonnegative(),
137
- })
138
- .array()
139
- .default([]),
310
+ actionInvocations: ACTION_INVOCATION_SCHEMA.array().default([]),
311
+ correlationEntries: CORRELATION_ENTRY_SCHEMA.array().default([]),
312
+ settled: z.boolean().default(true),
313
+ signalInvocations: SIGNAL_INVOCATION_SCHEMA.array().default([]),
140
314
  }))
141
315
  .output(z.void()),
142
- completeInvocation: oc
143
- .input(z.discriminatedUnion("status", [
144
- z.object({ status: z.literal("closed") }),
316
+ completeAction: oc
317
+ .input(z.union([
318
+ z.object({
319
+ reason: z.literal("closed-dependency"),
320
+ status: z.literal("skipped"),
321
+ }),
322
+ z.object({
323
+ failure: SIGNAL_FAILURE_SCHEMA,
324
+ reason: z.literal("failed-dependency"),
325
+ status: z.literal("skipped"),
326
+ }),
145
327
  z.object({
146
328
  failure: SIGNAL_FAILURE_SCHEMA,
147
329
  status: z.literal("failed"),
@@ -155,63 +337,14 @@ export const runtimeContract = {
155
337
  generate: oc
156
338
  .input(RUNTIME_GENERATION_INPUT_SCHEMA)
157
339
  .output(generationResultSchema),
158
- loadInvocation: oc.output(z.object({
159
- context: z.object({
160
- actionOutputs: z
161
- .discriminatedUnion("status", [
162
- z.object({
163
- actionInvocationId: z.string(),
164
- slot: z.number().int(),
165
- status: z.literal("closed"),
166
- }),
167
- z.object({
168
- actionInvocationId: z.string(),
169
- failure: SIGNAL_FAILURE_SCHEMA,
170
- slot: z.number().int(),
171
- status: z.literal("failed"),
172
- }),
173
- z.object({
174
- actionInvocationId: z.string(),
175
- output: encodableSchema,
176
- slot: z.number().int(),
177
- status: z.literal("succeeded"),
178
- }),
179
- ])
180
- .array(),
181
- contextId: z.string(),
182
- events: z
183
- .object({
184
- automationEventId: z.string(),
185
- payload: encodableSchema,
186
- slot: z.number().int(),
187
- })
188
- .array(),
189
- }),
190
- id: z.string(),
191
- slot: z.number().int(),
192
- })),
193
- nextBatch: oc.output(z.object({
194
- context: z.object({
195
- actionOutputs: z
196
- .object({
197
- actionDependencyIds: z.string().array(),
198
- actionInvocationId: z.string(),
199
- eventDependencyIds: z.string().array(),
200
- inputHash: z.string(),
201
- name: z.string(),
202
- slot: z.number().int(),
203
- status: TERMINAL_ACTION_STATUS_SCHEMA,
204
- })
205
- .array(),
206
- contextId: z.string(),
207
- events: z
208
- .object({
209
- automationEventId: z.string(),
210
- slot: z.number().int(),
211
- })
212
- .array(),
213
- }),
340
+ load: oc.output(z.object({
341
+ context: RUNTIME_RUN_CONTEXT_SCHEMA,
342
+ finalAttempt: z.boolean(),
343
+ targetAction: TARGET_ACTION_SCHEMA.optional(),
214
344
  })),
345
+ loadValues: oc
346
+ .input(SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.omit({ slot: true }))
347
+ .output(RUNTIME_VALUE_CONTEXT_SCHEMA),
215
348
  resolveAccountInput: oc
216
349
  .input(z.strictObject({
217
350
  binding: z.string().min(1),
@@ -240,4 +373,13 @@ export const runtimeContract = {
240
373
  .output(z.object({
241
374
  id: z.string().nullable(),
242
375
  })),
376
+ sendSms: oc
377
+ .input(z.object({
378
+ deliveryIndex: z.number().int().nonnegative().default(0),
379
+ text: z.string().trim().min(1).max(1_000),
380
+ to: z.union([e164PhoneNumberSchema, z.literal("*")]).default("*"),
381
+ }))
382
+ .output(z.object({
383
+ ids: z.string().array(),
384
+ })),
243
385
  };
package/dist/schemas.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  import { z } from "zod";
2
2
  export declare const reasonableNameSchema: z.ZodString;
3
+ /** Canonical E.164 phone number accepted by SMS boundaries. */
4
+ export declare const e164PhoneNumberSchema: z.ZodString;
package/dist/schemas.js CHANGED
@@ -1,2 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export const reasonableNameSchema = z.string().min(1).max(255).trim();
3
+ /** Canonical E.164 phone number accepted by SMS boundaries. */
4
+ export const e164PhoneNumberSchema = z
5
+ .string()
6
+ .trim()
7
+ .regex(/^\+[1-9]\d{1,14}$/, "Use an E.164 phone number such as +12065550123.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automate.ax/api-contract",
3
- "version": "0.45.0",
3
+ "version": "0.47.0",
4
4
  "description": "Public oRPC contract for the Automate.ax API.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@ai-sdk/gateway": "^4.0.46",
30
- "@automate.ax/codec": "0.45.0",
30
+ "@automate.ax/codec": "0.47.0",
31
31
  "@orpc/contract": "1.13.14",
32
32
  "zod": "^4.3.6"
33
33
  },
package/src/automation.ts CHANGED
@@ -73,7 +73,7 @@ export const automationContract = {
73
73
  name: z.string(),
74
74
  output: encodableSchema,
75
75
  slot: z.number().int().nonnegative(),
76
- status: z.enum(["pending", "succeeded", "closed", "failed"]),
76
+ status: z.enum(["pending", "succeeded", "skipped", "failed"]),
77
77
  })
78
78
  .array(),
79
79
  events: z
package/src/index.ts CHANGED
@@ -42,13 +42,14 @@ export {
42
42
  organizationDetailsOutputSchema,
43
43
  organizationInvitationOutputSchema,
44
44
  organizationMemberOutputSchema,
45
+ organizationPhoneNumberOutputSchema,
45
46
  organizationProjectOutputSchema,
46
47
  organizationRoleSchema,
47
48
  organizationSummaryOutputSchema,
48
49
  publicOrganizationOutputSchema,
49
50
  } from "./org"
50
51
  export { projectOutputSchema } from "./project"
51
- export { reasonableNameSchema } from "./schemas"
52
+ export { e164PhoneNumberSchema, reasonableNameSchema } from "./schemas"
52
53
  export { userOutputSchema } from "./auth"
53
54
  export {
54
55
  managementPermissionStatement,
@@ -99,6 +100,9 @@ export const firstPartyContract = {
99
100
  canInvite: orgContract.canInvite,
100
101
  createBillingPortal: orgContract.createBillingPortal,
101
102
  createCheckout: orgContract.createCheckout,
103
+ removePhoneNumber: orgContract.removePhoneNumber,
104
+ requestPhoneNumberVerification: orgContract.requestPhoneNumberVerification,
105
+ verifyPhoneNumber: orgContract.verifyPhoneNumber,
102
106
  },
103
107
  project: {
104
108
  ...publicContract.project,
package/src/org.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { oc } from "@orpc/contract"
2
2
  import { z } from "zod"
3
- import { reasonableNameSchema } from "./schemas"
3
+ import { e164PhoneNumberSchema, reasonableNameSchema } from "./schemas"
4
4
 
5
5
  export const organizationRoleSchema = z.enum(["member", "admin", "owner"])
6
6
 
@@ -34,13 +34,23 @@ export const organizationSummaryOutputSchema = z.object({
34
34
  emailRecipients: z.number(),
35
35
  projects: z.number(),
36
36
  seats: z.number(),
37
+ smsSegments: z.number(),
37
38
  }),
38
39
  usage: z.object({
39
40
  aiSpendUsd: z.number(),
40
41
  emailRecipients: z.number(),
42
+ smsSegments: z.number(),
41
43
  }),
42
44
  })
43
45
 
46
+ export const organizationPhoneNumberOutputSchema = z.object({
47
+ id: z.string(),
48
+ phoneNumber: e164PhoneNumberSchema,
49
+ createdAt: z.date(),
50
+ verifiedAt: z.date().nullable(),
51
+ consentedAt: z.date().nullable(),
52
+ })
53
+
44
54
  export const organizationMemberOutputSchema = z.object({
45
55
  id: z.string(),
46
56
  userId: z.string(),
@@ -70,6 +80,7 @@ export const organizationDetailsOutputSchema =
70
80
  organizationSummaryOutputSchema.extend({
71
81
  members: organizationMemberOutputSchema.array(),
72
82
  invitations: organizationInvitationOutputSchema.array(),
83
+ phoneNumbers: organizationPhoneNumberOutputSchema.array(),
73
84
  projects: organizationProjectOutputSchema.array(),
74
85
  })
75
86
 
@@ -197,6 +208,48 @@ export const orgContract = {
197
208
  }),
198
209
  )
199
210
  .output(z.void()),
211
+ removePhoneNumber: oc
212
+ .route({
213
+ method: "DELETE",
214
+ path: "/organizations/{organizationId}/phone-numbers/{phoneNumberId}",
215
+ operationId: "removeOrganizationPhoneNumber",
216
+ summary: "Remove organization phone number",
217
+ description:
218
+ "Removes an organization SMS destination and its verification and consent state.",
219
+ tags: ["Organizations"],
220
+ successStatus: 204,
221
+ })
222
+ .input(
223
+ z.object({
224
+ organizationId: z.string(),
225
+ phoneNumberId: z.string(),
226
+ }),
227
+ )
228
+ .output(z.void()),
229
+ requestPhoneNumberVerification: oc
230
+ .route({
231
+ method: "POST",
232
+ path: "/organizations/{organizationId}/phone-numbers/verifications",
233
+ operationId: "requestOrganizationPhoneNumberVerification",
234
+ summary: "Request organization phone verification",
235
+ description:
236
+ "Sends a verification code after the caller explicitly consents to organization automation SMS alerts.",
237
+ tags: ["Organizations"],
238
+ successStatus: 201,
239
+ })
240
+ .input(
241
+ z.object({
242
+ organizationId: z.string(),
243
+ phoneNumber: e164PhoneNumberSchema,
244
+ smsConsent: z.literal(true),
245
+ }),
246
+ )
247
+ .output(
248
+ z.object({
249
+ expiresAt: z.date(),
250
+ phoneNumberId: z.string(),
251
+ }),
252
+ ),
200
253
  update: oc
201
254
  .route({
202
255
  method: "PATCH",
@@ -214,4 +267,26 @@ export const orgContract = {
214
267
  }),
215
268
  )
216
269
  .output(z.void()),
270
+ verifyPhoneNumber: oc
271
+ .route({
272
+ method: "POST",
273
+ path: "/organizations/{organizationId}/phone-numbers/{phoneNumberId}/verification",
274
+ operationId: "verifyOrganizationPhoneNumber",
275
+ summary: "Verify organization phone number",
276
+ description:
277
+ "Verifies possession of an organization SMS destination and activates its recorded consent.",
278
+ tags: ["Organizations"],
279
+ successStatus: 204,
280
+ })
281
+ .input(
282
+ z.object({
283
+ organizationId: z.string(),
284
+ phoneNumberId: z.string(),
285
+ code: z
286
+ .string()
287
+ .trim()
288
+ .regex(/^\d{6}$/),
289
+ }),
290
+ )
291
+ .output(z.void()),
217
292
  }