@automate.ax/api-contract 0.57.2 → 0.57.4

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/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { automationExecutionStatusSchema } from "./automation.js";
2
2
  export { AUTOMATION_SDK_VERSION } from "./deployment.js";
3
3
  export { integrationAccountOutputSchema } from "./account.js";
4
- export { AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT, AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX, DEFAULT_GATEWAY_MODEL_ID, automationInvocationInputSchema, automationInvocationOutputSchema, automationInvocationScheduleSchema, generationInputSchema, generationResultSchema, runtimeContract, type GenerationInput, type GenerationResult, type RuntimeGenerationInput, } from "./runtime.js";
4
+ export { AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT, AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX, DEFAULT_GATEWAY_MODEL_ID, automationInvocationInputSchema, automationInvocationOutputSchema, automationInvocationScheduleSchema, generationInputSchema, generationResultSchema, hashSignalCoordinatorConfiguration, runtimeContract, type GenerationInput, type GenerationResult, type RuntimeGenerationInput, } from "./runtime.js";
5
5
  export type { GatewayModelId } from "@ai-sdk/gateway";
6
6
  export { createdOrganizationApiKeyOutputSchema, organizationApiKeyOutputSchema, } from "./api-key.js";
7
7
  export { activeSubscriptionOutputSchema, createdInvitationOutputSchema, organizationDetailsOutputSchema, organizationInvitationOutputSchema, organizationMemberOutputSchema, organizationProjectOutputSchema, organizationRoleSchema, organizationSummaryOutputSchema, publicOrganizationOutputSchema, } from "./org.js";
@@ -1135,16 +1135,68 @@ export declare const contract: {
1135
1135
  scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1136
1136
  signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1137
1137
  slot: import("zod").ZodNumber;
1138
- duration: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>;
1139
1138
  key: import("zod").ZodOptional<import("zod").ZodCustom<import("@automate.ax/codec").Encodable, import("@automate.ax/codec").Encodable>>;
1139
+ maxBurstDuration: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
1140
+ minGap: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
1141
+ minQuietPeriod: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
1140
1142
  outcomeSeq: import("zod").ZodNumber;
1141
- policy: import("zod").ZodLiteral<"window">;
1143
+ policy: import("zod").ZodLiteral<"funnel">;
1142
1144
  primaryPosition: import("zod").ZodEnum<{
1143
1145
  first: "first";
1144
1146
  last: "last";
1145
1147
  }>;
1148
+ selection: import("zod").ZodEnum<{
1149
+ first: "first";
1150
+ last: "last";
1151
+ all: "all";
1152
+ }>;
1153
+ triggerAt: import("zod").ZodEnum<{
1154
+ start: "start";
1155
+ end: "end";
1156
+ both: "both";
1157
+ }>;
1146
1158
  ttl: import("zod").ZodOptional<import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodNumber]>>;
1147
- }, import("zod/v4/core").$strip>]>>>;
1159
+ }, import("zod/v4/core").$strip>, import("zod").ZodUnion<readonly [import("zod").ZodObject<{
1160
+ actionDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1161
+ eventDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1162
+ scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1163
+ signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1164
+ slot: import("zod").ZodNumber;
1165
+ inputOrigins: import("zod").ZodArray<import("zod").ZodArray<import("zod").ZodString>>;
1166
+ outcomeSeq: import("zod").ZodNumber;
1167
+ policy: import("zod").ZodLiteral<"race">;
1168
+ scopeOrigins: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
1169
+ selectedIndex: import("zod").ZodNumber;
1170
+ status: import("zod").ZodLiteral<"closed">;
1171
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
1172
+ actionDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1173
+ eventDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1174
+ scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1175
+ signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1176
+ slot: import("zod").ZodNumber;
1177
+ inputOrigins: import("zod").ZodArray<import("zod").ZodArray<import("zod").ZodString>>;
1178
+ outcomeSeq: import("zod").ZodNumber;
1179
+ policy: import("zod").ZodLiteral<"race">;
1180
+ scopeOrigins: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
1181
+ selectedIndex: import("zod").ZodNumber;
1182
+ failure: import("zod").ZodObject<{
1183
+ message: import("zod").ZodString;
1184
+ name: import("zod").ZodString;
1185
+ }, import("zod/v4/core").$strip>;
1186
+ status: import("zod").ZodLiteral<"failed">;
1187
+ }, import("zod/v4/core").$strip>, import("zod").ZodObject<{
1188
+ actionDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1189
+ eventDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1190
+ scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1191
+ signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1192
+ slot: import("zod").ZodNumber;
1193
+ inputOrigins: import("zod").ZodArray<import("zod").ZodArray<import("zod").ZodString>>;
1194
+ outcomeSeq: import("zod").ZodNumber;
1195
+ policy: import("zod").ZodLiteral<"race">;
1196
+ scopeOrigins: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodString>>;
1197
+ selectedIndex: import("zod").ZodNumber;
1198
+ status: import("zod").ZodLiteral<"succeeded">;
1199
+ }, import("zod/v4/core").$strip>]>]>>>;
1148
1200
  settled: import("zod").ZodDefault<import("zod").ZodBoolean>;
