@automate.ax/api-contract 0.81.0 → 0.83.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
@@ -7,6 +7,7 @@ import { automationErrorSchema } from "./errors.js";
7
7
  export const DEFAULT_GATEWAY_MODEL_ID = "openai/gpt-4.1-nano";
8
8
  export const AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT = "default";
9
9
  export const AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX = "__$";
10
+ export const AUTOMATION_DELAY_ENTRYPOINT_PREFIX = `${AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX}delay:`;
10
11
  export const CALLBACK_PROTECTION_QUERY_PARAMETER = "_axCallback";
11
12
  export const AUTOMATION_LOG_MAX_ENTRIES = 1_000;
12
13
  export const AUTOMATION_TRACE_MAX_SPANS = 250;
@@ -93,8 +94,55 @@ export const automationInvocationInputSchema = z
93
94
  }),
94
95
  ]))
95
96
  .and(automationInvocationScheduleSchema);
97
+ const SIGNAL_DERIVATION_NODE_SCHEMA = z.discriminatedUnion("type", [
98
+ z.object({
99
+ id: z.string().min(1),
100
+ source: z.enum(["action", "event", "signal"]),
101
+ type: z.literal("source"),
102
+ }),
103
+ z.object({
104
+ inputs: z.number().int().nonnegative().array().min(1),
105
+ property: z.string(),
106
+ type: z.literal("property"),
107
+ }),
108
+ z.object({
109
+ inputs: z.number().int().nonnegative().array().min(1),
110
+ type: z.literal("transform"),
111
+ }),
112
+ ]);
113
+ /** Compact concrete derivation graph persisted for one durable consumer. */
114
+ export const signalDerivationSchema = z
115
+ .object({
116
+ nodes: SIGNAL_DERIVATION_NODE_SCHEMA.array().min(1),
117
+ roots: z.number().int().nonnegative().array().min(1),
118
+ })
119
+ .superRefine(({ nodes, roots }, context) => {
120
+ for (const [index, node] of nodes.entries()) {
121
+ if (node.type === "source")
122
+ continue;
123
+ for (const input of node.inputs) {
124
+ if (input >= index) {
125
+ context.addIssue({
126
+ code: "custom",
127
+ message: "Derivation inputs must reference preceding nodes.",
128
+ path: ["nodes", index, "inputs"],
129
+ });
130
+ }
131
+ }
132
+ }
133
+ for (const [index, root] of roots.entries()) {
134
+ if (root >= nodes.length) {
135
+ context.addIssue({
136
+ code: "custom",
137
+ message: "Derivation roots must reference an existing node.",
138
+ path: ["roots", index],
139
+ });
140
+ }
141
+ }
142
+ });
96
143
  const ACTION_INVOCATION_BASE_SCHEMA = z.object({
97
144
  actionDependencyIds: z.string().array(),
145
+ derivation: signalDerivationSchema.nullable(),
98
146
  description: z.string().nullable(),
99
147
  eventDependencyIds: z.string().array(),
100
148
  inputHash: z.string(),
@@ -142,13 +190,16 @@ const ACTION_RUN_INVOCATION_SCHEMA = z.union([
142
190
  status: z.literal("succeeded"),
143
191
  }),
144
192
  ]);
145
- const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
193
+ const SIGNAL_DEPENDENCIES_SCHEMA = z.object({
146
194
  actionDependencyIds: z.string().array(),
147
195
  eventDependencyIds: z.string().array(),
148
196
  scopePath: HOOK_SCOPE_PATH_SCHEMA,
149
197
  signalDependencyIds: z.string().array(),
150
198
  slot: z.number().int().nonnegative(),
151
199
  });
200
+ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = SIGNAL_DEPENDENCIES_SCHEMA.extend({
201
+ derivation: signalDerivationSchema.nullable(),
202
+ });
152
203
  const COORDINATION_PRIMARY_POSITION_SCHEMA = z.enum(["first", "last"]);
153
204
  const COORDINATION_DURATION_SCHEMA = z.union([
154
205
  z.string().min(1),
@@ -624,7 +675,7 @@ export const runtimeContract = {
624
675
  targetAction: TARGET_ACTION_SCHEMA.optional(),
625
676
  })),
626
677
  loadValues: oc
