@vertesia/workflow 0.62.0 → 0.64.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/lib/cjs/activities/advanced/createDocumentTypeFromInteractionRun.js +1 -1
- package/lib/cjs/activities/advanced/createDocumentTypeFromInteractionRun.js.map +1 -1
- package/lib/cjs/activities/advanced/createOrUpdateDocumentFromInteractionRun.js +4 -4
- package/lib/cjs/activities/advanced/createOrUpdateDocumentFromInteractionRun.js.map +1 -1
- package/lib/cjs/activities/advanced/updateDocumentFromInteractionRun.js +1 -1
- package/lib/cjs/activities/advanced/updateDocumentFromInteractionRun.js.map +1 -1
- package/lib/cjs/activities/createDocumentFromOther.js +4 -4
- package/lib/cjs/activities/createDocumentFromOther.js.map +1 -1
- package/lib/cjs/activities/executeInteraction.js +3 -3
- package/lib/cjs/activities/executeInteraction.js.map +1 -1
- package/lib/cjs/activities/extractDocumentText.js +2 -2
- package/lib/cjs/activities/extractDocumentText.js.map +1 -1
- package/lib/cjs/activities/generateEmbeddings.js +7 -7
- package/lib/cjs/activities/generateEmbeddings.js.map +1 -1
- package/lib/cjs/activities/media/processPdfWithTextract.js +4 -4
- package/lib/cjs/activities/media/processPdfWithTextract.js.map +1 -1
- package/lib/cjs/activities/media/transcribeMediaWithGladia.js +3 -3
- package/lib/cjs/activities/media/transcribeMediaWithGladia.js.map +1 -1
- package/lib/cjs/activities/notifyWebhook.js +1 -1
- package/lib/cjs/activities/notifyWebhook.js.map +1 -1
- package/lib/cjs/activities/renditions/generateImageRendition.js +4 -4
- package/lib/cjs/activities/renditions/generateImageRendition.js.map +1 -1
- package/lib/cjs/activities/renditions/generateVideoRendition.js +4 -4
- package/lib/cjs/activities/renditions/generateVideoRendition.js.map +1 -1
- package/lib/cjs/dsl/dsl-workflow.js +2 -7
- package/lib/cjs/dsl/dsl-workflow.js.map +1 -1
- package/lib/cjs/dsl/setup/ActivityContext.js +4 -4
- package/lib/cjs/dsl/setup/ActivityContext.js.map +1 -1
- package/lib/cjs/errors.js +47 -1
- package/lib/cjs/errors.js.map +1 -1
- package/lib/cjs/utils/blobs.js +3 -3
- package/lib/cjs/utils/blobs.js.map +1 -1
- package/lib/cjs/utils/client.js +3 -3
- package/lib/cjs/utils/client.js.map +1 -1
- package/lib/esm/activities/advanced/createDocumentTypeFromInteractionRun.js +2 -2
- package/lib/esm/activities/advanced/createDocumentTypeFromInteractionRun.js.map +1 -1
- package/lib/esm/activities/advanced/createOrUpdateDocumentFromInteractionRun.js +5 -5
- package/lib/esm/activities/advanced/createOrUpdateDocumentFromInteractionRun.js.map +1 -1
- package/lib/esm/activities/advanced/updateDocumentFromInteractionRun.js +2 -2
- package/lib/esm/activities/advanced/updateDocumentFromInteractionRun.js.map +1 -1
- package/lib/esm/activities/createDocumentFromOther.js +5 -5
- package/lib/esm/activities/createDocumentFromOther.js.map +1 -1
- package/lib/esm/activities/executeInteraction.js +4 -4
- package/lib/esm/activities/executeInteraction.js.map +1 -1
- package/lib/esm/activities/extractDocumentText.js +3 -3
- package/lib/esm/activities/extractDocumentText.js.map +1 -1
- package/lib/esm/activities/generateEmbeddings.js +8 -8
- package/lib/esm/activities/generateEmbeddings.js.map +1 -1
- package/lib/esm/activities/media/processPdfWithTextract.js +5 -5
- package/lib/esm/activities/media/processPdfWithTextract.js.map +1 -1
- package/lib/esm/activities/media/transcribeMediaWithGladia.js +4 -4
- package/lib/esm/activities/media/transcribeMediaWithGladia.js.map +1 -1
- package/lib/esm/activities/notifyWebhook.js +2 -2
- package/lib/esm/activities/notifyWebhook.js.map +1 -1
- package/lib/esm/activities/renditions/generateImageRendition.js +5 -5
- package/lib/esm/activities/renditions/generateImageRendition.js.map +1 -1
- package/lib/esm/activities/renditions/generateVideoRendition.js +5 -5
- package/lib/esm/activities/renditions/generateVideoRendition.js.map +1 -1
- package/lib/esm/dsl/dsl-workflow.js +3 -8
- package/lib/esm/dsl/dsl-workflow.js.map +1 -1
- package/lib/esm/dsl/setup/ActivityContext.js +5 -5
- package/lib/esm/dsl/setup/ActivityContext.js.map +1 -1
- package/lib/esm/errors.js +43 -0
- package/lib/esm/errors.js.map +1 -1
- package/lib/esm/utils/blobs.js +3 -3
- package/lib/esm/utils/blobs.js.map +1 -1
- package/lib/esm/utils/client.js +4 -4
- package/lib/esm/utils/client.js.map +1 -1
- package/lib/types/activities/advanced/createOrUpdateDocumentFromInteractionRun.d.ts.map +1 -1
- package/lib/types/activities/extractDocumentText.d.ts.map +1 -1
- package/lib/types/dsl/dsl-workflow.d.ts.map +1 -1
- package/lib/types/errors.d.ts +27 -0
- package/lib/types/errors.d.ts.map +1 -1
- package/lib/workflows-bundle.js +50 -9
- package/package.json +4 -4
- package/src/activities/advanced/createDocumentTypeFromInteractionRun.ts +2 -2
- package/src/activities/advanced/createOrUpdateDocumentFromInteractionRun.ts +6 -5
- package/src/activities/advanced/updateDocumentFromInteractionRun.ts +2 -2
- package/src/activities/createDocumentFromOther.ts +5 -5
- package/src/activities/executeInteraction.ts +4 -4
- package/src/activities/extractDocumentText.ts +3 -3
- package/src/activities/generateEmbeddings.ts +8 -8
- package/src/activities/media/processPdfWithTextract.ts +5 -5
- package/src/activities/media/transcribeMediaWithGladia.ts +4 -4
- package/src/activities/notifyWebhook.ts +2 -2
- package/src/activities/renditions/generateImageRendition.ts +5 -5
- package/src/activities/renditions/generateVideoRendition.ts +5 -5
- package/src/dsl/dsl-workflow.ts +4 -9
- package/src/dsl/setup/ActivityContext.ts +5 -5
- package/src/errors.ts +56 -0
- package/src/utils/blobs.ts +3 -3
- package/src/utils/client.ts +4 -4
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vertesia/workflow",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.64.0",
|
4
4
|
"type": "module",
|
5
5
|
"description": "Composable prompts workflow dsl",
|
6
6
|
"main": "./lib/esm/index.js",
|
@@ -49,10 +49,10 @@
|
|
49
49
|
"tmp-promise": "^3.0.3",
|
50
50
|
"yaml": "^2.6.0",
|
51
51
|
"mime": "^4.0.0",
|
52
|
-
"@vertesia/common": "0.62.0",
|
53
|
-
"@vertesia/client": "0.62.0",
|
54
52
|
"@llumiverse/common": "0.18.0",
|
55
|
-
"@vertesia/
|
53
|
+
"@vertesia/common": "0.64.0",
|
54
|
+
"@vertesia/client": "0.64.0",
|
55
|
+
"@vertesia/api-fetch-client": "0.64.0"
|
56
56
|
},
|
57
57
|
"ts_dual_module": {
|
58
58
|
"outDir": "lib",
|
@@ -2,7 +2,7 @@ import { CreateContentObjectTypePayload, DSLActivityExecutionPayload, DSLActivit
|
|
2
2
|
import { log } from "@temporalio/activity";
|
3
3
|
import { projectResult } from "../../dsl/projections.js";
|
4
4
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
5
|
-
import {
|
5
|
+
import { ActivityParamNotFoundError } from "../../errors.js";
|
6
6
|
|
7
7
|
|
8
8
|
export interface CreateDocumentTypeFromInteractionRunParams {
|
@@ -25,7 +25,7 @@ export async function createDocumentTypeFromInteractionRun(payload: DSLActivityE
|
|
25
25
|
const { params, client } = await setupActivity<CreateDocumentTypeFromInteractionRunParams>(payload);
|
26
26
|
|
27
27
|
if (!params.run) {
|
28
|
-
throw new
|
28
|
+
throw new ActivityParamNotFoundError("run", payload.activity);
|
29
29
|
}
|
30
30
|
|
31
31
|
const genTypeRes = params.run.result;
|
@@ -1,7 +1,8 @@
|
|
1
1
|
import { log } from "@temporalio/activity";
|
2
2
|
import { ContentObjectStatus, DSLActivityExecutionPayload, DSLActivitySpec } from "@vertesia/common";
|
3
3
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
4
|
-
import {
|
4
|
+
import { ActivityParamNotFoundError, DocumentNotFoundError } from "../../errors.js";
|
5
|
+
|
5
6
|
interface CreateOrUpdateObjectFromInteractionRunParams {
|
6
7
|
/**
|
7
8
|
* The execution run object to use. Required.
|
@@ -47,21 +48,21 @@ export async function createOrUpdateDocumentFromInteractionRun(payload: DSLActiv
|
|
47
48
|
const objectTypeName = params.object_type;
|
48
49
|
|
49
50
|
if (!runId) {
|
50
|
-
throw new
|
51
|
+
throw new ActivityParamNotFoundError("run_id", payload.activity);
|
51
52
|
}
|
52
53
|
if (!objectTypeName && !params.update_existing_id) {
|
53
|
-
throw new
|
54
|
+
throw new ActivityParamNotFoundError("object_type", payload.activity);
|
54
55
|
}
|
55
56
|
|
56
57
|
log.info("Creating document from interaction result", { runId, objectTypeName });
|
57
58
|
|
58
59
|
const run = await client.runs.retrieve(runId).catch((e) => {
|
59
|
-
throw new
|
60
|
+
throw new DocumentNotFoundError(`Error fetching run ${runId}: ${e.message}`);
|
60
61
|
});
|
61
62
|
|
62
63
|
const type = objectTypeName ?
|
63
64
|
await client.types.getTypeByName(objectTypeName).catch((e) => {
|
64
|
-
throw new
|
65
|
+
throw new DocumentNotFoundError(`Error fetching type ${objectTypeName}: ${e.message}`);
|
65
66
|
})
|
66
67
|
: undefined;
|
67
68
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { DSLActivityExecutionPayload, DSLActivitySpec, ExecutionRun } from "@vertesia/common";
|
2
2
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
3
|
-
import {
|
3
|
+
import { ActivityParamNotFoundError } from "../../errors.js";
|
4
4
|
|
5
5
|
|
6
6
|
export interface UpdateDocumentFromInteractionRunParams {
|
@@ -19,7 +19,7 @@ export async function updateDocumentFromInteractionRun(payload: DSLActivityExecu
|
|
19
19
|
const { params, client, objectId } = await setupActivity<UpdateDocumentFromInteractionRunParams>(payload);
|
20
20
|
|
21
21
|
if (!params.run) {
|
22
|
-
throw new
|
22
|
+
throw new ActivityParamNotFoundError("run", payload.activity);
|
23
23
|
}
|
24
24
|
|
25
25
|
const docProps = params.run.result;
|
@@ -4,7 +4,7 @@ import { DSLActivityExecutionPayload, DSLActivitySpec } from "@vertesia/common";
|
|
4
4
|
import fs from 'fs';
|
5
5
|
import { pdfExtractPages } from "../conversion/mutool.js";
|
6
6
|
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
7
|
-
import {
|
7
|
+
import { DocumentNotFoundError } from "../errors.js";
|
8
8
|
import { saveBlobToTempFile } from "../utils/blobs.js";
|
9
9
|
|
10
10
|
interface CreatePdfDocumentFromSourceParams {
|
@@ -41,23 +41,23 @@ export async function createPdfDocumentFromSource(payload: DSLActivityExecutionP
|
|
41
41
|
|
42
42
|
if (!inputObject) {
|
43
43
|
log.error(`Document ${objectId} not found`);
|
44
|
-
throw new
|
44
|
+
throw new DocumentNotFoundError(`Document ${objectId} not found`, [objectId]);
|
45
45
|
}
|
46
46
|
|
47
47
|
if (!inputObject.content?.source) {
|
48
48
|
log.error(`Document ${objectId} has no source`);
|
49
|
-
throw new
|
49
|
+
throw new DocumentNotFoundError(`Document ${objectId} has no source`, [objectId]);
|
50
50
|
}
|
51
51
|
|
52
52
|
if (!inputObject.content.type || (!inputObject.content.type?.startsWith('application/pdf'))) {
|
53
53
|
log.error(`Document ${objectId} is not an image`);
|
54
|
-
throw new
|
54
|
+
throw new DocumentNotFoundError(`Document ${objectId} is not an image or pdf: ${inputObject.content.type}`, [objectId]);
|
55
55
|
}
|
56
56
|
|
57
57
|
const targetType = await client.types.getTypeByName(params.target_object_type);
|
58
58
|
if (!targetType) {
|
59
59
|
log.error(`Type ${params.target_object_type} not found`);
|
60
|
-
throw new
|
60
|
+
throw new DocumentNotFoundError(`Type ${params.target_object_type} not found`);
|
61
61
|
}
|
62
62
|
|
63
63
|
const tmpFile = await saveBlobToTempFile(client, inputObject.content.source, ".pdf");
|
@@ -12,7 +12,7 @@ import {
|
|
12
12
|
} from "@vertesia/common";
|
13
13
|
import { projectResult } from "../dsl/projections.js";
|
14
14
|
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
15
|
-
import {
|
15
|
+
import { ActivityParamInvalidError, ActivityParamNotFoundError } from "../errors.js";
|
16
16
|
import { TruncateSpec, truncByMaxTokens } from "../utils/tokens.js";
|
17
17
|
|
18
18
|
//Example:
|
@@ -130,7 +130,7 @@ export async function executeInteraction(payload: DSLActivityExecutionPayload<Ex
|
|
130
130
|
|
131
131
|
if (!interactionName) {
|
132
132
|
log.error("Missing interactionName", { params });
|
133
|
-
throw new
|
133
|
+
throw new ActivityParamNotFoundError("interactionName", payload.activity);
|
134
134
|
}
|
135
135
|
|
136
136
|
if (params.truncate) {
|
@@ -157,10 +157,10 @@ export async function executeInteraction(payload: DSLActivityExecutionPayload<Ex
|
|
157
157
|
log.error("Failed to execute interaction", { error });
|
158
158
|
if (error.message.includes("Failed to validate merged prompt schema")) {
|
159
159
|
//issue with the input data, don't retry
|
160
|
-
throw new
|
160
|
+
throw new ActivityParamInvalidError("prompt_data", payload.activity, error.message);
|
161
161
|
} else if (error.message.includes("modelId: Path `modelId` is required")) {
|
162
162
|
//issue with the input data, don't retry
|
163
|
-
throw new
|
163
|
+
throw new ActivityParamInvalidError("model", payload.activity, error.message);
|
164
164
|
} else {
|
165
165
|
throw error;
|
166
166
|
}
|
@@ -5,14 +5,14 @@ import {
|
|
5
5
|
DSLActivityExecutionPayload,
|
6
6
|
DSLActivitySpec,
|
7
7
|
} from "@vertesia/common";
|
8
|
+
import { markdownWithMarkitdown } from "../conversion/markitdown.js";
|
8
9
|
import { mutoolPdfToText } from "../conversion/mutool.js";
|
9
10
|
import { markdownWithPandoc } from "../conversion/pandoc.js";
|
10
11
|
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
11
|
-
import {
|
12
|
+
import { DocumentNotFoundError } from "../errors.js";
|
12
13
|
import { TextExtractionResult, TextExtractionStatus } from "../result-types.js";
|
13
14
|
import { fetchBlobAsBuffer, md5 } from "../utils/blobs.js";
|
14
15
|
import { countTokens } from "../utils/tokens.js";
|
15
|
-
import { markdownWithMarkitdown } from "../conversion/markitdown.js";
|
16
16
|
|
17
17
|
//@ts-ignore
|
18
18
|
const JSON: DSLActivitySpec = {
|
@@ -39,7 +39,7 @@ export async function extractDocumentText(
|
|
39
39
|
const doc = r[0] as ContentObject;
|
40
40
|
if (!doc) {
|
41
41
|
log.error(`Document ${objectId} not found`);
|
42
|
-
throw new
|
42
|
+
throw new DocumentNotFoundError(`Document ${objectId} not found`, payload.objectIds);
|
43
43
|
}
|
44
44
|
|
45
45
|
log.info(`Extracting text for object ${doc.id}`);
|
@@ -10,7 +10,7 @@ import {
|
|
10
10
|
SupportedEmbeddingTypes,
|
11
11
|
} from "@vertesia/common";
|
12
12
|
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
13
|
-
import {
|
13
|
+
import { DocumentNotFoundError } from "../errors.js";
|
14
14
|
import { fetchBlobAsBase64, md5 } from "../utils/blobs.js";
|
15
15
|
import { DocPart, getContentParts } from "../utils/chunks.js";
|
16
16
|
import { countTokens } from "../utils/tokens.js";
|
@@ -59,16 +59,16 @@ export async function generateEmbeddings(
|
|
59
59
|
const projectData = await fetchProject();
|
60
60
|
const config = projectData?.configuration.embeddings[type];
|
61
61
|
if (!projectData) {
|
62
|
-
throw new
|
62
|
+
throw new DocumentNotFoundError("Project not found", [payload.project_id]);
|
63
63
|
}
|
64
64
|
if (!config) {
|
65
|
-
throw new
|
65
|
+
throw new DocumentNotFoundError("Embeddings configuration not found", [
|
66
66
|
objectId,
|
67
67
|
]);
|
68
68
|
}
|
69
69
|
|
70
70
|
if (!projectData) {
|
71
|
-
throw new
|
71
|
+
throw new DocumentNotFoundError("Project not found", [payload.project_id]);
|
72
72
|
}
|
73
73
|
|
74
74
|
if (!projectData?.configuration.embeddings[type]?.enabled) {
|
@@ -100,11 +100,11 @@ export async function generateEmbeddings(
|
|
100
100
|
);
|
101
101
|
|
102
102
|
if (!document) {
|
103
|
-
throw new
|
103
|
+
throw new DocumentNotFoundError("Document not found", [objectId]);
|
104
104
|
}
|
105
105
|
|
106
106
|
if (!document.content) {
|
107
|
-
throw new
|
107
|
+
throw new DocumentNotFoundError("Document content not found", [objectId]);
|
108
108
|
}
|
109
109
|
|
110
110
|
let res;
|
@@ -413,12 +413,12 @@ async function generateImageEmbeddings({
|
|
413
413
|
!resRnd.renditions ||
|
414
414
|
!resRnd.renditions.length
|
415
415
|
) {
|
416
|
-
throw new
|
416
|
+
throw new DocumentNotFoundError("Rendition retrieval failed", [document.id]);
|
417
417
|
}
|
418
418
|
|
419
419
|
const renditions = resRnd.renditions;
|
420
420
|
if (!renditions?.length) {
|
421
|
-
throw new
|
421
|
+
throw new DocumentNotFoundError("No source found in rendition", [
|
422
422
|
document.id,
|
423
423
|
]);
|
424
424
|
}
|
@@ -16,7 +16,7 @@ import type { AwsCredentialIdentityProvider } from "@smithy/types";
|
|
16
16
|
import { log } from "@temporalio/activity";
|
17
17
|
import { TextractProcessor } from "../../conversion/TextractProcessor.js";
|
18
18
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
19
|
-
import {
|
19
|
+
import { DocumentNotFoundError } from "../../errors.js";
|
20
20
|
import { TextExtractionResult, TextExtractionStatus } from "../../result-types.js";
|
21
21
|
import { fetchBlobAsBuffer, md5 } from "../../utils/blobs.js";
|
22
22
|
import { countTokens } from "../../utils/tokens.js";
|
@@ -49,13 +49,13 @@ export async function convertPdfToStructuredText(payload: DSLActivityExecutionPa
|
|
49
49
|
}
|
50
50
|
|
51
51
|
if (!object.content?.source) {
|
52
|
-
throw new
|
52
|
+
throw new DocumentNotFoundError(`No source found for object ${objectId}`);
|
53
53
|
}
|
54
54
|
|
55
55
|
const pdfUrl = await client.store.objects.getContentSource(objectId).then(res => res.source);
|
56
56
|
|
57
57
|
if (!pdfUrl) {
|
58
|
-
throw new
|
58
|
+
throw new DocumentNotFoundError(`Error fetching source ${object.content.source}`);
|
59
59
|
}
|
60
60
|
|
61
61
|
const project = await client.getProject();
|
@@ -123,10 +123,10 @@ export async function getS3AWSCredentials(awsConfig: AwsConfiguration, composabl
|
|
123
123
|
|
124
124
|
// fetch s3 role ARN
|
125
125
|
if (!awsConfig || !awsConfig.enabled) {
|
126
|
-
throw new
|
126
|
+
throw new DocumentNotFoundError("AWS integration is not enabled for this project");
|
127
127
|
}
|
128
128
|
if (!awsConfig.s3_role_arn) {
|
129
|
-
throw new
|
129
|
+
throw new DocumentNotFoundError("S3 Role ARN is not defined in AWS project integration");
|
130
130
|
}
|
131
131
|
|
132
132
|
log.info("Getting AWS credentials for Textract", { projectId, composableAuthToken, roleArn: awsConfig.s3_role_arn });
|
@@ -2,7 +2,7 @@ import { DSLActivityExecutionPayload, DSLActivitySpec, GladiaConfiguration, Supp
|
|
2
2
|
import { activityInfo, CompleteAsyncError, log } from "@temporalio/activity";
|
3
3
|
import { FetchClient } from "@vertesia/api-fetch-client";
|
4
4
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
5
|
-
import {
|
5
|
+
import { DocumentNotFoundError } from "../../errors.js";
|
6
6
|
import { TextExtractionResult, TextExtractionStatus } from "../../index.js";
|
7
7
|
|
8
8
|
|
@@ -27,7 +27,7 @@ export async function transcribeMedia(payload: DSLActivityExecutionPayload<Trans
|
|
27
27
|
|
28
28
|
const gladiaConfig = await client.projects.integrations.retrieve(payload.project_id, SupportedIntegrations.gladia) as GladiaConfiguration | undefined;
|
29
29
|
if (!gladiaConfig || !gladiaConfig.enabled) {
|
30
|
-
throw new
|
30
|
+
throw new DocumentNotFoundError("Gladia integration not enabled");
|
31
31
|
}
|
32
32
|
|
33
33
|
const object = await client.objects.retrieve(objectId, "+text");
|
@@ -39,13 +39,13 @@ export async function transcribeMedia(payload: DSLActivityExecutionPayload<Trans
|
|
39
39
|
}
|
40
40
|
|
41
41
|
if (!object.content?.source) {
|
42
|
-
throw new
|
42
|
+
throw new DocumentNotFoundError(`No source found for object ${objectId}`);
|
43
43
|
}
|
44
44
|
|
45
45
|
const mediaUrl = await client.store.objects.getContentSource(objectId).then(res => res.source);
|
46
46
|
|
47
47
|
if (!mediaUrl) {
|
48
|
-
throw new
|
48
|
+
throw new DocumentNotFoundError(`Error fetching source ${object.content.source}`);
|
49
49
|
}
|
50
50
|
|
51
51
|
const taskToken = Buffer.from(activityInfo().taskToken).toString('base64url');
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { log } from "@temporalio/activity";
|
2
2
|
import { DSLActivityExecutionPayload, DSLActivitySpec } from "@vertesia/common";
|
3
3
|
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
4
|
-
import {
|
4
|
+
import { WorkflowParamNotFoundError } from "../errors.js";
|
5
5
|
|
6
6
|
export interface NotifyWebhookParams {
|
7
7
|
target_url: string; //URL to send the notification to
|
@@ -21,7 +21,7 @@ export async function notifyWebhook(payload: DSLActivityExecutionPayload<NotifyW
|
|
21
21
|
const { params } = await setupActivity<NotifyWebhookParams>(payload);
|
22
22
|
const { target_url, method, payload: requestPayload, headers } = params
|
23
23
|
|
24
|
-
if (!target_url) throw new
|
24
|
+
if (!target_url) throw new WorkflowParamNotFoundError('target_url');
|
25
25
|
|
26
26
|
const body = method === 'POST' ? JSON.stringify({
|
27
27
|
...requestPayload,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { log } from "@temporalio/activity";
|
2
2
|
import { DSLActivityExecutionPayload, DSLActivitySpec } from "@vertesia/common";
|
3
3
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
4
|
-
import {
|
4
|
+
import { DocumentNotFoundError, WorkflowParamNotFoundError } from "../../errors.js";
|
5
5
|
import { saveBlobToTempFile } from "../../utils/blobs.js";
|
6
6
|
import {
|
7
7
|
ImageRenditionParams,
|
@@ -39,19 +39,19 @@ export async function generateImageRendition(
|
|
39
39
|
const inputObject = await client.objects.retrieve(objectId).catch((err) => {
|
40
40
|
log.error(`Failed to retrieve document ${objectId}`, { err });
|
41
41
|
if (err.message.includes("not found")) {
|
42
|
-
throw new
|
42
|
+
throw new DocumentNotFoundError(`Document ${objectId} not found`, [objectId]);
|
43
43
|
}
|
44
44
|
throw err;
|
45
45
|
});
|
46
46
|
|
47
47
|
if (!params.format) {
|
48
48
|
log.error(`Format not found`);
|
49
|
-
throw new
|
49
|
+
throw new WorkflowParamNotFoundError(`format`);
|
50
50
|
}
|
51
51
|
|
52
52
|
if (!inputObject.content?.source) {
|
53
53
|
log.error(`Document ${objectId} has no source`);
|
54
|
-
throw new
|
54
|
+
throw new DocumentNotFoundError(`Document ${objectId} has no source`, [objectId]);
|
55
55
|
}
|
56
56
|
|
57
57
|
if (
|
@@ -61,7 +61,7 @@ export async function generateImageRendition(
|
|
61
61
|
log.error(
|
62
62
|
`Document ${objectId} is not an image or a video: ${inputObject.content.type}`,
|
63
63
|
);
|
64
|
-
throw new
|
64
|
+
throw new DocumentNotFoundError(
|
65
65
|
`Document ${objectId} is not an image or a video: ${inputObject.content.type}`,
|
66
66
|
[objectId],
|
67
67
|
);
|
@@ -6,7 +6,7 @@ import os from "os";
|
|
6
6
|
import path from "path";
|
7
7
|
import { promisify } from "util";
|
8
8
|
import { setupActivity } from "../../dsl/setup/ActivityContext.js";
|
9
|
-
import {
|
9
|
+
import { DocumentNotFoundError, WorkflowParamNotFoundError } from "../../errors.js";
|
10
10
|
import { saveBlobToTempFile } from "../../utils/blobs.js";
|
11
11
|
import {
|
12
12
|
ImageRenditionParams,
|
@@ -136,7 +136,7 @@ export async function generateVideoRendition(
|
|
136
136
|
const inputObject = await client.objects.retrieve(objectId).catch((err) => {
|
137
137
|
log.error(`Failed to retrieve document ${objectId}`, { err });
|
138
138
|
if (err.message.includes("not found")) {
|
139
|
-
throw new
|
139
|
+
throw new DocumentNotFoundError(`Document ${objectId} not found`, [
|
140
140
|
objectId,
|
141
141
|
]);
|
142
142
|
}
|
@@ -145,12 +145,12 @@ export async function generateVideoRendition(
|
|
145
145
|
|
146
146
|
if (!params.format) {
|
147
147
|
log.error(`Format not found`);
|
148
|
-
throw new
|
148
|
+
throw new WorkflowParamNotFoundError(`format`);
|
149
149
|
}
|
150
150
|
|
151
151
|
if (!inputObject.content?.source) {
|
152
152
|
log.error(`Document ${objectId} has no source`);
|
153
|
-
throw new
|
153
|
+
throw new DocumentNotFoundError(`Document ${objectId} has no source`, [
|
154
154
|
objectId,
|
155
155
|
]);
|
156
156
|
}
|
@@ -162,7 +162,7 @@ export async function generateVideoRendition(
|
|
162
162
|
log.error(
|
163
163
|
`Document ${objectId} is not a video: ${inputObject.content.type}`,
|
164
164
|
);
|
165
|
-
throw new
|
165
|
+
throw new DocumentNotFoundError(
|
166
166
|
`Document ${objectId} is not a video: ${inputObject.content.type}`,
|
167
167
|
[objectId],
|
168
168
|
);
|
package/src/dsl/dsl-workflow.ts
CHANGED
@@ -21,10 +21,10 @@ import {
|
|
21
21
|
WorkflowExecutionPayload
|
22
22
|
} from "@vertesia/common";
|
23
23
|
import ms, { StringValue } from 'ms';
|
24
|
-
import { ActivityParamInvalid, ActivityParamNotFound, NoDocumentFound, WorkflowParamNotFound } from "../errors.js";
|
25
|
-
import { Vars } from "./vars.js";
|
26
24
|
import { HandleDslErrorParams } from "../activities/handleError.js";
|
27
25
|
import * as activities from "../activities/index.js";
|
26
|
+
import { WF_NON_RETRYABLE_ERRORS, WorkflowParamNotFoundError } from "../errors.js";
|
27
|
+
import { Vars } from "./vars.js";
|
28
28
|
|
29
29
|
interface BaseActivityPayload extends WorkflowExecutionPayload {
|
30
30
|
workflow_name: string;
|
@@ -43,7 +43,7 @@ export async function dslWorkflow(payload: DSLWorkflowExecutionPayload) {
|
|
43
43
|
|
44
44
|
const definition = payload.workflow;
|
45
45
|
if (!definition) {
|
46
|
-
throw new
|
46
|
+
throw new WorkflowParamNotFoundError("workflow");
|
47
47
|
}
|
48
48
|
// the base payload will be used to create the activities payload
|
49
49
|
const basePayload: BaseActivityPayload = {
|
@@ -61,12 +61,7 @@ export async function dslWorkflow(payload: DSLWorkflowExecutionPayload) {
|
|
61
61
|
backoffCoefficient: 2,
|
62
62
|
maximumAttempts: 10,
|
63
63
|
maximumInterval: 100 * 30 * 1000, //ms
|
64
|
-
nonRetryableErrorTypes:
|
65
|
-
NoDocumentFound.name,
|
66
|
-
ActivityParamNotFound.name,
|
67
|
-
WorkflowParamNotFound.name,
|
68
|
-
ActivityParamInvalid.name,
|
69
|
-
],
|
64
|
+
nonRetryableErrorTypes: WF_NON_RETRYABLE_ERRORS,
|
70
65
|
},
|
71
66
|
};
|
72
67
|
log.debug("Global activity options", {
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
Project,
|
7
7
|
WorkflowExecutionPayload,
|
8
8
|
} from "@vertesia/common";
|
9
|
-
import {
|
9
|
+
import { DocumentNotFoundError, WorkflowParamNotFoundError } from "../../errors.js";
|
10
10
|
import { getProjectFromToken } from "../../utils/auth.js";
|
11
11
|
import { getVertesiaClient } from "../../utils/client.js";
|
12
12
|
import { Vars } from "../vars.js";
|
@@ -38,7 +38,7 @@ export class ActivityContext<ParamsT extends Record<string, any>> {
|
|
38
38
|
const objectId = this.payload.objectIds && this.payload.objectIds[0];
|
39
39
|
if (!objectId) {
|
40
40
|
log.error("No objectId found in payload");
|
41
|
-
throw new
|
41
|
+
throw new WorkflowParamNotFoundError(
|
42
42
|
"objectIds[0]",
|
43
43
|
(this.payload as WorkflowExecutionPayload as DSLWorkflowExecutionPayload).workflow,
|
44
44
|
);
|
@@ -54,7 +54,7 @@ export class ActivityContext<ParamsT extends Record<string, any>> {
|
|
54
54
|
const runId = activityInfo().workflowExecution.runId;
|
55
55
|
if (!runId) {
|
56
56
|
log.error("No runId found in activityInfo");
|
57
|
-
throw new
|
57
|
+
throw new WorkflowParamNotFoundError(
|
58
58
|
"runId",
|
59
59
|
(this.payload as WorkflowExecutionPayload as DSLWorkflowExecutionPayload).workflow,
|
60
60
|
);
|
@@ -66,7 +66,7 @@ export class ActivityContext<ParamsT extends Record<string, any>> {
|
|
66
66
|
const workflowId = activityInfo().workflowExecution.workflowId;
|
67
67
|
if (!workflowId) {
|
68
68
|
log.error("No workflowId found in activityInfo");
|
69
|
-
throw new
|
69
|
+
throw new WorkflowParamNotFoundError(
|
70
70
|
"workflowId",
|
71
71
|
(this.payload as WorkflowExecutionPayload as DSLWorkflowExecutionPayload).workflow,
|
72
72
|
);
|
@@ -127,7 +127,7 @@ export async function setupActivity<ParamsT extends Record<string, any>>(
|
|
127
127
|
vars.setValue(key, result);
|
128
128
|
}
|
129
129
|
} else if (fetchSpec.on_not_found === "throw") {
|
130
|
-
throw new
|
130
|
+
throw new DocumentNotFoundError("No documents found for: " + JSON.stringify(fetchSpec));
|
131
131
|
} else {
|
132
132
|
vars.setValue(key, null);
|
133
133
|
}
|
package/src/errors.ts
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
import { ApplicationFailure } from "@temporalio/workflow";
|
2
2
|
import { DSLActivitySpec, DSLWorkflowSpec } from "@vertesia/common";
|
3
3
|
|
4
|
+
/**
|
5
|
+
* @deprecated Use {@link DocumentNotFoundError} instead.
|
6
|
+
*/
|
4
7
|
export class NoDocumentFound extends Error {
|
5
8
|
constructor(
|
6
9
|
message: string,
|
@@ -22,6 +25,9 @@ export class DocumentNotFoundError extends ApplicationFailure {
|
|
22
25
|
}
|
23
26
|
}
|
24
27
|
|
28
|
+
/**
|
29
|
+
* @deprecated Use {@link ActivityParamNotFoundError} instead.
|
30
|
+
*/
|
25
31
|
export class ActivityParamNotFound extends Error {
|
26
32
|
constructor(
|
27
33
|
public paramName: string,
|
@@ -32,6 +38,22 @@ export class ActivityParamNotFound extends Error {
|
|
32
38
|
}
|
33
39
|
}
|
34
40
|
|
41
|
+
export class ActivityParamNotFoundError extends ApplicationFailure {
|
42
|
+
constructor(
|
43
|
+
public paramName: string,
|
44
|
+
public activity: DSLActivitySpec,
|
45
|
+
) {
|
46
|
+
super(
|
47
|
+
`Required parameter ${paramName} not found in activity ${activity.name}`,
|
48
|
+
"ActivityParamNotFoundError",
|
49
|
+
true, // non-retryable
|
50
|
+
);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @deprecated Use {@link ActivityParamInvalidError} instead.
|
56
|
+
*/
|
35
57
|
export class ActivityParamInvalid extends Error {
|
36
58
|
constructor(
|
37
59
|
public paramName: string,
|
@@ -43,6 +65,23 @@ export class ActivityParamInvalid extends Error {
|
|
43
65
|
}
|
44
66
|
}
|
45
67
|
|
68
|
+
export class ActivityParamInvalidError extends ApplicationFailure {
|
69
|
+
constructor(
|
70
|
+
public paramName: string,
|
71
|
+
public activity: DSLActivitySpec,
|
72
|
+
reason?: string,
|
73
|
+
) {
|
74
|
+
super(
|
75
|
+
`${paramName} in activity ${activity.name} is invalid${reason ? ` ${reason}` : ""}`,
|
76
|
+
"ActivityParamInvalidError",
|
77
|
+
true, // non-retryable
|
78
|
+
);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* @deprecated Use {@link WorkflowParamNotFoundError} instead.
|
84
|
+
*/
|
46
85
|
export class WorkflowParamNotFound extends Error {
|
47
86
|
constructor(
|
48
87
|
public paramName: string,
|
@@ -53,9 +92,26 @@ export class WorkflowParamNotFound extends Error {
|
|
53
92
|
}
|
54
93
|
}
|
55
94
|
|
95
|
+
export class WorkflowParamNotFoundError extends ApplicationFailure {
|
96
|
+
constructor(
|
97
|
+
public paramName: string,
|
98
|
+
public workflow?: DSLWorkflowSpec,
|
99
|
+
) {
|
100
|
+
super(
|
101
|
+
`Required parameter ${paramName} not found in workflow ${workflow?.name}`,
|
102
|
+
"WorkflowParamNotFoundError",
|
103
|
+
true, // non-retryable
|
104
|
+
);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
56
108
|
export const WF_NON_RETRYABLE_ERRORS = [
|
57
109
|
"NoDocumentFound",
|
58
110
|
"DocumentNotFoundError",
|
111
|
+
"ActivityParamInvalid",
|
112
|
+
"ActivityParamInvalidError",
|
59
113
|
"ActivityParamNotFound",
|
114
|
+
"ActivityParamNotFoundError",
|
60
115
|
"WorkflowParamNotFound",
|
116
|
+
"WorkflowParamNotFoundError",
|
61
117
|
];
|
package/src/utils/blobs.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import { VertesiaClient } from "@vertesia/client";
|
2
2
|
import crypto from "crypto";
|
3
3
|
import { createWriteStream } from "fs";
|
4
|
-
import tmp from "tmp";
|
5
|
-
import { NoDocumentFound } from "../errors.js";
|
6
4
|
import { Readable } from "stream";
|
7
5
|
import { pipeline } from "stream/promises";
|
6
|
+
import tmp from "tmp";
|
7
|
+
import { DocumentNotFoundError } from "../errors.js";
|
8
8
|
|
9
9
|
tmp.setGracefulCleanup();
|
10
10
|
|
@@ -14,7 +14,7 @@ export async function fetchBlobAsStream(client: VertesiaClient, blobUri: string)
|
|
14
14
|
} catch (err: any) {
|
15
15
|
if (err.message.includes("not found")) {
|
16
16
|
//TODO improve error handling with a fetch fail error class in the client
|
17
|
-
throw new
|
17
|
+
throw new DocumentNotFoundError(`Failed to download blob ${blobUri}: ${err.message}`, []);
|
18
18
|
} else {
|
19
19
|
throw new Error(`Failed to download blob ${blobUri}: ${err.message}`);
|
20
20
|
}
|
package/src/utils/client.ts
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
import { VertesiaClient } from "@vertesia/client";
|
6
6
|
import { WorkflowExecutionBaseParams } from "@vertesia/common";
|
7
|
-
import {
|
7
|
+
import { WorkflowParamNotFoundError } from "../errors.js";
|
8
8
|
|
9
9
|
|
10
10
|
export function getVertesiaClient(payload: WorkflowExecutionBaseParams) {
|
@@ -13,15 +13,15 @@ export function getVertesiaClient(payload: WorkflowExecutionBaseParams) {
|
|
13
13
|
|
14
14
|
export function getVertesiaClientOptions(payload: WorkflowExecutionBaseParams) {
|
15
15
|
if (!payload.auth_token) {
|
16
|
-
throw new
|
16
|
+
throw new WorkflowParamNotFoundError("Authentication Token is missing from WorkflowExecutionPayload.authToken");
|
17
17
|
}
|
18
18
|
|
19
19
|
if (!payload.config?.studio_url) {
|
20
|
-
throw new
|
20
|
+
throw new WorkflowParamNotFoundError("Content Store URL is missing from WorkflowExecutionPayload.servers.storeUrl");
|
21
21
|
}
|
22
22
|
|
23
23
|
if (!payload.config?.store_url) {
|
24
|
-
throw new
|
24
|
+
throw new WorkflowParamNotFoundError("Content Store URL is missing from WorkflowExecutionPayload.servers.storeUrl");
|
25
25
|
}
|
26
26
|
|
27
27
|
return {
|