1149
1201
  signalInvocations: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
1150
1202
  actionDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
@@ -1417,6 +1469,7 @@ export declare const contract: {
1417
1469
  scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1418
1470
  signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1419
1471
  slot: import("zod").ZodNumber;
1472
+ coordinatorConfigurationHash: import("zod").ZodOptional<import("zod").ZodString>;
1420
1473
  contextId: import("zod").ZodString;
1421
1474
  outcomeSeq: import("zod").ZodNumber;
1422
1475
  signalInvocationId: import("zod").ZodString;
@@ -1428,6 +1481,7 @@ export declare const contract: {
1428
1481
  scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1429
1482
  signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1430
1483
  slot: import("zod").ZodNumber;
1484
+ coordinatorConfigurationHash: import("zod").ZodOptional<import("zod").ZodString>;
1431
1485
  contextId: import("zod").ZodString;
1432
1486
  outcomeSeq: import("zod").ZodNumber;
1433
1487
  signalInvocationId: import("zod").ZodString;
@@ -1438,6 +1492,7 @@ export declare const contract: {
1438
1492
  scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1439
1493
  signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1440
1494
  slot: import("zod").ZodNumber;
1495
+ coordinatorConfigurationHash: import("zod").ZodOptional<import("zod").ZodString>;
1441
1496
  contextId: import("zod").ZodString;
1442
1497
  outcomeSeq: import("zod").ZodNumber;
1443
1498
  signalInvocationId: import("zod").ZodString;
@@ -1452,6 +1507,7 @@ export declare const contract: {
1452
1507
  scopePath: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodNumber>>;
1453
1508
  signalDependencyIds: import("zod").ZodArray<import("zod").ZodString>;
1454
1509
  slot: import("zod").ZodNumber;
1510
+ coordinatorConfigurationHash: import("zod").ZodOptional<import("zod").ZodString>;
1455
1511
  contextId: import("zod").ZodString;
1456
1512
  outcomeSeq: import("zod").ZodNumber;
1457
1513
  signalInvocationId: import("zod").ZodString;
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { runtimeContract } from "./runtime.js";
11
11
  export { automationExecutionStatusSchema } from "./automation.js";
12
12
  export { AUTOMATION_SDK_VERSION } from "./deployment.js";
13
13
  export { integrationAccountOutputSchema } from "./account.js";
14
- export { AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT, AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX, DEFAULT_GATEWAY_MODEL_ID, automationInvocationInputSchema, automationInvocationOutputSchema, automationInvocationScheduleSchema, generationInputSchema, generationResultSchema, runtimeContract, } from "./runtime.js";
14
+ export { AUTOMATION_INVOCATION_DEFAULT_ENTRYPOINT, AUTOMATION_INVOCATION_RESERVED_ENTRYPOINT_PREFIX, DEFAULT_GATEWAY_MODEL_ID, automationInvocationInputSchema, automationInvocationOutputSchema, automationInvocationScheduleSchema, generationInputSchema, generationResultSchema, hashSignalCoordinatorConfiguration, runtimeContract, } from "./runtime.js";
15
15
  export { createdOrganizationApiKeyOutputSchema, organizationApiKeyOutputSchema, } from "./api-key.js";
16
16
  export { activeSubscriptionOutputSchema, createdInvitationOutputSchema, organizationDetailsOutputSchema, organizationInvitationOutputSchema, organizationMemberOutputSchema, organizationProjectOutputSchema, organizationRoleSchema, organizationSummaryOutputSchema, publicOrganizationOutputSchema, } from "./org.js";
17
17
  export { projectOutputSchema } from "./project.js";
package/dist/runtime.d.ts CHANGED
@@ -187,6 +187,13 @@ declare const RUNTIME_GENERATION_INPUT_SCHEMA: z.ZodUnion<readonly [z.ZodObject<
187
187
  }, z.core.$strip>>;
188
188
  }, z.core.$strip>]>;
189
189
  export type RuntimeGenerationInput = z.output<typeof RUNTIME_GENERATION_INPUT_SCHEMA>;
190
+ /**
191
+ * Hashes one coordinator definition exactly as the runtime stores it.
192
+ *
193
+ * @param definition - Structural coordinator definition.
194
+ * @param primaryPosition - Optional inherited-parent precedence.
195
+ */
196
+ export declare function hashSignalCoordinatorConfiguration(definition: unknown, primaryPosition?: "first" | "last"): Promise<string>;
190
197
  export declare const runtimeContract: {
191
198
  commit: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
192
199
  actionInvocations: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
@@ -260,16 +267,68 @@ export declare const runtimeContract: {
260
267
  scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
261
268
  signalDependencyIds: z.ZodArray<z.ZodString>;
262
269
  slot: z.ZodNumber;
263
- duration: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
264
270
  key: z.ZodOptional<z.ZodCustom<import("@automate.ax/codec").Encodable, import("@automate.ax/codec").Encodable>>;
271
+ maxBurstDuration: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
272
+ minGap: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
273
+ minQuietPeriod: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
265
274
  outcomeSeq: z.ZodNumber;
266
- policy: z.ZodLiteral<"window">;
275
+ policy: z.ZodLiteral<"funnel">;
267
276
  primaryPosition: z.ZodEnum<{
268
277
  first: "first";
269
278
  last: "last";
270
279
  }>;
280
+ selection: z.ZodEnum<{
281
+ first: "first";
282
+ last: "last";
283
+ all: "all";
284
+ }>;
285
+ triggerAt: z.ZodEnum<{
286
+ start: "start";
287
+ end: "end";
288
+ both: "both";
289
+ }>;
271
290
  ttl: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
272
- }, z.core.$strip>]>>>;
291
+ }, z.core.$strip>, z.ZodUnion<readonly [z.ZodObject<{
292
+ actionDependencyIds: z.ZodArray<z.ZodString>;
293
+ eventDependencyIds: z.ZodArray<z.ZodString>;
294
+ scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
295
+ signalDependencyIds: z.ZodArray<z.ZodString>;
296
+ slot: z.ZodNumber;
297
+ inputOrigins: z.ZodArray<z.ZodArray<z.ZodString>>;
298
+ outcomeSeq: z.ZodNumber;
299
+ policy: z.ZodLiteral<"race">;
300
+ scopeOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
301
+ selectedIndex: z.ZodNumber;
302
+ status: z.ZodLiteral<"closed">;
303
+ }, z.core.$strip>, z.ZodObject<{
304
+ actionDependencyIds: z.ZodArray<z.ZodString>;
305
+ eventDependencyIds: z.ZodArray<z.ZodString>;
306
+ scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
307
+ signalDependencyIds: z.ZodArray<z.ZodString>;
308
+ slot: z.ZodNumber;
309
+ inputOrigins: z.ZodArray<z.ZodArray<z.ZodString>>;
310
+ outcomeSeq: z.ZodNumber;
311
+ policy: z.ZodLiteral<"race">;
312
+ scopeOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
313
+ selectedIndex: z.ZodNumber;
314
+ failure: z.ZodObject<{
315
+ message: z.ZodString;
316
+ name: z.ZodString;
317
+ }, z.core.$strip>;
318
+ status: z.ZodLiteral<"failed">;
319
+ }, z.core.$strip>, z.ZodObject<{
320
+ actionDependencyIds: z.ZodArray<z.ZodString>;
321
+ eventDependencyIds: z.ZodArray<z.ZodString>;
322
+ scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
323
+ signalDependencyIds: z.ZodArray<z.ZodString>;
324
+ slot: z.ZodNumber;
325
+ inputOrigins: z.ZodArray<z.ZodArray<z.ZodString>>;
326
+ outcomeSeq: z.ZodNumber;
327
+ policy: z.ZodLiteral<"race">;
328
+ scopeOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
329
+ selectedIndex: z.ZodNumber;
330
+ status: z.ZodLiteral<"succeeded">;
331
+ }, z.core.$strip>]>]>>>;
273
332
  settled: z.ZodDefault<z.ZodBoolean>;
