@vertesia/workflow 1.1.1-dev.20260505.160410Z → 1.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"executeInteraction.d.ts","sourceRoot":"","sources":["../../../src/activities/executeInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EACH,2BAA2B,EAC3B,eAAe,EAMlB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAiDpE,MAAM,WAAW,0BAA0B;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC;IAEpB,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B;;OAEG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,0BAA0B;IAExE,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe,CAAC,wBAAwB,CAAC;IACjF,IAAI,EAAE,oBAAoB,CAAC;CAC9B;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,2BAA2B,CAAC,wBAAwB,CAAC,gBAoHtG;AAED,wBAAsB,8BAA8B,CAChD,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,0BAA0B,EAClC,WAAW,EAAE,GAAG,EAChB,KAAK,CAAC,EAAE,OAAO,oFAuFlB"}
1
+ {"version":3,"file":"executeInteraction.d.ts","sourceRoot":"","sources":["../../../src/activities/executeInteraction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EACH,2BAA2B,EAC3B,eAAe,EAMlB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,YAAY,EAAoB,MAAM,oBAAoB,CAAC;AAiDpE,MAAM,WAAW,0BAA0B;IACvC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC;IAEpB,uDAAuD;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;IAE7B;;OAEG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAyB,SAAQ,0BAA0B;IAExE,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe,CAAC,wBAAwB,CAAC;IACjF,IAAI,EAAE,oBAAoB,CAAC;CAC9B;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,2BAA2B,CAAC,wBAAwB,CAAC,gBAqHtG;AAED,wBAAsB,8BAA8B,CAChD,MAAM,EAAE,cAAc,EACtB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,0BAA0B,EAClC,WAAW,EAAE,GAAG,EAChB,KAAK,CAAC,EAAE,OAAO,oFAuFlB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/workflow",
3
- "version": "1.1.1-dev.20260505.160410Z",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "Vertesia workflow DSL",
6
6
  "main": "./lib/esm/index.js",
@@ -44,10 +44,10 @@
44
44
  "tmp-promise": "^3.0.3",
45
45
  "yaml": "^2.6.0",
46
46
  "@llumiverse/common": "1.1.1-dev.20260505.151157Z",
47
- "@vertesia/api-fetch-client": "1.1.1-dev.20260505.160410Z",
48
- "@vertesia/common": "1.1.1-dev.20260505.160410Z",
49
- "@vertesia/client": "1.1.1-dev.20260505.160410Z",
50
- "@vertesia/memory": "1.1.1-dev.20260505.160410Z"
47
+ "@vertesia/api-fetch-client": "1.2.0",
48
+ "@vertesia/common": "1.2.0",
49
+ "@vertesia/client": "1.2.0",
50
+ "@vertesia/memory": "1.2.0"
51
51
  },
52
52
  "ts_dual_module": {
53
53
  "outDir": "lib",
@@ -0,0 +1,83 @@
1
+ import { ApplicationFailure } from '@temporalio/activity';
2
+ import { MockActivityEnvironment } from '@temporalio/testing';
3
+ import type { VertesiaClient } from '@vertesia/client';
4
+ import { ContentEventName, type DSLActivityExecutionPayload } from '@vertesia/common';
5
+ import type { ActivityContext } from '../dsl/setup/ActivityContext.js';
6
+ import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
7
+ import { executeInteraction, type ExecuteInteractionParams } from './executeInteraction.js';
8
+
9
+ vi.mock('../dsl/setup/ActivityContext.js', async (importOriginal) => {
10
+ const actual = await importOriginal<typeof import('../dsl/setup/ActivityContext.js')>();
11
+ return { ...actual, setupActivity: vi.fn() };
12
+ });
13
+
14
+ let testEnv: MockActivityEnvironment;
15
+
16
+ beforeAll(() => {
17
+ testEnv = new MockActivityEnvironment();
18
+ });
19
+
20
+ beforeEach(() => {
21
+ vi.clearAllMocks();
22
+ });
23
+
24
+ const createPayload = (): DSLActivityExecutionPayload<ExecuteInteractionParams> => ({
25
+ auth_token: 'mock-token',
26
+ account_id: 'test-account',
27
+ project_id: 'test-project',
28
+ params: {
29
+ interactionName: 'testInteraction',
30
+ prompt_data: {},
31
+ },
32
+ config: { studio_url: 'http://mock-studio', store_url: 'http://mock-store' },
33
+ workflow_name: 'test-workflow',
34
+ event: ContentEventName.create,
35
+ objectIds: ['test-object-id'],
36
+ input: { inputType: 'objectIds', objectIds: ['test-object-id'] },
37
+ vars: {},
38
+ activity: { name: 'executeInteraction', params: {} },
39
+ });
40
+
41
+ async function mockInteractionError(error: Error & { statusCode?: number; status?: number; code?: number }): Promise<void> {
42
+ const { setupActivity } = await import('../dsl/setup/ActivityContext.js');
43
+ const mockClient = {
44
+ interactions: {
45
+ executeByName: vi.fn().mockRejectedValue(error),
46
+ },
47
+ } as unknown as VertesiaClient;
48
+
49
+ vi.mocked(setupActivity).mockResolvedValue({
50
+ client: mockClient,
51
+ inputType: 'objectIds',
52
+ params: createPayload().params,
53
+ } as unknown as ActivityContext<ExecuteInteractionParams>);
54
+ }
55
+
56
+ describe('executeInteraction retryability', () => {
57
+ it('leaves 412 rendition-in-progress failures retryable', async () => {
58
+ await mockInteractionError(Object.assign(new Error('rendition in progress'), { statusCode: 412 }));
59
+
60
+ await expect(testEnv.run(executeInteraction, createPayload())).rejects.toMatchObject({
61
+ message: 'Interaction Execution failed testInteraction: rendition in progress',
62
+ });
63
+ });
64
+
65
+ it.each([
66
+ ['status', { status: 412 }],
67
+ ['code', { code: 412 }],
68
+ ])('leaves 412 failures retryable when reported as %s', async (_field, statusProps) => {
69
+ await mockInteractionError(Object.assign(new Error('precondition failed'), statusProps));
70
+
71
+ await expect(testEnv.run(executeInteraction, createPayload())).rejects.toMatchObject({
72
+ message: 'Interaction Execution failed testInteraction: precondition failed',
73
+ });
74
+ });
75
+
76
+ it('marks other 4xx failures as non-retryable', async () => {
77
+ await mockInteractionError(Object.assign(new Error('bad request'), { statusCode: 400 }));
78
+
79
+ await expect(testEnv.run(executeInteraction, createPayload())).rejects.toMatchObject({
80
+ nonRetryable: true,
81
+ } satisfies Partial<ApplicationFailure>);
82
+ });
83
+ });
@@ -203,7 +203,8 @@ export async function executeInteraction(payload: DSLActivityExecutionPayload<Ex
203
203
  if (error.statusCode === 429 && params.exit_on_resource_exhaustion) {
204
204
  throw new ResourceExhaustedError(error.statusCode, "Resource exhausted - rate limit exceeded");
205
205
  } else if (is4xxNonRetryable(error.status) || is4xxNonRetryable(error.statusCode) || is4xxNonRetryable(error.code) || error.retryable === false) {
206
- // 4xx HTTP errors (except 429 rate-limit) are permanent client errors (e.g. model not found, invalid request).
206
+ // 4xx HTTP errors (except retryable statuses) are permanent client errors
207
+ // (e.g. model not found, invalid request).
207
208
  // Errors explicitly marked as non-retryable (e.g. LlumiverseError) also fall here.
208
209
  // They will not be resolved by retrying.
209
210
  throw ApplicationFailure.create({
@@ -341,9 +342,10 @@ export async function executeInteractionFromActivity(
341
342
 
342
343
  /**
343
344
  * Returns true for 4xx status codes that indicate permanent client errors.
344
- * 429 (Too Many Requests) is excluded because it is retryable.
345
+ * 412 (Precondition Failed) and 429 (Too Many Requests) are excluded because
346
+ * they are retryable.
345
347
  */
346
348
  function is4xxNonRetryable(code: number | undefined): boolean {
347
349
  if (code === undefined || typeof code !== 'number') return false;
348
- return code >= 400 && code < 500 && code !== 429;
350
+ return code >= 400 && code < 500 && code !== 412 && code !== 429;
349
351
  }