@vertesia/workflow 0.52.0 → 0.55.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.
Files changed (155) hide show
  1. package/lib/cjs/activities/createDocumentFromOther.js +1 -1
  2. package/lib/cjs/activities/executeInteraction.js +29 -15
  3. package/lib/cjs/activities/executeInteraction.js.map +1 -1
  4. package/lib/cjs/activities/extractDocumentText.js +33 -30
  5. package/lib/cjs/activities/extractDocumentText.js.map +1 -1
  6. package/lib/cjs/activities/generateEmbeddings.js +1 -1
  7. package/lib/cjs/activities/generateEmbeddings.js.map +1 -1
  8. package/lib/cjs/activities/generateImageRendition.js +31 -11
  9. package/lib/cjs/activities/generateImageRendition.js.map +1 -1
  10. package/lib/cjs/activities/generateOrAssignContentType.js +25 -12
  11. package/lib/cjs/activities/generateOrAssignContentType.js.map +1 -1
  12. package/lib/cjs/activities/getObjectFromStore.js +1 -1
  13. package/lib/cjs/activities/handleError.js +22 -0
  14. package/lib/cjs/activities/handleError.js.map +1 -0
  15. package/lib/cjs/activities/index-dsl.js +3 -1
  16. package/lib/cjs/activities/index-dsl.js.map +1 -1
  17. package/lib/cjs/activities/index.js +0 -1
  18. package/lib/cjs/activities/index.js.map +1 -1
  19. package/lib/cjs/activities/media/processPdfWithTextract.js +4 -4
  20. package/lib/cjs/activities/media/transcribeMediaWithGladia.js +1 -1
  21. package/lib/cjs/activities/media/transcribeMediaWithGladia.js.map +1 -1
  22. package/lib/cjs/activities/setDocumentStatus.js +1 -1
  23. package/lib/cjs/conversion/TextractProcessor.js +9 -9
  24. package/lib/cjs/conversion/image.js +6 -2
  25. package/lib/cjs/conversion/image.js.map +1 -1
  26. package/lib/cjs/conversion/markitdown.js +42 -0
  27. package/lib/cjs/conversion/markitdown.js.map +1 -0
  28. package/lib/cjs/conversion/mutool.js +1 -1
  29. package/lib/cjs/conversion/pandoc.js +9 -9
  30. package/lib/cjs/conversion/pandoc.js.map +1 -1
  31. package/lib/cjs/dsl/dsl-workflow.js +59 -11
  32. package/lib/cjs/dsl/dsl-workflow.js.map +1 -1
  33. package/lib/cjs/dsl/vars.js +6 -6
  34. package/lib/cjs/dsl/vars.js.map +1 -1
  35. package/lib/cjs/index.js +1 -1
  36. package/lib/cjs/iterative-generation/activities/extractToc.js +1 -1
  37. package/lib/cjs/iterative-generation/activities/extractToc.js.map +1 -1
  38. package/lib/cjs/iterative-generation/activities/generatePart.js +2 -2
  39. package/lib/cjs/iterative-generation/activities/generatePart.js.map +1 -1
  40. package/lib/cjs/iterative-generation/activities/generateToc.js +1 -1
  41. package/lib/cjs/iterative-generation/activities/generateToc.js.map +1 -1
  42. package/lib/cjs/iterative-generation/iterativeGenerationWorkflow.js +1 -1
  43. package/lib/cjs/iterative-generation/iterativeGenerationWorkflow.js.map +1 -1
  44. package/lib/cjs/iterative-generation/utils.js +4 -4
  45. package/lib/cjs/iterative-generation/utils.js.map +1 -1
  46. package/lib/esm/activities/createDocumentFromOther.js +1 -1
  47. package/lib/esm/activities/executeInteraction.js +31 -17
  48. package/lib/esm/activities/executeInteraction.js.map +1 -1
  49. package/lib/esm/activities/extractDocumentText.js +39 -36
  50. package/lib/esm/activities/extractDocumentText.js.map +1 -1
  51. package/lib/esm/activities/generateEmbeddings.js +1 -1
  52. package/lib/esm/activities/generateEmbeddings.js.map +1 -1
  53. package/lib/esm/activities/generateImageRendition.js +31 -11
  54. package/lib/esm/activities/generateImageRendition.js.map +1 -1
  55. package/lib/esm/activities/generateOrAssignContentType.js +25 -12
  56. package/lib/esm/activities/generateOrAssignContentType.js.map +1 -1
  57. package/lib/esm/activities/getObjectFromStore.js +1 -1
  58. package/lib/esm/activities/handleError.js +19 -0
  59. package/lib/esm/activities/handleError.js.map +1 -0
  60. package/lib/esm/activities/index-dsl.js +1 -0
  61. package/lib/esm/activities/index-dsl.js.map +1 -1
  62. package/lib/esm/activities/index.js +0 -1
  63. package/lib/esm/activities/index.js.map +1 -1
  64. package/lib/esm/activities/media/processPdfWithTextract.js +4 -4
  65. package/lib/esm/activities/media/transcribeMediaWithGladia.js +1 -1
  66. package/lib/esm/activities/media/transcribeMediaWithGladia.js.map +1 -1
  67. package/lib/esm/activities/setDocumentStatus.js +1 -1
  68. package/lib/esm/conversion/TextractProcessor.js +9 -9
  69. package/lib/esm/conversion/image.js +6 -2
  70. package/lib/esm/conversion/image.js.map +1 -1
  71. package/lib/esm/conversion/markitdown.js +36 -0
  72. package/lib/esm/conversion/markitdown.js.map +1 -0
  73. package/lib/esm/conversion/mutool.js +1 -1
  74. package/lib/esm/conversion/pandoc.js +11 -11
  75. package/lib/esm/conversion/pandoc.js.map +1 -1
  76. package/lib/esm/dsl/dsl-workflow.js +60 -12
  77. package/lib/esm/dsl/dsl-workflow.js.map +1 -1
  78. package/lib/esm/dsl/vars.js +6 -6
  79. package/lib/esm/dsl/vars.js.map +1 -1
  80. package/lib/esm/index.js +1 -1
  81. package/lib/esm/iterative-generation/activities/extractToc.js +1 -1
  82. package/lib/esm/iterative-generation/activities/extractToc.js.map +1 -1
  83. package/lib/esm/iterative-generation/activities/generatePart.js +2 -2
  84. package/lib/esm/iterative-generation/activities/generatePart.js.map +1 -1
  85. package/lib/esm/iterative-generation/activities/generateToc.js +1 -1
  86. package/lib/esm/iterative-generation/activities/generateToc.js.map +1 -1
  87. package/lib/esm/iterative-generation/iterativeGenerationWorkflow.js +1 -1
  88. package/lib/esm/iterative-generation/iterativeGenerationWorkflow.js.map +1 -1
  89. package/lib/esm/iterative-generation/utils.js +4 -4
  90. package/lib/esm/iterative-generation/utils.js.map +1 -1
  91. package/lib/types/activities/createDocumentFromOther.d.ts +1 -1
  92. package/lib/types/activities/executeInteraction.d.ts +4 -4
  93. package/lib/types/activities/executeInteraction.d.ts.map +1 -1
  94. package/lib/types/activities/extractDocumentText.d.ts +3 -3
  95. package/lib/types/activities/extractDocumentText.d.ts.map +1 -1
  96. package/lib/types/activities/generateImageRendition.d.ts +1 -1
  97. package/lib/types/activities/generateImageRendition.d.ts.map +1 -1
  98. package/lib/types/activities/generateOrAssignContentType.d.ts +1 -1
  99. package/lib/types/activities/generateOrAssignContentType.d.ts.map +1 -1
  100. package/lib/types/activities/getObjectFromStore.d.ts +1 -1
  101. package/lib/types/activities/handleError.d.ts +6 -0
  102. package/lib/types/activities/handleError.d.ts.map +1 -0
  103. package/lib/types/activities/index-dsl.d.ts +1 -0
  104. package/lib/types/activities/index-dsl.d.ts.map +1 -1
  105. package/lib/types/activities/index.d.ts +0 -1
  106. package/lib/types/activities/index.d.ts.map +1 -1
  107. package/lib/types/activities/setDocumentStatus.d.ts +1 -1
  108. package/lib/types/conversion/image.d.ts.map +1 -1
  109. package/lib/types/conversion/markitdown.d.ts +2 -0
  110. package/lib/types/conversion/markitdown.d.ts.map +1 -0
  111. package/lib/types/conversion/mutool.d.ts +1 -1
  112. package/lib/types/conversion/pandoc.d.ts +1 -1
  113. package/lib/types/conversion/pandoc.d.ts.map +1 -1
  114. package/lib/types/dsl/dsl-workflow.d.ts +1 -1
  115. package/lib/types/dsl/dsl-workflow.d.ts.map +1 -1
  116. package/lib/types/dsl/vars.d.ts +2 -2
  117. package/lib/types/index.d.ts +1 -1
  118. package/lib/types/iterative-generation/types.d.ts +3 -3
  119. package/lib/types/iterative-generation/types.d.ts.map +1 -1
  120. package/lib/workflows-bundle.js +396 -94
  121. package/package.json +5 -4
  122. package/src/activities/createDocumentFromOther.ts +1 -1
  123. package/src/activities/executeInteraction.ts +66 -39
  124. package/src/activities/extractDocumentText.ts +67 -51
  125. package/src/activities/generateEmbeddings.ts +1 -1
  126. package/src/activities/generateImageRendition.ts +35 -14
  127. package/src/activities/generateOrAssignContentType.ts +52 -26
  128. package/src/activities/getObjectFromStore.ts +1 -1
  129. package/src/activities/handleError.ts +25 -0
  130. package/src/activities/index-dsl.ts +1 -0
  131. package/src/activities/index.ts +0 -1
  132. package/src/activities/media/processPdfWithTextract.ts +4 -4
  133. package/src/activities/media/transcribeMediaWithGladia.ts +1 -1
  134. package/src/activities/setDocumentStatus.ts +1 -1
  135. package/src/conversion/TextractProcessor.ts +9 -9
  136. package/src/conversion/image.ts +8 -2
  137. package/src/conversion/markitdown.ts +41 -0
  138. package/src/conversion/mutool.ts +1 -1
  139. package/src/conversion/pandoc.test.ts +2 -2
  140. package/src/conversion/pandoc.ts +38 -42
  141. package/src/dsl/dsl-workflow.ts +80 -12
  142. package/src/dsl/validation.test.ts +2 -2
  143. package/src/dsl/vars.test.ts +1 -1
  144. package/src/dsl/vars.ts +6 -6
  145. package/src/dsl/workflow-exec-child.test.ts +14 -4
  146. package/src/dsl/workflow-fetch.test.ts +1 -1
  147. package/src/dsl/workflow-import.test.ts +1 -1
  148. package/src/dsl/workflow.test.ts +12 -2
  149. package/src/index.ts +1 -1
  150. package/src/iterative-generation/activities/extractToc.ts +1 -1
  151. package/src/iterative-generation/activities/generatePart.ts +2 -2
  152. package/src/iterative-generation/activities/generateToc.ts +1 -1
  153. package/src/iterative-generation/iterativeGenerationWorkflow.ts +1 -1
  154. package/src/iterative-generation/types.ts +4 -4
  155. package/src/iterative-generation/utils.ts +4 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/workflow",