274
333
  signalInvocations: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
275
334
  actionDependencyIds: z.ZodArray<z.ZodString>;
@@ -542,6 +601,7 @@ export declare const runtimeContract: {
542
601
  scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
543
602
  signalDependencyIds: z.ZodArray<z.ZodString>;
544
603
  slot: z.ZodNumber;
604
+ coordinatorConfigurationHash: z.ZodOptional<z.ZodString>;
545
605
  contextId: z.ZodString;
546
606
  outcomeSeq: z.ZodNumber;
547
607
  signalInvocationId: z.ZodString;
@@ -553,6 +613,7 @@ export declare const runtimeContract: {
553
613
  scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
554
614
  signalDependencyIds: z.ZodArray<z.ZodString>;
555
615
  slot: z.ZodNumber;
616
+ coordinatorConfigurationHash: z.ZodOptional<z.ZodString>;
556
617
  contextId: z.ZodString;
557
618
  outcomeSeq: z.ZodNumber;
558
619
  signalInvocationId: z.ZodString;
@@ -563,6 +624,7 @@ export declare const runtimeContract: {
563
624
  scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
564
625
  signalDependencyIds: z.ZodArray<z.ZodString>;
565
626
  slot: z.ZodNumber;
627
+ coordinatorConfigurationHash: z.ZodOptional<z.ZodString>;
566
628
  contextId: z.ZodString;
567
629
  outcomeSeq: z.ZodNumber;
568
630
  signalInvocationId: z.ZodString;
@@ -577,6 +639,7 @@ export declare const runtimeContract: {
577
639
  scopePath: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
578
640
  signalDependencyIds: z.ZodArray<z.ZodString>;
579
641
  slot: z.ZodNumber;
642
+ coordinatorConfigurationHash: z.ZodOptional<z.ZodString>;
580
643
  contextId: z.ZodString;
581
644
  outcomeSeq: z.ZodNumber;
582
645
  signalInvocationId: z.ZodString;
package/dist/runtime.js CHANGED
@@ -120,6 +120,10 @@ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
120
120
  slot: z.number().int().nonnegative(),
121
121
  });
122
122
  const COORDINATION_PRIMARY_POSITION_SCHEMA = z.enum(["first", "last"]);
123
+ const COORDINATION_DURATION_SCHEMA = z.union([
124
+ z.string().min(1),
125
+ z.number().nonnegative(),
126
+ ]);
123
127
  const CORRELATION_STREAM_NAMES_SCHEMA = z
124
128
  .string()
125
129
  .min(1)
@@ -162,13 +166,62 @@ const COLLECTION_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
162
166
  primaryPosition: COORDINATION_PRIMARY_POSITION_SCHEMA,
163
167
  ttl: z.union([z.string().min(1), z.number().nonnegative()]).optional(),
164
168
  });