627
- .input(SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.omit({
678
+ .input(SIGNAL_DEPENDENCIES_SCHEMA.omit({
628
679
  scopePath: true,
629
680
  slot: true,
630
681
  }))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automate.ax/api-contract",
3
- "version": "0.81.0",
3
+ "version": "0.83.0",
4
4
  "description": "Public oRPC contract for the Automate.ax API.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -21,6 +21,7 @@
21
21
  ".": "./src/index.ts",
22
22
  "./errors": "./src/errors.ts",
23
23
  "./permissions": "./src/permissions.ts",
24
+ "./runtime-protocol": "./src/runtime-protocol.ts",
24
25
  "./runtime": "./src/runtime.ts"
25
26
  },
26
27
  "cjs": false,
@@ -30,13 +31,14 @@
30
31
  },
31
32
  "dependencies": {
32
33
  "@ai-sdk/gateway": "^4.0.46",
33
- "@automate.ax/codec": "0.81.0",
34
+ "@automate.ax/codec": "0.83.0",
35
+ "@automate.ax/integration-contracts": "0.83.0",
34
36
  "@orpc/contract": "1.15.0",
35
37
  "fast-json-stable-stringify": "^2.1.0",
36
38
  "zod": "^4.3.6"
37
39
  },
38
40
  "devDependencies": {
39
- "@internal/config": "0.0.0",
41
+ "@internal/config": "0.1.0",
40
42
  "@types/bun": "latest",
41
43
  "@typescript/native": "npm:typescript@^7.0.2",
42
44
  "@zachsents/oxlint-config": "^0.4.1",
@@ -81,6 +83,11 @@
81
83
  "types": "./dist/permissions.d.ts",
82
84
  "default": "./dist/permissions.js"
83
85
  },
86
+ "./runtime-protocol": {
87
+ "bun": "./src/runtime-protocol.ts",
88
+ "types": "./dist/runtime-protocol.d.ts",
89
+ "default": "./dist/runtime-protocol.js"
90
+ },
84
91
  "./runtime": {
85
92
  "bun": "./src/runtime.ts",
86
93
  "types": "./dist/runtime.d.ts",
package/src/deployment.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { oc } from "@orpc/contract"
2
2
  import * as z from "zod"
3
+ import { AUTOMATION_RUNTIME_PROTOCOL_VERSION } from "./runtime-protocol"
3
4
  import { cursorPageOutputSchema, cursorPaginationInputSchema } from "./schemas"
4
5
 
5
6
  /** SDK compatibility version used to select the immutable runtime image. */
@@ -24,6 +25,15 @@ const DEPLOYMENT_IN_PROGRESS_ERROR = {
24
25
  status: 409,
25
26
  } as const
26
27
 
28
+ const UNSUPPORTED_RUNTIME_PROTOCOL_ERROR = {
29
+ data: z.object({
30
+ receivedVersion: z.number().int().positive().nullable(),
31
+ supportedVersion: z.literal(AUTOMATION_RUNTIME_PROTOCOL_VERSION),
32
+ }),
33
+ message: "The automation bundle uses an unsupported runtime protocol.",
34
+ status: 400,
35
+ } as const
36
+
27
37
  const GIT_SOURCE_SCHEMA = z.object({
28
38
  commitSha: z.string().regex(/^[0-9a-f]{40}(?:[0-9a-f]{24})?$/),
29
39
  dirty: z.boolean(),
@@ -96,7 +106,10 @@ export const deploymentContract = {
96
106
  .input(z.object({ deploymentId: z.string() }))
97
107
  .output(z.void()),
98
108
  create: oc
99
- .errors({ DEPLOYMENT_IN_PROGRESS: DEPLOYMENT_IN_PROGRESS_ERROR })
109
+ .errors({
110
+ DEPLOYMENT_IN_PROGRESS: DEPLOYMENT_IN_PROGRESS_ERROR,
111
+ UNSUPPORTED_RUNTIME_PROTOCOL: UNSUPPORTED_RUNTIME_PROTOCOL_ERROR,
112
+ })
100
113
  .input(
101
114
  z.object({
102
115
  artifact: z.instanceof(Blob),
@@ -123,6 +136,7 @@ export const deploymentContract = {
123
136
  mode: z.enum(["reconcile", "upsert"]),
124
137
  projectId: z.string(),
125
138
  rebindAccounts: z.boolean().default(false),
139
+ runtimeProtocolVersion: z.number().int().positive().optional(),
126
140
  git: GIT_SOURCE_SCHEMA.optional(),
127
141
  }),
128
142
  )
@@ -171,7 +185,10 @@ export const deploymentContract = {
171
185
  )
172
186
  .output(cursorPageOutputSchema(deploymentOutputSchema)),
173
187
  redeploy: oc
174
- .errors({ DEPLOYMENT_IN_PROGRESS: DEPLOYMENT_IN_PROGRESS_ERROR })
188
+ .errors({
189
+ DEPLOYMENT_IN_PROGRESS: DEPLOYMENT_IN_PROGRESS_ERROR,
190
+ UNSUPPORTED_RUNTIME_PROTOCOL: UNSUPPORTED_RUNTIME_PROTOCOL_ERROR,
191
+ })
175
192
  .route({
176
193
  method: "POST",
177
194
  path: "/projects/{projectId}/deployments/redeploy",
@@ -0,0 +1,26 @@
1
+ import { oc } from "@orpc/contract"
2
+ import * as z from "zod"
3
+
4
+ export const convexEventsContract = {
5
+ convexEvent: oc
6
+ .route({
7
+ description:
8
+ "Authenticates and ingests a semantic event emitted by a Convex action.",
9
+ method: "POST",
10
+ operationId: "receiveConvexEvent",
11
+ path: "/events/convex/{endpointKey}",
12
+ successStatus: 204,
13
+ summary: "Receive a signed Convex event",
14
+ tags: ["Events"],
15
+ })
16
+ .input(
17
+ z.object({
18
+ emittedAt: z.iso.datetime({ offset: true }),
19
+ endpointKey: z.string(),
20
+ id: z.string(),
21
+ name: z.string(),
22
+ payload: z.json(),
23
+ }),
24
+ )
25
+ .output(z.void()),
26
+ }
@@ -1,6 +1,7 @@
1
1
  import { airtableEventsContract } from "./airtable"
2
2
  import { asanaEventsContract } from "./asana"
3
3
  import { brevoEventsContract } from "./brevo"
4
+ import { convexEventsContract } from "./convex"
4
5
  import { googleCalendarEventsContract } from "./google-calendar"
5
6
  import { googleFormsEventsContract } from "./google-forms"
6
7
  import { googleMeetEventsContract } from "./google-meet"
@@ -19,6 +20,7 @@ export const eventsContract = {
19
20
  ...airtableEventsContract,
20
21
  ...asanaEventsContract,
21
22
  ...brevoEventsContract,
23
+ ...convexEventsContract,
22
24
  ...googleCalendarEventsContract,
23
25
  ...googleFormsEventsContract,
24
26
  ...googleMeetEventsContract,
@@ -1,11 +1,12 @@
1
1
  import { oc } from "@orpc/contract"
2
2
  import { z } from "zod"
3
3
 
4
- export const EXECUTION_DATASET_VERSION = 4
4
+ export const EXECUTION_DATASET_VERSION = 6
5
5
 
6
6
  export const executionDatasetResourceSchema = z.enum([
7
7
  "projects",
8
8
  "automations",
9
+ "automation-invocations",
9
10
  "contexts",
10
11
  "context-parents",
11
12
  "event-links",
package/src/index.ts CHANGED
@@ -29,6 +29,7 @@ export {
29
29
  deploymentOutputSchema,
30
30
  deploymentStatusSchema,
31
31
  } from "./deployment"
32
+ export { AUTOMATION_RUNTIME_PROTOCOL_VERSION } from "./runtime-protocol"
32
33
  export {
33
34
  AUTOMATION_ERROR_CAUSE_DEPTH,
34
35
  automationErrorSchema,
package/src/org.ts CHANGED
@@ -32,10 +32,12 @@ export const organizationSummaryOutputSchema = z.object({
32
32
  pendingInvitationCount: z.number(),
33
33
  projectCount: z.number(),
34
34
  activeSubscription: activeSubscriptionOutputSchema.nullable(),
35
+ executionRetentionDays: z.number().int().positive(),
35
36
  plan: z.enum(["free", "pro", "enterprise"]),
36
37
  limits: z.object({
37
38
  aiSpendUsd: z.number(),
38
39
  emailSends: z.number(),
40
+ executionRetentionDays: z.number().int().positive(),
39
41
  projects: z.number(),
40
42
  seats: z.number(),
41
43
  }),
@@ -225,10 +227,23 @@ export const orgContract = {
225
227
  tags: ["Organizations"],
226
228
  })
227
229
  .input(
228
- z.object({
229
- organizationId: z.string(),
230
- name: reasonableNameSchema,
231
- }),
230
+ z
231
+ .object({
232
+ executionRetentionDays: z
233
+ .number()
234
+ .int()
235
+ .positive()
236
+ .nullable()
237
+ .optional(),
238
+ organizationId: z.string(),
239
+ name: reasonableNameSchema.optional(),
240
+ })
241
+ .refine(
242
+ (input) =>
243
+ input.executionRetentionDays !== undefined ||
244
+ input.name !== undefined,
245
+ "Provide an organization setting to update.",
246
+ ),
232
247
  )
233
248
  .output(z.void()),
234
249
  }
@@ -0,0 +1,2 @@
1
+ /** Runtime protocol required by newly built automation bundles. */
2
+ export const AUTOMATION_RUNTIME_PROTOCOL_VERSION = 1
package/src/runtime.ts CHANGED
@@ -12,6 +12,8 @@ export const DEFAULT_GATEWAY_MODEL_ID =
12
12
  "openai/gpt-4.1-nano" satisfies GatewayModelId
13
13
  export const AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT = "default"
14
14
  export const AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX = "__$"
15
+ export const AUTOMATION_DELAY_ENTRYPOINT_PREFIX =
16
+ `${AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX}delay:` as const
15
17
  export const CALLBACK_PROTECTION_QUERY_PARAMETER = "_axCallback"
16
18
  export const AUTOMATION_LOG_MAX_ENTRIES = 1_000
17
19
  export const AUTOMATION_TRACE_MAX_SPANS = 250
@@ -110,8 +112,59 @@ export const automationInvocationInputSchema = z
110
112
  )
111
113
  .and(automationInvocationScheduleSchema)
112
114
 
115
+ const SIGNAL_DERIVATION_NODE_SCHEMA = z.discriminatedUnion("type", [
116
+ z.object({
117
+ id: z.string().min(1),
118
+ source: z.enum(["action", "event", "signal"]),
119
+ type: z.literal("source"),
120
+ }),
121
+ z.object({
122
+ inputs: z.number().int().nonnegative().array().min(1),
123
+ property: z.string(),
124
+ type: z.literal("property"),
125
+ }),
126
+ z.object({
127
+ inputs: z.number().int().nonnegative().array().min(1),
128
+ type: z.literal("transform"),
129
+ }),
130
+ ])
131
+
132
+ /** Compact concrete derivation graph persisted for one durable consumer. */
133
+ export const signalDerivationSchema = z
134
+ .object({
135
+ nodes: SIGNAL_DERIVATION_NODE_SCHEMA.array().min(1),
136
+ roots: z.number().int().nonnegative().array().min(1),
137
+ })
138
+ .superRefine(({ nodes, roots }, context) => {
139
+ for (const [index, node] of nodes.entries()) {
140
+ if (node.type === "source") continue
141
+ for (const input of node.inputs) {
142
+ if (input >= index) {
143
+ context.addIssue({
144
+ code: "custom",
145
+ message: "Derivation inputs must reference preceding nodes.",
146
+ path: ["nodes", index, "inputs"],
147
+ })
148
+ }
149
+ }
150
+ }
151
+ for (const [index, root] of roots.entries()) {
152
+ if (root >= nodes.length) {
153
+ context.addIssue({
154
+ code: "custom",
155
+ message: "Derivation roots must reference an existing node.",
156
+ path: ["roots", index],
157
+ })
158
+ }
159
+ }
160
+ })
161
+
162
+ /** Persisted source, property, and opaque transform derivation graph. */
163
+ export type SignalDerivation = z.infer<typeof signalDerivationSchema>
164
+
113
165
  const ACTION_INVOCATION_BASE_SCHEMA = z.object({
114
166
  actionDependencyIds: z.string().array(),
167
+ derivation: signalDerivationSchema.nullable(),
115
168
  description: z.string().nullable(),
116
169
  eventDependencyIds: z.string().array(),
117
170
  inputHash: z.string(),
@@ -163,7 +216,7 @@ const ACTION_RUN_INVOCATION_SCHEMA = z.union([
163
216
  }),
164
217
  ])
165
218
 
166
- const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
219
+ const SIGNAL_DEPENDENCIES_SCHEMA = z.object({
167
220
  actionDependencyIds: z.string().array(),
168
221
  eventDependencyIds: z.string().array(),
169
222
  scopePath: HOOK_SCOPE_PATH_SCHEMA,
@@ -171,6 +224,12 @@ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
171
224
  slot: z.number().int().nonnegative(),
172
225
  })
173
226
 
227
+ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = SIGNAL_DEPENDENCIES_SCHEMA.extend(
228
+ {
229
+ derivation: signalDerivationSchema.nullable(),
230
+ },
231
+ )
232
+
174
233
  const COORDINATION_PRIMARY_POSITION_SCHEMA = z.enum(["first", "last"])
175
234
  const COORDINATION_DURATION_SCHEMA = z.union([
176
235
  z.string().min(1),
@@ -722,7 +781,7 @@ export const runtimeContract = {
722
781
  ),
723
782
  loadValues: oc
724
783
  .input(
725
- SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.omit({
784
+ SIGNAL_DEPENDENCIES_SCHEMA.omit({
726
785
  scopePath: true,
727
786
  slot: true,
728
787
  }),