3
- "version": "0.52.0",
3
+ "version": "0.55.0",
4
4
  "type": "module",
5
5
  "description": "Composable prompts workflow dsl",
6
6
  "main": "./lib/esm/index.js",
@@ -19,6 +19,7 @@
19
19
  "license": "Apache-2.0",
20
20
  "devDependencies": {
21
21
  "@smithy/types": "^3.7.2",
22
+ "@temporalio/proto": "^1.11.5",
22
23
  "@temporalio/testing": "^1.11.5",
23
24
  "@temporalio/worker": "^1.11.5",
24
25
  "@types/fluent-ffmpeg": "^2.1.27",
@@ -50,9 +51,9 @@
50
51
  "tmp": "^0.2.3",
51
52
  "tmp-promise": "^3.0.3",
52
53
  "yaml": "^2.6.0",
53
- "@vertesia/common": "0.52.0",
54
- "@vertesia/client": "0.53.0",
55
- "@llumiverse/core": "0.17.0"
54
+ "@llumiverse/core": "0.17.0",
55
+ "@vertesia/common": "0.55.0",
56
+ "@vertesia/client": "0.55.0"
56
57
  },
57
58
  "ts_dual_module": {
58
59
  "outDir": "lib",
@@ -24,7 +24,7 @@ export interface CreatePdfDocumentFromSource extends DSLActivitySpec<CreatePdfDo
24
24
 
25
25
 
26
26
  /**
27
- * Create a new PDF by extrracting pages from a source PDF
27
+ * Create a new PDF by extracting pages from a source PDF
28
28
  * @returns
29
29
  */
30
30
  export async function createPdfDocumentFromSource(payload: DSLActivityExecutionPayload<CreatePdfDocumentFromSourceParams>) {
@@ -1,16 +1,23 @@
1
1
  import { ModelOptions } from "@llumiverse/core";
2
2
  import { activityInfo, log } from "@temporalio/activity";
3
3
  import { VertesiaClient } from "@vertesia/client";
4
- import { DSLActivityExecutionPayload, DSLActivitySpec, ExecutionRun, ExecutionRunStatus, InteractionExecutionConfiguration, RunSearchPayload } from "@vertesia/common";
4
+ import {
5
+ DSLActivityExecutionPayload,
6
+ DSLActivitySpec,
7
+ ExecutionRun,
8
+ ExecutionRunStatus,
9
+ InteractionExecutionConfiguration,
10
+ RunSearchPayload,
11
+ } from "@vertesia/common";
5
12
  import { projectResult } from "../dsl/projections.js";
6
13
  import { setupActivity } from "../dsl/setup/ActivityContext.js";
7
- import { ActivityParamNotFound } from "../errors.js";
14
+ import { ActivityParamInvalid, ActivityParamNotFound } from "../errors.js";
8
15
  import { TruncateSpec, truncByMaxTokens } from "../utils/tokens.js";
9
16
 
10
17
  //Example:
11
18
  //@ts-ignore
12
19
  const JSON: DSLActivitySpec = {
13
- name: 'executeInteraction',
20
+ name: "executeInteraction",
14
21
  import: ["defaultModel", "guidlineId", "docTypeId"],
15
22
  params: {
16
23
  defaultModel: "${model}",
@@ -23,8 +30,8 @@ const JSON: DSLActivitySpec = {
23
30
  result_schema: "${docType.object_schema}",
24
31
  prompt_data: {
25
32
  documents: "${documents}",
26
- guidline: "${guidline.text}"
27
- }
33
+ guidline: "${guidline.text}",
34
+ },
28
35
  },
29
36
  fetch: {
30
37
  documents: {
@@ -41,7 +48,7 @@ const JSON: DSLActivitySpec = {
41
48
  id: "${guidlineId}",
42
49
  },
43
50
  select: "+text",
44
- on_not_found: "throw"
51
+ on_not_found: "throw",
45
52
  },
46
53
  docType: {
47
54
  type: "document_type",
@@ -50,19 +57,19 @@ const JSON: DSLActivitySpec = {
50
57
  id: "${docTypeId}",
51
58
  },
52
59
  select: "+object_schema",
53
- }
54
- }
55
- }
60
+ },
61
+ },
62
+ };
56
63
  export interface InteractionExecutionParams {
57
64
  /**
58
65
  * The environment to use. If not specified the project default environment will be used.
59
- * If the latter is not specified an exeption will be thrown.
66
+ * If the latter is not specified an exception will be thrown.
60
67
  */
61
68
  environment?: string;
62
69
  /**
63
70
  * The model to use. If not specified the project default model will be used.
64
71
  * If the latter is not specified the default model of the environment will be used.
65
- * If the latter is not specified an exeption will be thrown.
72
+ * If the latter is not specified an exception will be thrown.
66
73
  */
67
74
  model?: string;
68
75
 
@@ -90,7 +97,7 @@ export interface InteractionExecutionParams {
90
97
  /**
91
98
  * TODO: must be kept in sync with InteractionAsyncExecutionPayload form @vertesia/common
92
99
  * Also see the executeInteractionAsync endpoint on the server for how the client payload is sent to the workflow.
93
- * (interaction is translsted to interactionName)
100
+ * (interaction is translated to interactionName)
94
101
  */
95
102
  export interface ExecuteInteractionParams extends InteractionExecutionParams {
96
103
  //TODO rename to interaction as in InteractionAsyncExecutionPayload
@@ -106,13 +113,11 @@ export interface ExecuteInteractionParams extends InteractionExecutionParams {
106
113
  }
107
114
 
108
115
  export interface ExecuteInteraction extends DSLActivitySpec<ExecuteInteractionParams> {
109
- name: 'executeInteraction';
116
+ name: "executeInteraction";
110
117
  }
111
118
 
112
119
  export async function executeInteraction(payload: DSLActivityExecutionPayload<ExecuteInteractionParams>) {
113
- const {
114
- client, params
115
- } = await setupActivity<ExecuteInteractionParams>(payload);
120
+ const { client, params } = await setupActivity<ExecuteInteractionParams>(payload);
116
121
 
117
122
  const { interactionName, prompt_data, static_prompt_data: wf_prompt_data } = params;
118
123
  if (wf_prompt_data) {
@@ -131,17 +136,37 @@ export async function executeInteraction(payload: DSLActivityExecutionPayload<Ex
131
136
  }
132
137
  }
133
138
 
134
- const res = await executeInteractionFromActivity(client, interactionName, params, prompt_data, payload.debug_mode);
135
-
136
- return projectResult(payload, params, res, {
137
- runId: res.id,
138
- status: res.status,
139
- result: res.result,
140
- });
141
-
139
+ try {
140
+ const res = await executeInteractionFromActivity(
141
+ client,
142
+ interactionName,
143
+ params,
144
+ prompt_data,
145
+ payload.debug_mode,
146
+ );
147
+ return projectResult(payload, params, res, {
148
+ runId: res.id,
149
+ status: res.status,
150
+ result: res.result,
151
+ });
152
+ } catch (error: any) {
153
+ log.error("Failed to execute interaction", { error });
154
+ if (error.message.includes("Failed to validate merged prompt schema")) {
155
+ //issue with the input data, don't retry
156
+ throw new ActivityParamInvalid("prompt_data", payload.activity, error.message);
157
+ } else {
158
+ throw error;
159
+ }
160
+ }
142
161
  }
143
162
 
144
- export async function executeInteractionFromActivity(client: VertesiaClient, interactionName: string, params: InteractionExecutionParams, prompt_data: any, debug?: boolean) {
163
+ export async function executeInteractionFromActivity(
164
+ client: VertesiaClient,
165
+ interactionName: string,
166
+ params: InteractionExecutionParams,
167
+ prompt_data: any,
168
+ debug?: boolean,
169
+ ) {
145
170
  const userTags = params.tags;
146
171
  const info = activityInfo();
147
172
  const runId = info.workflowExecution.runId;
@@ -161,7 +186,7 @@ export async function executeInteractionFromActivity(client: VertesiaClient, int
161
186
  };
162
187
  const previousRun = await client.runs.search(payload).then((res) => {
163
188
  log.info("Search results", { results: res });
164
- return res ? res[0] ?? undefined : undefined
189
+ return res ? (res[0] ?? undefined) : undefined;
165
190
  });
166
191
 
167
192
  if (previousRun) {
@@ -178,26 +203,28 @@ export async function executeInteractionFromActivity(client: VertesiaClient, int
178
203
  environment: params.environment,
179
204
  model: params.model,
180
205
  model_options: params.model_options,
181
- }
206
+ };
182
207
  const data = {
183
208
  ...prompt_data,
184
209
  previous_error: previousStudioExecutionRun?.error,
185
- }
210
+ };
186
211
 
187
212
  const result_schema = params.result_schema;
188
213
 
189
214
  log.debug(`About to execute interaction ${interactionName}`, { config, data, result_schema, tags });
190
215
 
191
- const res = await client.interactions.executeByName(interactionName, {
192
- config,
193
- data,
194
- result_schema,
195
- tags,
196
- stream: false,
197
- }).catch((err) => {
198
- log.error(`Error executing interaction ${interactionName}`, { err });
199
- throw new Error(`Interaction Execution failed ${interactionName}: ${err.message}`);
200
- });
216
+ const res = await client.interactions
217
+ .executeByName(interactionName, {
218
+ config,
219
+ data,
220
+ result_schema,
221
+ tags,
222
+ stream: false,
223
+ })
224
+ .catch((err) => {
225
+ log.error(`Error executing interaction ${interactionName}`, { err });
226
+ throw new Error(`Interaction Execution failed ${interactionName}: ${err.message}`);
227
+ });
201
228
 
202
229
  if (debug) {
203
230
  log.info(`Interaction executed ${interactionName}`, res);
@@ -209,4 +236,4 @@ export async function executeInteractionFromActivity(client: VertesiaClient, int
209
236
  }
210
237
 
211
238
  return res;
212
- }
239
+ }
@@ -1,33 +1,41 @@
1
1
  import { log } from "@temporalio/activity";
2
- import { ContentObject, CreateContentObjectPayload, DSLActivityExecutionPayload, DSLActivitySpec } from '@vertesia/common';
3
- import { mutoolPdfToText } from '../conversion/mutool.js';
4
- import { manyToMarkdown } from '../conversion/pandoc.js';
2
+ import {
3
+ ContentObject,
4
+ CreateContentObjectPayload,
5
+ DSLActivityExecutionPayload,
6
+ DSLActivitySpec,
7
+ } from "@vertesia/common";
8
+ import { mutoolPdfToText } from "../conversion/mutool.js";
9
+ import { markdownWithPandoc } from "../conversion/pandoc.js";
5
10
  import { setupActivity } from "../dsl/setup/ActivityContext.js";
6
- import { NoDocumentFound } from '../errors.js';
7
- import { TextExtractionResult, TextExtractionStatus } from '../result-types.js';
8
- import { fetchBlobAsBuffer, md5 } from '../utils/blobs.js';
9
- import { countTokens } from '../utils/tokens.js';
11
+ import { NoDocumentFound } from "../errors.js";
12
+ import { TextExtractionResult, TextExtractionStatus } from "../result-types.js";
13
+ import { fetchBlobAsBuffer, md5 } from "../utils/blobs.js";
14
+ import { countTokens } from "../utils/tokens.js";
15
+ import { markdownWithMarkitdown } from "../conversion/markitdown.js";
10
16
 
11
17
  //@ts-ignore
12
18
  const JSON: DSLActivitySpec = {
13
- name: 'extractDocumentText',
14
- }
19
+ name: "extractDocumentText",
20
+ };
15
21
 
16
22
  // doesn't have any own param
17
- export interface ExtractDocumentTextParams { };
23
+ export interface ExtractDocumentTextParams {}
18
24
  export interface ExtractDocumentText extends DSLActivitySpec<ExtractDocumentTextParams> {
19
- name: 'extractDocumentText';
25
+ name: "extractDocumentText";
20
26
  projection?: never;
21
27
  }
22
28
 
23
- export async function extractDocumentText(payload: DSLActivityExecutionPayload<ExtractDocumentTextParams>): Promise<TextExtractionResult> {
29
+ export async function extractDocumentText(
30
+ payload: DSLActivityExecutionPayload<ExtractDocumentTextParams>,
31
+ ): Promise<TextExtractionResult> {
24
32
  const { client, objectId } = await setupActivity(payload);
25
33
 
26
34
  const r = await client.objects.find({
27
35
  query: { _id: objectId },
28
36
  limit: 1,
29
- select: "+text"
30
- })
37
+ select: "+text",
38
+ });
31
39
  const doc = r[0] as ContentObject;
32
40
  if (!doc) {
33
41
  log.error(`Document ${objectId} not found`);
@@ -36,7 +44,6 @@ export async function extractDocumentText(payload: DSLActivityExecutionPayload<E
36
44
 
37
45
  log.info(`Extracting text for object ${doc.id}`);
38
46
 
39
-
40
47
  if (!doc.content?.type || !doc.content?.source) {
41
48
  if (doc.text) {
42
49
  return createResponse(doc, doc.text, TextExtractionStatus.skipped, "Text present and no source or type");
@@ -58,74 +65,80 @@ export async function extractDocumentText(payload: DSLActivityExecutionPayload<E
58
65
  return createResponse(doc, "", TextExtractionStatus.error, e.message);
59
66
  }
60
67
 
61
-
62
68
  let txt: string;
63
69
 
64
70
  switch (doc.content.type) {
65
-
66
- case 'application/pdf':
67
- //if pdf is more than 2MB, use mutool
71
+ case "application/pdf":
68
72
  txt = await mutoolPdfToText(fileBuffer);
69
73
  break;
70
74
 
71
- case 'text/plain':
72
- txt = fileBuffer.toString('utf8')
75
+ case "text/plain":
76
+ txt = fileBuffer.toString("utf8");
73
77
  break;
74
78
 
75
79
  //docx
76
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
77
- txt = await manyToMarkdown(fileBuffer, 'docx');
80
+ case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
81
+ txt = await markdownWithMarkitdown(fileBuffer, "docx");
82
+ break;
83
+
84
+ //pptx
85
+ case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
86
+ txt = await markdownWithMarkitdown(fileBuffer, "pptx");
78
87
  break;
79
88
 
80
89
  //html
81
- case 'text/html':
82
- txt = await manyToMarkdown(fileBuffer, 'html');
90
+ case "text/html":
91
+ txt = await markdownWithPandoc(fileBuffer, "html");
83
92
  break;
84
93
 
85
94
  //opendocument
86
- case 'application/vnd.oasis.opendocument.text':
87
- txt = await manyToMarkdown(fileBuffer, 'odt');
95
+ case "application/vnd.oasis.opendocument.text":
96
+ txt = await markdownWithPandoc(fileBuffer, "odt");
88
97
  break;
89
98
 
90
99
  //rtf
91
- case 'application/rtf':
92
- txt = await manyToMarkdown(fileBuffer, 'rtf');
100
+ case "application/rtf":
101
+ txt = await markdownWithPandoc(fileBuffer, "rtf");
93
102
  break;
94
103
 
95
104
  //markdown
96
- case 'text/markdown':
97
- txt = fileBuffer.toString('utf8');
105
+ case "text/markdown":
106
+ txt = fileBuffer.toString("utf8");
98
107
  break;
99
108
 
100
109
  //csv
101
- case 'text/csv':
102
- txt = fileBuffer.toString('utf8');
110
+ case "text/csv":
111
+ txt = fileBuffer.toString("utf8");
103
112
  break;
104
113
 
105
114
  //typescript
106
- case 'application/typescript':
107
- txt = fileBuffer.toString('utf8');
115
+ case "application/typescript":
116
+ txt = fileBuffer.toString("utf8");
108
117
  break;
109
118
 
110
119
  //javascript
111
- case 'application/javascript':
112
- txt = fileBuffer.toString('utf8');
120
+ case "application/javascript":
121
+ txt = fileBuffer.toString("utf8");
113
122
  break;
114
123
 
115
124
  //json
116
- case 'application/json':
117
- txt = fileBuffer.toString('utf8');
125
+ case "application/json":
126
+ txt = fileBuffer.toString("utf8");
118
127
  break;
119
128
 
120
129
  default:
121
130
  if (sniffIfText(fileBuffer)) {
122
- txt = fileBuffer.toString('utf8'); //TODO: add charset detection
131
+ txt = fileBuffer.toString("utf8"); //TODO: add charset detection
123
132
  break;
124
133
  }
125
- return createResponse(doc, doc.text ?? '', TextExtractionStatus.skipped, `Unsupported mime type: ${doc.content.type}`);
134
+ return createResponse(
135
+ doc,
136
+ doc.text ?? "",
137
+ TextExtractionStatus.skipped,
138
+ `Unsupported mime type: ${doc.content.type}`,
139
+ );
126
140
  }
127
141
 
128
-
129
142
  const tokensData = countTokens(txt);
130
143
  const etag = doc.content.etag ?? md5(txt);
131
144
 
@@ -135,15 +148,20 @@ export async function extractDocumentText(payload: DSLActivityExecutionPayload<E
135
148
  tokens: {
136
149
  ...tokensData,
137
150
  etag: etag,
138
- }
139
- }
151
+ },
152
+ };
140
153
 
141
154
  await client.objects.update(doc.id, updateData);
142
155
 
143
156
  return createResponse(doc, txt, TextExtractionStatus.success);
144
157
  }
145
158
 
146
- function createResponse(doc: ContentObject, text: string, status: TextExtractionStatus, message?: string): TextExtractionResult {
159
+ function createResponse(
160
+ doc: ContentObject,
161
+ text: string,
162
+ status: TextExtractionStatus,
163
+ message?: string,
164
+ ): TextExtractionResult {
147
165
  return {
148
166
  status,
149
167
  message,
@@ -151,11 +169,9 @@ function createResponse(doc: ContentObject, text: string, status: TextExtraction
151
169
  len: text.length,
152
170
  objectId: doc.id,
153
171
  hasText: !!text,
154
- }
155
-
172
+ };
156
173
  }
157
174
 
158
-
159
175
  function sniffIfText(buf: Buffer) {
160
176
  // If file is too large, don't even try
161
177
  if (buf.length > 500 * 1024) {
@@ -181,9 +197,9 @@ function sniffIfText(buf: Buffer) {
181
197
 
182
198
  // Additional check for valid UTF-8 encoding
183
199
  try {
184
- const s = buf.toString('utf8');
185
- return s.length > 0 && !s.includes('\uFFFD'); // Replacement character
200
+ const s = buf.toString("utf8");
201
+ return s.length > 0 && !s.includes("\uFFFD"); // Replacement character
186
202
  } catch (e) {
187
203
  return false;
188
204
  }
189
- }
205
+ }
@@ -214,7 +214,7 @@ async function generateTextEmbeddings({ document, client, type, config }: Execut
214
214
  }
215
215
  log.info(`Generated embeddings for part ${i}`, { len: e.values.length, duration: new Date().getTime() - localStart });
216
216
 
217
- return { inumber: i, result: e }
217
+ return { number: i, result: e }
218
218
  } catch (err: any) {
219
219
  log.info(`Error generating ${type} embeddings for part ${i} of ${document.id}`, { error: err });
220
220
  return { number: i, result: null, message: "error generating embeddings", error: err.message }
@@ -1,17 +1,17 @@
1
1
  import { log } from "@temporalio/activity";
2
2
  import { NodeStreamSource } from "@vertesia/client/node";
3
3
  import { DSLActivityExecutionPayload, DSLActivitySpec, RenditionProperties } from "@vertesia/common";
4
- import fs from 'fs';
5
4
  import ffmpeg from 'fluent-ffmpeg';
6
- import path from 'path';
5
+ import fs from 'fs';
7
6
  import os from 'os';
7
+ import path from 'path';
8
8
  import { imageResizer } from "../conversion/image.js";
9
9
  import { setupActivity } from "../dsl/setup/ActivityContext.js";
10
10
  import { NoDocumentFound, WorkflowParamNotFound } from "../errors.js";
11
11
  import { saveBlobToTempFile } from "../utils/blobs.js";
12
12
 
13
13
  interface GenerateImageRenditionParams {
14
- max_hw: number; //maximum size of the longuest side of the image
14
+ max_hw: number; //maximum size of the longest side of the image
15
15
  format: string; //format of the output image
16
16
  }
17
17
 
@@ -20,11 +20,20 @@ export interface GenerateImageRendition extends DSLActivitySpec<GenerateImageRen
20
20
  }
21
21
 
22
22
  export async function generateImageRendition(payload: DSLActivityExecutionPayload<GenerateImageRenditionParams>) {
23
- const { client, objectId, params } = await setupActivity<GenerateImageRenditionParams>(payload);
23
+ const { client, objectId, params: originParams } = await setupActivity<GenerateImageRenditionParams>(payload);
24
+
25
+ // Fix: Use maxHeightWidth if max_hw is not provided
26
+ const params = {
27
+ ...originParams,
28
+ max_hw: originParams.max_hw || (originParams as any).maxHeightWidth || 1024, // Default to 1024 if both are missing
29
+ format: originParams.format || (originParams as any).format_output || 'png' // Default to png if format is missing
30
+ };
31
+
32
+ log.info(`Generating image rendition for ${objectId}`, { originParams, params });
24
33
 
25
34
  const inputObject = await client.objects.retrieve(objectId).catch((err) => {
26
- log.error(`Failed to retrieve document ${objectId}`, err);
27
- if (err.response?.status === 404) {
35
+ log.error(`Failed to retrieve document ${objectId}`, { err });
36
+ if (err.message.includes("not found")) {
28
37
  throw new NoDocumentFound(`Document ${objectId} not found`, [objectId]);
29
38
  }
30
39
  throw err;
@@ -124,38 +133,50 @@ export async function generateImageRendition(payload: DSLActivityExecutionPayloa
124
133
  let resizedImagePath = null;
125
134
 
126
135
  try {
136
+ log.info(`Resizing image for ${objectId} page ${i}`, { page, params });
127
137
  // Resize the image using ImageMagick
128
138
  resizedImagePath = await imageResizer(page, params.max_hw, params.format);
129
139
 
130
140
  // Create a read stream from the resized image file
131
141
  const fileStream = fs.createReadStream(resizedImagePath);
132
-
142
+ const format = "image/" + params.format;
143
+ const fileId = pageId.split("/").pop() ?? "0." + params.format;
133
144
  const source = new NodeStreamSource(
134
145
  fileStream,
135
- pageId.split("/").pop() ?? "0." + params.format,
136
- "image/" + params.format,
146
+ fileId,
147
+ format,
137
148
  pageId,
138
149
  );
139
150
 
140
151
  log.info(
141
- `Uploading rendition for ${objectId} page ${i} with max_hw: ${params.max_hw} and format: ${params.format}`,
152
+ `Uploading rendition for ${objectId} page ${i} with max_hw: ${params.max_hw} and format: ${params.format}`, {
153
+ resizedImagePath,
154
+ fileId,
155
+ format,
156
+ pageId,
157
+ }
142
158
  );
143
159
 
144
160
  const result = await client.objects.upload(source).catch((err) => {
145
- log.error(`Failed to upload rendition for ${objectId} page ${i}`, { error: err });
146
- return Promise.resolve(null);
161
+ log.error(`Failed to upload rendition for ${objectId} page ${i}`, {
162
+ error: err,
163
+ errorMessage: err.message,
164
+ stack: err.stack
165
+ });
166
+ return Promise.reject(`Upload failed: ${err.message}`);
147
167
  });
168
+ log.info(`Rendition uploaded for ${objectId} page ${i}`, { result });
148
169
 
149
170
  return result;
150
171
  } catch (error) {
151
172
  log.error(`Failed to process rendition for ${objectId} page ${i}`, { error });
152
- return Promise.resolve(null);
173
+ return Promise.reject(error instanceof Error ? error.message : null);
153
174
  }
154
175
  });
155
176
 
156
177
  const uploaded = await Promise.all(uploads);
157
178
  if (!uploaded || !uploaded.length || !uploaded[0]) {
158
- log.error(`Failed to upload rendition for ${objectId}`);
179
+ log.error(`Failed to upload rendition for ${objectId}`, { uploaded });
159
180
  throw new Error(`Failed to upload rendition for ${objectId} - upload object is empty`);
160
181
  }
161
182