165
- const WINDOW_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
166
- duration: z.union([z.string().min(1), z.number().nonnegative()]),
169
+ const FUNNEL_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
167
170
  key: encodableSchema,
171
+ maxBurstDuration: COORDINATION_DURATION_SCHEMA.optional(),
172
+ minGap: COORDINATION_DURATION_SCHEMA.optional(),
173
+ minQuietPeriod: COORDINATION_DURATION_SCHEMA.optional(),
168
174
  outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
169
- policy: z.literal("window"),
175
+ policy: z.literal("funnel"),
170
176
  primaryPosition: COORDINATION_PRIMARY_POSITION_SCHEMA,
171
- ttl: z.union([z.string().min(1), z.number().nonnegative()]).optional(),
177
+ selection: z.enum(["all", "first", "last"]),
178
+ triggerAt: z.enum(["start", "end", "both"]),
179
+ ttl: COORDINATION_DURATION_SCHEMA.optional(),
180
+ }).superRefine((offer, context) => {
181
+ if (offer.triggerAt === "end" &&
182
+ offer.minGap !== undefined &&
183
+ offer.minQuietPeriod === undefined &&
184
+ offer.maxBurstDuration === undefined) {
185
+ context.addIssue({
186
+ code: "custom",
187
+ message: "A trailing funnel with minGap also requires minQuietPeriod or maxBurstDuration.",
188
+ path: ["minGap"],
189
+ });
190
+ }
191
+ if (offer.selection !== "all" && offer.selection !== offer.primaryPosition) {
192
+ context.addIssue({
193
+ code: "custom",
194
+ message: "A selecting funnel must continue from its selected occurrence.",
195
+ path: ["primaryPosition"],
196
+ });
197
+ }
198
+ if (offer.triggerAt === "start" && offer.selection !== "first") {
199
+ context.addIssue({
200
+ code: "custom",
201
+ message: "A start-only funnel can only select its first occurrence.",
202
+ path: ["selection"],
203
+ });
204
+ }
205
+ });
206
+ const RACE_OFFER_BASE_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
207
+ inputOrigins: z.string().array().array().min(1),
208
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
209
+ policy: z.literal("race"),
210
+ scopeOrigins: z.string().array().default([]),
211
+ selectedIndex: z.number().int().nonnegative(),
212
+ });
213
+ const RACE_OFFER_SCHEMA = z
214
+ .union([
215
+ RACE_OFFER_BASE_SCHEMA.extend({ status: z.literal("closed") }),
216
+ RACE_OFFER_BASE_SCHEMA.extend({
217
+ failure: SIGNAL_FAILURE_SCHEMA,
218
+ status: z.literal("failed"),
219
+ }),
220
+ RACE_OFFER_BASE_SCHEMA.extend({ status: z.literal("succeeded") }),
221
+ ])
222
+ .refine((offer) => offer.selectedIndex < offer.inputOrigins.length, {
223
+ message: "Race input must identify a declared input.",
224
+ path: ["selectedIndex"],
172
225
  });
