@uploadista/flow-documents-replicate 0.0.18-beta.8 → 0.0.18

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,6 +1,6 @@
1
1
 
2
2
  
3
- > @uploadista/flow-documents-replicate@0.0.18-beta.7 build /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/flow/documents/replicate
3
+ > @uploadista/flow-documents-replicate@0.0.18-beta.17 build /Users/denislaboureyras/Documents/uploadista/dev/uploadista-workspace/uploadista-sdk/packages/flow/documents/replicate
4
4
  > tsdown
5
5
 
6
6
  ℹ tsdown v0.16.8 powered by rolldown v1.0.0-beta.52
@@ -8,9 +8,17 @@
8
8
  ℹ tsconfig: tsconfig.json
9
9
  ℹ Build start
10
10
  ℹ Cleaning 4 files
11
- ℹ dist/index.mjs  5.24 kB │ gzip: 1.75 kB
12
- ℹ dist/index.mjs.map 10.59 kB │ gzip: 3.31 kB
11
+ ℹ dist/index.mjs  5.49 kB │ gzip: 1.83 kB
12
+ ℹ dist/index.mjs.map 11.02 kB │ gzip: 3.42 kB
13
13
  ℹ dist/index.d.mts.map  0.55 kB │ gzip: 0.32 kB
14
14
  ℹ dist/index.d.mts  1.72 kB │ gzip: 0.62 kB
15
- ℹ 4 files, total: 18.11 kB
16
- ✔ Build complete in 4129ms
15
+ ℹ 4 files, total: 18.79 kB
16
+ [UNRESOLVED_IMPORT] Warning: Could not resolve '@uploadista/observability' in src/document-ai-plugin.ts
17
+ ╭─[ src/document-ai-plugin.ts:8:35 ]
18
+ │
19
+ 8 │ import { withOperationSpan } from "@uploadista/observability";
20
+  │ ─────────────┬─────────────
21
+  │ ╰─────────────── Module not found, treating it as an external dependency
22
+ ───╯
23
+
24
+ ✔ Build complete in 4485ms
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/document-ai-plugin.ts"],"sourcesContent":[],"mappings":";;;;;KAUK,OAAA;KAEA,oBAAA;EAFA,MAAA,EAAA,MAAO;AAAA,CAAA;AAEa,KAKpB,oBAAA,GAAA,CAAkB,OAAA,EACZ,iBADY,GAAA;EACZ,WAAA,EAAA,WAAA;CACQ,EAAA,GAAd,MAAA,CAAO,MAAO,CAAA,oBAAA,EAAsB,eAAtB,CAAA;KAGd,YAAA,GAHoC,MAAA,GAAA;EAApC,kBAAO,CAAA,EAMe,oBANf;EAAM,4BAAA,CAAA,EAAA,OAAA;EAGb,UAAA,CAAA,EAKc,OALF;AAgFjB,CAAA;;;;;;AA6JA;AAKA;;;;;;;;;;;;;;cAlKa,2BACH;eAEO;MACd,KAAA,CAAA,MAAA;cAyJU,+BAA6B,KAAA,CAAA,MAAA;cAK7B,0CAjKH;eAEO;MACd,KAAA,CAAA,MAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/document-ai-plugin.ts"],"sourcesContent":[],"mappings":";;;;;KAWK,OAAA;KAEA,oBAAA;EAFA,MAAA,EAAA,MAAO;AAAA,CAAA;AAEa,KAKpB,oBAAA,GAAA,CAAkB,OAAA,EACZ,iBADY,GAAA;EACZ,WAAA,EAAA,WAAA;CACQ,EAAA,GAAd,MAAA,CAAO,MAAO,CAAA,oBAAA,EAAsB,eAAtB,CAAA;KAGd,YAAA,GAHoC,MAAA,GAAA;EAApC,kBAAO,CAAA,EAMe,oBANf;EAAM,4BAAA,CAAA,EAAA,OAAA;EAGb,UAAA,CAAA,EAKc,OALF;AAgFjB,CAAA;;;;;;AAoKA;AAKA;;;;;;;;;;;;;;cAzKa,2BACH;eAEO;MACd,KAAA,CAAA,MAAA;cAgKU,+BAA6B,KAAA,CAAA,MAAA;cAK7B,0CAxKH;eAEO;MACd,KAAA,CAAA,MAAA"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import { UploadistaError } from "@uploadista/core/errors";
2
2
  import { CredentialProvider, DocumentAiPlugin } from "@uploadista/core/flow";