173
226
  const SIGNAL_INVOCATION_SCHEMA = z.union([
174
227
  SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
@@ -186,6 +239,7 @@ const SIGNAL_INVOCATION_SCHEMA = z.union([
186
239
  }),
187
240
  ]);
188
241
  const SIGNAL_BATCH_OUTCOME_BASE_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
242
+ coordinatorConfigurationHash: z.string().optional(),
189
243
  contextId: z.string(),
190
244
  outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
191
245
  signalInvocationId: z.string(),
@@ -428,6 +482,29 @@ const RUNTIME_GENERATION_INPUT_SCHEMA = z.union([
428
482
  output: RUNTIME_GENERATION_OUTPUT_SCHEMA,
429
483
  }),
430
484
  ]);
485
+ /**
486
+ * Hashes one coordinator definition exactly as the runtime stores it.
487
+ *
488
+ * @param definition - Structural coordinator definition.
489
+ * @param primaryPosition - Optional inherited-parent precedence.
490
+ */
491
+ export async function hashSignalCoordinatorConfiguration(definition, primaryPosition) {
492
+ return await sha256Base64Url(JSON.stringify({
493
+ definitionHash: await sha256Base64Url(JSON.stringify(definition)),
494
+ primaryPosition: primaryPosition ?? null,
495
+ }));
496
+ }
497
+ /**
498
+ * Hashes UTF-8 text to an unpadded URL-safe base64 digest.
499
+ *
500
+ * @param value - Text to hash.
501
+ */
502
+ async function sha256Base64Url(value) {
503
+ return btoa(String.fromCharCode(...new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)))))
504
+ .replaceAll("+", "-")
505
+ .replaceAll("/", "_")
506
+ .replace(/=+$/, "");
507
+ }
431
508
  export const runtimeContract = {
432
509
  commit: oc
433
510
  .input(z.object({
@@ -436,7 +513,8 @@ export const runtimeContract = {
436
513
  .union([
437
514
  COLLECTION_OFFER_SCHEMA,
438
515
  CORRELATION_OFFER_SCHEMA,
439
- WINDOW_OFFER_SCHEMA,
516
+ FUNNEL_OFFER_SCHEMA,
517
+ RACE_OFFER_SCHEMA,
440
518
  ])
441
519
  .array()
442
520
  .default([]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automate.ax/api-contract",
3
- "version": "0.57.2",
3
+ "version": "0.57.4",
4
4
  "description": "Public oRPC contract for the Automate.ax API.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@ai-sdk/gateway": "^4.0.46",
31
- "@automate.ax/codec": "0.57.2",
31
+ "@automate.ax/codec": "0.57.4",
32
32
  "@orpc/contract": "1.15.0",
33
33
  "zod": "^4.3.6"
34
34
  },
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export {
21
21
  automationInvocationScheduleSchema,
22
22
  generationInputSchema,
23
23
  generationResultSchema,
24
+ hashSignalCoordinatorConfiguration,
24
25
  runtimeContract,
25
26
  type GenerationInput,
26
27
  type GenerationResult,
package/src/runtime.ts CHANGED
@@ -137,6 +137,10 @@ const SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA = z.object({
137
137
  })
138
138
 
139
139
  const COORDINATION_PRIMARY_POSITION_SCHEMA = z.enum(["first", "last"])
140
+ const COORDINATION_DURATION_SCHEMA = z.union([
141
+ z.string().min(1),
142
+ z.number().nonnegative(),
143
+ ])
140
144
  const CORRELATION_STREAM_NAMES_SCHEMA = z
141
145
  .string()
142
146
  .min(1)
@@ -184,15 +188,69 @@ const COLLECTION_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
184
188
  ttl: z.union([z.string().min(1), z.number().nonnegative()]).optional(),
185
189
  })
186
190
 
187
- const WINDOW_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
188
- duration: z.union([z.string().min(1), z.number().nonnegative()]),
191
+ const FUNNEL_OFFER_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
189
192
  key: encodableSchema,
193
+ maxBurstDuration: COORDINATION_DURATION_SCHEMA.optional(),
194
+ minGap: COORDINATION_DURATION_SCHEMA.optional(),
195
+ minQuietPeriod: COORDINATION_DURATION_SCHEMA.optional(),
190
196
  outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
191
- policy: z.literal("window"),
197
+ policy: z.literal("funnel"),
192
198
  primaryPosition: COORDINATION_PRIMARY_POSITION_SCHEMA,
193
- ttl: z.union([z.string().min(1), z.number().nonnegative()]).optional(),
199
+ selection: z.enum(["all", "first", "last"]),
200
+ triggerAt: z.enum(["start", "end", "both"]),
201
+ ttl: COORDINATION_DURATION_SCHEMA.optional(),
202
+ }).superRefine((offer, context) => {
203
+ if (
204
+ offer.triggerAt === "end" &&
205
+ offer.minGap !== undefined &&
206
+ offer.minQuietPeriod === undefined &&
207
+ offer.maxBurstDuration === undefined
208
+ ) {
209
+ context.addIssue({
210
+ code: "custom",
211
+ message:
212
+ "A trailing funnel with minGap also requires minQuietPeriod or maxBurstDuration.",
213
+ path: ["minGap"],
214
+ })
215
+ }
216
+ if (offer.selection !== "all" && offer.selection !== offer.primaryPosition) {
217
+ context.addIssue({
218
+ code: "custom",
219
+ message: "A selecting funnel must continue from its selected occurrence.",
220
+ path: ["primaryPosition"],
221
+ })
222
+ }
223
+ if (offer.triggerAt === "start" && offer.selection !== "first") {
224
+ context.addIssue({
225
+ code: "custom",
226
+ message: "A start-only funnel can only select its first occurrence.",
227
+ path: ["selection"],
228
+ })
229
+ }
230
+ })
231
+
232
+ const RACE_OFFER_BASE_SCHEMA = SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
233
+ inputOrigins: z.string().array().array().min(1),
234
+ outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
235
+ policy: z.literal("race"),
236
+ scopeOrigins: z.string().array().default([]),
237
+ selectedIndex: z.number().int().nonnegative(),
194
238
  })
195
239
 
240
+ const RACE_OFFER_SCHEMA = z
241
+ .union([
242
+ RACE_OFFER_BASE_SCHEMA.extend({ status: z.literal("closed") }),
243
+ RACE_OFFER_BASE_SCHEMA.extend({
244
+ failure: SIGNAL_FAILURE_SCHEMA,
245
+ status: z.literal("failed"),
246
+ }),
247
+ RACE_OFFER_BASE_SCHEMA.extend({ status: z.literal("succeeded") }),
248
+ ])
249
+ .refine((offer) => offer.selectedIndex < offer.inputOrigins.length, {
250
+ message: "Race input must identify a declared input.",
251
+ path: ["selectedIndex"],
252
+ })
253
+
196
254
  const SIGNAL_INVOCATION_SCHEMA = z.union([
197
255
  SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
198
256
  outcomeSeq: OUTCOME_SEQUENCE_SCHEMA.optional(),
@@ -211,6 +269,7 @@ const SIGNAL_INVOCATION_SCHEMA = z.union([
211
269
 
212
270
  const SIGNAL_BATCH_OUTCOME_BASE_SCHEMA =
213
271
  SIGNAL_INVOCATION_DEPENDENCIES_SCHEMA.extend({
272
+ coordinatorConfigurationHash: z.string().optional(),
214
273
  contextId: z.string(),
215
274
  outcomeSeq: OUTCOME_SEQUENCE_SCHEMA,
216
275
  signalInvocationId: z.string(),
@@ -484,6 +543,42 @@ export type RuntimeGenerationInput = z.output<
484
543
  typeof RUNTIME_GENERATION_INPUT_SCHEMA
485
544
  >
486
545
 
546
+ /**
547
+ * Hashes one coordinator definition exactly as the runtime stores it.
548
+ *
549
+ * @param definition - Structural coordinator definition.
550
+ * @param primaryPosition - Optional inherited-parent precedence.
551
+ */
552
+ export async function hashSignalCoordinatorConfiguration(
553
+ definition: unknown,
554
+ primaryPosition?: "first" | "last",
555
+ ) {
556
+ return await sha256Base64Url(
557
+ JSON.stringify({
558
+ definitionHash: await sha256Base64Url(JSON.stringify(definition)),
559
+ primaryPosition: primaryPosition ?? null,
560
+ }),
561
+ )
562
+ }
563
+
564
+ /**
565
+ * Hashes UTF-8 text to an unpadded URL-safe base64 digest.
566
+ *
567
+ * @param value - Text to hash.
568
+ */
569
+ async function sha256Base64Url(value: string) {
570
+ return btoa(
571
+ String.fromCharCode(
572
+ ...new Uint8Array(
573
+ await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)),
574
+ ),
575
+ ),
576
+ )
577
+ .replaceAll("+", "-")
578
+ .replaceAll("/", "_")
579
+ .replace(/=+$/, "")
580
+ }
581
+
487
582
  export const runtimeContract = {
488
583
  commit: oc
489
584
  .input(
@@ -493,7 +588,8 @@ export const runtimeContract = {
493
588
  .union([
494
589
  COLLECTION_OFFER_SCHEMA,
495
590
  CORRELATION_OFFER_SCHEMA,
496
- WINDOW_OFFER_SCHEMA,
591
+ FUNNEL_OFFER_SCHEMA,
592
+ RACE_OFFER_SCHEMA,
497
593
  ])
498
594
  .array()
499
595
  .default([]),