3
+ import { withOperationSpan } from "@uploadista/observability";
3
4
  import { Effect, Layer, Option } from "effect";
4
5
  import Replicate from "replicate";
5
6
 
@@ -114,7 +115,12 @@ const documentAiPlugin = (config, options) => {
114
115
  extractedText,
115
116
  format: getFormatFromTaskType(params.taskType)
116
117
  };
117
- });
118
+ }).pipe(withOperationSpan("ai", "ocr", {
119
+ "ai.provider": "replicate",
120
+ "ai.model": ocrModelId,
121
+ "ai.task_type": params.taskType,
122
+ "ai.credential_id": context.credentialId
123
+ }));
118
124
  } }));
119
125
  };
120
126
  const ReplicateDocumentAiPluginLive = documentAiPlugin({ useCredentialProviderService: true });
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["CredentialProviderService","input: Record<string, unknown>","extractedText: string"],"sources":["../src/document-ai-plugin.ts"],"sourcesContent":["import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n CredentialProvider as CredentialProviderService,\n type DocumentAiContext,\n DocumentAiPlugin,\n type OcrResult,\n} from \"@uploadista/core/flow\";\nimport { Effect, Layer, Option } from \"effect\";\nimport Replicate from \"replicate\";\n\ntype ModelId = `${string}/${string}` | `${string}/${string}:${string}`;\n\ntype ReplicateCredentials = {\n apiKey: string;\n};\n\n// Credential provider function type\ntype CredentialProvider = (\n context: DocumentAiContext & { serviceType: \"replicate\" },\n) => Effect.Effect<ReplicateCredentials, UploadistaError>;\n\n// Plugin configuration can be either a static API key or options with credential provider or service\ntype PluginConfig =\n | string\n | {\n credentialProvider?: CredentialProvider;\n useCredentialProviderService?: boolean;\n ocrModelId?: ModelId;\n };\n\n/**\n * Map OcrTaskType to Replicate model task type\n */\nfunction mapTaskType(taskType: string): string {\n switch (taskType) {\n case \"convertToMarkdown\":\n return \"Convert to Markdown\";\n case \"freeOcr\":\n return \"Free OCR\";\n case \"parseFigure\":\n return \"Parse Figure\";\n case \"locateObject\":\n return \"Locate Object by Reference\";\n default:\n return \"Convert to Markdown\";\n }\n}\n\n/**\n * Map OcrResolution to Replicate resolution parameter\n */\nfunction mapResolution(resolution?: string): string {\n switch (resolution) {\n case \"tiny\":\n return \"Tiny\";\n case \"small\":\n return \"Small\";\n case \"base\":\n return \"Base\";\n case \"gundam\":\n return \"Gundam (Recommended)\";\n case \"large\":\n return \"Large\";\n default:\n return \"Gundam (Recommended)\";\n }\n}\n\n/**\n * Determine format based on task type\n */\nfunction getFormatFromTaskType(taskType: string): \"markdown\" | \"plain\" | \"structured\" {\n switch (taskType) {\n case \"convertToMarkdown\":\n return \"markdown\";\n case \"parseFigure\":\n return \"structured\";\n default:\n return \"plain\";\n }\n}\n\n/**\n * Create the Replicate DocumentAI plugin\n * Supports both static credentials (OSS) and dynamic credential providers (UploadistaCloud)\n *\n * @example\n * // Static credentials (OSS)\n * documentAiPlugin(process.env.REPLICATE_API_TOKEN)\n *\n * @example\n * // Dynamic credentials with function (UploadistaCloud)\n * documentAiPlugin({\n * credentialProvider: (context) => Effect.succeed({ apiKey: \"...\" })\n * })\n *\n * @example\n * // Dynamic credentials with Effect service (UploadistaCloud)\n * documentAiPlugin({\n * useCredentialProviderService: true\n * })\n */\nexport const documentAiPlugin = (\n config: PluginConfig,\n options?: {\n ocrModelId?: ModelId;\n },\n) => {\n // Parse configuration\n const isStatic = typeof config === \"string\";\n const staticApiKey = isStatic ? config : null;\n const credentialProvider = isStatic ? null : config.credentialProvider;\n const useCredentialProviderService = isStatic\n ? false\n : config.useCredentialProviderService;\n\n // Model ID for DeepSeek-OCR\n const ocrModelId =\n (isStatic ? options?.ocrModelId : config.ocrModelId) ||\n \"lucataco/deepseek-ocr:0080ec8faf4da6a14afb8502e96f5bb53afbc28b40e2d4a5e17945b8f69eb863\";\n\n // Helper to get API token (either static, from provider function, or from service)\n const getApiToken = (context: DocumentAiContext) => {\n if (staticApiKey) {\n return Effect.succeed(staticApiKey);\n }\n if (useCredentialProviderService) {\n return Effect.gen(function* () {\n const credentialProviderService = yield* Effect.serviceOption(\n CredentialProviderService,\n );\n\n if (Option.isNone(credentialProviderService)) {\n return yield* Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"Credential provider service not found\"),\n }),\n );\n }\n\n const credentials =\n yield* credentialProviderService.value.getCredential({\n clientId: context.clientId,\n serviceType: \"replicate\",\n });\n\n if (\n typeof credentials === \"object\" &&\n credentials !== null &&\n \"apiKey\" in credentials &&\n typeof credentials.apiKey === \"string\"\n ) {\n return credentials.apiKey;\n }\n\n return yield* Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"Invalid credential format from service\"),\n }),\n );\n });\n }\n if (credentialProvider) {\n return Effect.gen(function* () {\n const credentials = yield* credentialProvider({\n ...context,\n serviceType: \"replicate\",\n });\n return credentials.apiKey;\n });\n }\n return Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"No API credentials configured\"),\n }),\n );\n };\n\n return Layer.succeed(\n DocumentAiPlugin,\n DocumentAiPlugin.of({\n performOCR: (inputUrl, params, context) => {\n return Effect.gen(function* () {\n // Get API token (static or from credential provider)\n const apiToken = yield* getApiToken(context);\n\n yield* Effect.logInfo(\n `Starting OCR for document with task type: ${params.taskType}`\n );\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const replicate = new Replicate({\n auth: apiToken,\n });\n\n const input: Record<string, unknown> = {\n image: inputUrl,\n task_type: mapTaskType(params.taskType),\n resolution_size: mapResolution(params.resolution),\n };\n\n // Add reference text if provided and task type is locateObject\n if (params.taskType === \"locateObject\" && params.referenceText) {\n input.reference_text = params.referenceText;\n }\n\n const result = await replicate.run(ocrModelId, {\n input,\n });\n\n return result;\n },\n catch: (error) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n return UploadistaError.fromCode(\"OCR_FAILED\", {\n cause: errorMessage,\n });\n },\n }).pipe(\n Effect.tapError((error) =>\n Effect.logError(`OCR failed: ${error instanceof UploadistaError ? error.cause : String(error)}`)\n )\n );\n\n // Extract text from the result\n // Replicate OCR typically returns a string or an object with text\n let extractedText: string;\n\n if (typeof output === \"string\") {\n extractedText = output;\n } else if (\n typeof output === \"object\" &&\n output !== null &&\n \"text\" in output &&\n typeof output.text === \"string\"\n ) {\n extractedText = output.text;\n } else {\n // Try to stringify if it's a different format\n extractedText = JSON.stringify(output);\n }\n\n yield* Effect.logInfo(`OCR completed, extracted ${extractedText.length} characters`);\n\n const result: OcrResult = {\n extractedText,\n format: getFormatFromTaskType(params.taskType),\n };\n\n return result;\n });\n },\n })\n );\n};\n\n// Export live layer with credential provider service\nexport const ReplicateDocumentAiPluginLive = documentAiPlugin({\n useCredentialProviderService: true,\n});\n\n// Export factory function for custom configuration\nexport const createReplicateDocumentAiPlugin = documentAiPlugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["CredentialProviderService","input: Record<string, unknown>","extractedText: string"],"sources":["../src/document-ai-plugin.ts"],"sourcesContent":["import { UploadistaError } from \"@uploadista/core/errors\";\nimport {\n CredentialProvider as CredentialProviderService,\n type DocumentAiContext,\n DocumentAiPlugin,\n type OcrResult,\n} from \"@uploadista/core/flow\";\nimport { withOperationSpan } from \"@uploadista/observability\";\nimport { Effect, Layer, Option } from \"effect\";\nimport Replicate from \"replicate\";\n\ntype ModelId = `${string}/${string}` | `${string}/${string}:${string}`;\n\ntype ReplicateCredentials = {\n apiKey: string;\n};\n\n// Credential provider function type\ntype CredentialProvider = (\n context: DocumentAiContext & { serviceType: \"replicate\" },\n) => Effect.Effect<ReplicateCredentials, UploadistaError>;\n\n// Plugin configuration can be either a static API key or options with credential provider or service\ntype PluginConfig =\n | string\n | {\n credentialProvider?: CredentialProvider;\n useCredentialProviderService?: boolean;\n ocrModelId?: ModelId;\n };\n\n/**\n * Map OcrTaskType to Replicate model task type\n */\nfunction mapTaskType(taskType: string): string {\n switch (taskType) {\n case \"convertToMarkdown\":\n return \"Convert to Markdown\";\n case \"freeOcr\":\n return \"Free OCR\";\n case \"parseFigure\":\n return \"Parse Figure\";\n case \"locateObject\":\n return \"Locate Object by Reference\";\n default:\n return \"Convert to Markdown\";\n }\n}\n\n/**\n * Map OcrResolution to Replicate resolution parameter\n */\nfunction mapResolution(resolution?: string): string {\n switch (resolution) {\n case \"tiny\":\n return \"Tiny\";\n case \"small\":\n return \"Small\";\n case \"base\":\n return \"Base\";\n case \"gundam\":\n return \"Gundam (Recommended)\";\n case \"large\":\n return \"Large\";\n default:\n return \"Gundam (Recommended)\";\n }\n}\n\n/**\n * Determine format based on task type\n */\nfunction getFormatFromTaskType(taskType: string): \"markdown\" | \"plain\" | \"structured\" {\n switch (taskType) {\n case \"convertToMarkdown\":\n return \"markdown\";\n case \"parseFigure\":\n return \"structured\";\n default:\n return \"plain\";\n }\n}\n\n/**\n * Create the Replicate DocumentAI plugin\n * Supports both static credentials (OSS) and dynamic credential providers (UploadistaCloud)\n *\n * @example\n * // Static credentials (OSS)\n * documentAiPlugin(process.env.REPLICATE_API_TOKEN)\n *\n * @example\n * // Dynamic credentials with function (UploadistaCloud)\n * documentAiPlugin({\n * credentialProvider: (context) => Effect.succeed({ apiKey: \"...\" })\n * })\n *\n * @example\n * // Dynamic credentials with Effect service (UploadistaCloud)\n * documentAiPlugin({\n * useCredentialProviderService: true\n * })\n */\nexport const documentAiPlugin = (\n config: PluginConfig,\n options?: {\n ocrModelId?: ModelId;\n },\n) => {\n // Parse configuration\n const isStatic = typeof config === \"string\";\n const staticApiKey = isStatic ? config : null;\n const credentialProvider = isStatic ? null : config.credentialProvider;\n const useCredentialProviderService = isStatic\n ? false\n : config.useCredentialProviderService;\n\n // Model ID for DeepSeek-OCR\n const ocrModelId =\n (isStatic ? options?.ocrModelId : config.ocrModelId) ||\n \"lucataco/deepseek-ocr:0080ec8faf4da6a14afb8502e96f5bb53afbc28b40e2d4a5e17945b8f69eb863\";\n\n // Helper to get API token (either static, from provider function, or from service)\n const getApiToken = (context: DocumentAiContext) => {\n if (staticApiKey) {\n return Effect.succeed(staticApiKey);\n }\n if (useCredentialProviderService) {\n return Effect.gen(function* () {\n const credentialProviderService = yield* Effect.serviceOption(\n CredentialProviderService,\n );\n\n if (Option.isNone(credentialProviderService)) {\n return yield* Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"Credential provider service not found\"),\n }),\n );\n }\n\n const credentials =\n yield* credentialProviderService.value.getCredential({\n clientId: context.clientId,\n serviceType: \"replicate\",\n });\n\n if (\n typeof credentials === \"object\" &&\n credentials !== null &&\n \"apiKey\" in credentials &&\n typeof credentials.apiKey === \"string\"\n ) {\n return credentials.apiKey;\n }\n\n return yield* Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"Invalid credential format from service\"),\n }),\n );\n });\n }\n if (credentialProvider) {\n return Effect.gen(function* () {\n const credentials = yield* credentialProvider({\n ...context,\n serviceType: \"replicate\",\n });\n return credentials.apiKey;\n });\n }\n return Effect.fail(\n UploadistaError.fromCode(\"UNKNOWN_ERROR\", {\n cause: new Error(\"No API credentials configured\"),\n }),\n );\n };\n\n return Layer.succeed(\n DocumentAiPlugin,\n DocumentAiPlugin.of({\n performOCR: (inputUrl, params, context) => {\n return Effect.gen(function* () {\n // Get API token (static or from credential provider)\n const apiToken = yield* getApiToken(context);\n\n yield* Effect.logInfo(\n `Starting OCR for document with task type: ${params.taskType}`\n );\n\n const output = yield* Effect.tryPromise({\n try: async () => {\n const replicate = new Replicate({\n auth: apiToken,\n });\n\n const input: Record<string, unknown> = {\n image: inputUrl,\n task_type: mapTaskType(params.taskType),\n resolution_size: mapResolution(params.resolution),\n };\n\n // Add reference text if provided and task type is locateObject\n if (params.taskType === \"locateObject\" && params.referenceText) {\n input.reference_text = params.referenceText;\n }\n\n const result = await replicate.run(ocrModelId, {\n input,\n });\n\n return result;\n },\n catch: (error) => {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n return UploadistaError.fromCode(\"OCR_FAILED\", {\n cause: errorMessage,\n });\n },\n }).pipe(\n Effect.tapError((error) =>\n Effect.logError(`OCR failed: ${error instanceof UploadistaError ? error.cause : String(error)}`)\n )\n );\n\n // Extract text from the result\n // Replicate OCR typically returns a string or an object with text\n let extractedText: string;\n\n if (typeof output === \"string\") {\n extractedText = output;\n } else if (\n typeof output === \"object\" &&\n output !== null &&\n \"text\" in output &&\n typeof output.text === \"string\"\n ) {\n extractedText = output.text;\n } else {\n // Try to stringify if it's a different format\n extractedText = JSON.stringify(output);\n }\n\n yield* Effect.logInfo(`OCR completed, extracted ${extractedText.length} characters`);\n\n const result: OcrResult = {\n extractedText,\n format: getFormatFromTaskType(params.taskType),\n };\n\n return result;\n }).pipe(\n withOperationSpan(\"ai\", \"ocr\", {\n \"ai.provider\": \"replicate\",\n \"ai.model\": ocrModelId,\n \"ai.task_type\": params.taskType,\n \"ai.credential_id\": context.credentialId,\n }),\n );\n },\n })\n );\n};\n\n// Export live layer with credential provider service\nexport const ReplicateDocumentAiPluginLive = documentAiPlugin({\n useCredentialProviderService: true,\n});\n\n// Export factory function for custom configuration\nexport const createReplicateDocumentAiPlugin = documentAiPlugin;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uploadista/flow-documents-replicate",
3
3
  "type": "module",
4
- "version": "0.0.18-beta.8",
4
+ "version": "0.0.18",
5
5
  "description": "Replicate OCR plugin for Uploadista document processing",
6
6
  "license": "MIT",
7
7
  "author": "Uploadista",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "replicate": "1.4.0",
18
- "@uploadista/core": "0.0.18-beta.8"
18
+ "@uploadista/core": "0.0.18"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "effect": "^3.0.0"
@@ -24,7 +24,7 @@
24
24
  "@types/node": "24.10.1",
25
25
  "effect": "3.19.8",
26
26
  "tsdown": "0.16.8",
27
- "@uploadista/typescript-config": "0.0.18-beta.8"
27
+ "@uploadista/typescript-config": "0.0.18"
28
28
  },
29
29
  "scripts": {
30
30
  "build": "tsdown",
@@ -5,6 +5,7 @@ import {
5
5
  DocumentAiPlugin,
6
6
  type OcrResult,
7
7
  } from "@uploadista/core/flow";
8
+ import { withOperationSpan } from "@uploadista/observability";
8
9
  import { Effect, Layer, Option } from "effect";
9
10
  import Replicate from "replicate";
10
11
 
@@ -250,7 +251,14 @@ export const documentAiPlugin = (
250
251
  };
251
252
 
252
253
  return result;
253
- });
254
+ }).pipe(
255
+ withOperationSpan("ai", "ocr", {
256
+ "ai.provider": "replicate",
257
+ "ai.model": ocrModelId,
258
+ "ai.task_type": params.taskType,
259
+ "ai.credential_id": context.credentialId,
260
+ }),
261
+ );
254
262
  },
255
263
  })
256
264
  );