@bratsos/workflow-engine 0.2.1 → 0.4.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ModelKey } from './chunk-P4KMGCT3.js';
2
- export { AVAILABLE_MODELS, AnthropicBatchProvider, DEFAULT_MODEL_KEY, GoogleBatchProvider, ModelKey, ModelStatsTracker, NoInputSchema, OpenAIBatchProvider, calculateCost, createAIHelper, defineAsyncBatchStage, defineStage, getBestProviderForModel, getDefaultModel, getModel, getModelById, getRegisteredModel, listModels, listRegisteredModels, modelSupportsBatch, printAvailableModels, registerModels, requireStageOutput, resolveModelForProvider } from './chunk-P4KMGCT3.js';
1
+ import { ModelKey } from './chunk-XS3ZX4KW.js';
2
+ export { AVAILABLE_MODELS, AnthropicBatchProvider, DEFAULT_MODEL_KEY, GoogleBatchProvider, ModelKey, ModelStatsTracker, NoInputSchema, OpenAIBatchProvider, calculateCost, createAIHelper, defineAsyncBatchStage, defineStage, getBestProviderForModel, getDefaultModel, getModel, getModelById, getRegisteredModel, listModels, listRegisteredModels, modelSupportsBatch, printAvailableModels, registerEmbeddingProvider, registerModels, requireStageOutput, resolveModelForProvider } from './chunk-XS3ZX4KW.js';
3
3
  import './chunk-D7RVRRM2.js';
4
4
  export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from './chunk-NYKMT46J.js';
5
5
  import './chunk-MUWP5SF2.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bratsos/workflow-engine",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "Type-safe, distributed workflow engine for AI-orchestrated processes with suspend/resume, parallel execution, and cost tracking",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -76,14 +76,9 @@
76
76
  "README.md",
77
77
  "LICENSE"
78
78
  ],
79
- "scripts": {
80
- "typecheck": "tsc --noEmit",
81
- "build": "tsup",
82
- "test": "vitest run",
83
- "sync-models": "tsx src/cli/sync-models.ts"
84
- },
85
79
  "dependencies": {
86
80
  "@ai-sdk/google": "^3.0.1",
81
+ "@ai-sdk/provider": "^3.0.0",
87
82
  "@openrouter/ai-sdk-provider": "^2.1.1",
88
83
  "ai": "^6.0.3",
89
84
  "js-tiktoken": "^1.0.21",
@@ -118,5 +113,11 @@
118
113
  },
119
114
  "engines": {
120
115
  "node": ">=22.11.0"
116
+ },
117
+ "scripts": {
118
+ "typecheck": "tsc --noEmit",
119
+ "build": "tsup",
120
+ "test": "vitest run",
121
+ "sync-models": "tsx src/cli/sync-models.ts"
121
122
  }
122
- }
123
+ }
@@ -108,6 +108,7 @@ await kernel.dispatch({
108
108
  | `createNodeHost` | Function | `@bratsos/workflow-engine-host-node` | Create Node.js host |
109
109
  | `createServerlessHost` | Function | `@bratsos/workflow-engine-host-serverless` | Create serverless host |
110
110
  | `createAIHelper` | Function | `@bratsos/workflow-engine` | AI operations (text, object, embed, batch) |
111
+ | `registerEmbeddingProvider` | Function | `@bratsos/workflow-engine` | Register custom embedding providers (Voyage, Cohere, etc.) |
111
112
  | `definePlugin` | Function | `@bratsos/workflow-engine/kernel` | Define kernel plugins |
112
113
  | `createPluginRunner` | Function | `@bratsos/workflow-engine/kernel` | Create plugin event processor |
113
114
 
@@ -337,6 +338,14 @@ const ai = createAIHelper(
337
338
  const { text, cost } = await ai.generateText("gemini-2.5-flash", prompt);
338
339
  const { object } = await ai.generateObject("gemini-2.5-flash", prompt, schema);
339
340
  const { embedding } = await ai.embed("text-embedding-004", ["text1"], { dimensions: 768 });
341
+ // OpenRouter embedding models (OpenAI, Cohere, etc.)
342
+ const { embedding } = await ai.embed("openai/text-embedding-3-small", ["text1"]);
343
+
344
+ // Custom embedding providers (Voyage, Cohere, Jina, etc.)
345
+ import { registerEmbeddingProvider } from "@bratsos/workflow-engine";
346
+ import { voyage } from "voyage-ai-provider";
347
+ registerEmbeddingProvider("voyage", (modelId) => voyage.embeddingModel(modelId));
348
+ // Then register models with provider: "voyage" and use ai.embed() as usual
340
349
  ```
341
350
 
342
351
  ## Persistence Setup
@@ -248,16 +248,16 @@ const result = await ai.generateObject(
248
248
 
249
249
  ## embed
250
250
 
251
- Generate embeddings for text.
251
+ Generate embeddings for text. Supports Google and OpenRouter as built-in providers, plus any custom provider registered via `registerEmbeddingProvider()`.
252
252
 
253
253
  ```typescript
254
- // Single text
254
+ // Google embedding model (with Google-specific options)
255
255
  const result = await ai.embed(
256
256
  "text-embedding-004",
257
257
  "The quick brown fox",
258
258
  {
259
259
  dimensions: 768, // Output dimensions (default: 768)
260
- taskType: "RETRIEVAL_DOCUMENT", // or "RETRIEVAL_QUERY", "SEMANTIC_SIMILARITY"
260
+ taskType: "RETRIEVAL_DOCUMENT", // Google-only: "RETRIEVAL_QUERY", "SEMANTIC_SIMILARITY"
261
261
  }
262
262
  );
263
263
 
@@ -266,6 +266,12 @@ console.log(result.dimensions); // 768
266
266
  console.log(result.inputTokens);
267
267
  console.log(result.cost);
268
268
 
269
+ // OpenRouter embedding model (OpenAI, Cohere, etc.)
270
+ const result = await ai.embed(
271
+ "openai/text-embedding-3-small",
272
+ "The quick brown fox",
273
+ );
274
+
269
275
  // Multiple texts (batch)
270
276
  const result = await ai.embed("text-embedding-004", [
271
277
  "First document",
@@ -277,6 +283,43 @@ console.log(result.embeddings); // number[][] (3 embeddings)
277
283
  console.log(result.embedding); // First embedding (convenience)
278
284
  ```
279
285
 
286
+ > **Note:** `taskType` and `outputDimensionality` options only apply to Google embedding models.
287
+ > OpenRouter embedding models work without provider-specific options. The provider is determined
288
+ > by the `provider` field in the model's `ModelConfig`.
289
+
290
+ ### Custom Embedding Providers
291
+
292
+ Use `registerEmbeddingProvider()` to add support for any AI SDK community embedding provider (Voyage, Cohere, Jina, etc.) without modifying the library. Call this once at application startup, before any `embed()` calls.
293
+
294
+ ```typescript
295
+ import { registerEmbeddingProvider, registerModels } from "@bratsos/workflow-engine";
296
+ import { voyage } from "voyage-ai-provider";
297
+
298
+ // 1. Register the provider factory (once at startup)
299
+ registerEmbeddingProvider("voyage", (modelId) => voyage.embeddingModel(modelId));
300
+
301
+ // 2. Register models that use the provider
302
+ registerModels({
303
+ "voyage-4-large": {
304
+ id: "voyage-4-large",
305
+ name: "Voyage 4 Large",
306
+ provider: "voyage", // Must match the name in registerEmbeddingProvider()
307
+ inputCostPerMillion: 0.06,
308
+ outputCostPerMillion: 0,
309
+ isEmbeddingModel: true,
310
+ },
311
+ });
312
+
313
+ // 3. Use it like any other embedding model
314
+ const { embedding } = await ai.embed("voyage-4-large", "Hello world");
315
+ ```
316
+
317
+ **How it works:**
318
+ - The factory receives the model's `id` from `ModelConfig` and must return an `EmbeddingModelV3` instance (from `@ai-sdk/provider`)
319
+ - Custom providers are checked **before** built-in providers, so you can even override `"openrouter"` or `"google"` if needed
320
+ - The workflow engine stays provider-agnostic — install your chosen provider package as your app's dependency, not the library's
321
+ - Provider-specific options (like Google's `taskType`) are handled by each provider through the AI SDK's standard mechanism
322
+
280
323
  ## streamText
281
324
 
282
325
  Stream text generation.
@@ -465,6 +508,26 @@ registerModels({
465
508
  const result = await ai.generateText("my-custom-model", prompt);
466
509
  ```
467
510
 
511
+ ### Register Custom Embedding Models
512
+
513
+ ```typescript
514
+ import { registerModels } from "@bratsos/workflow-engine";
515
+
516
+ registerModels({
517
+ "openai/text-embedding-3-small": {
518
+ id: "openai/text-embedding-3-small",
519
+ name: "OpenAI text-embedding-3-small",
520
+ provider: "openrouter",
521
+ inputCostPerMillion: 0.02,
522
+ outputCostPerMillion: 0,
523
+ isEmbeddingModel: true,
524
+ },
525
+ });
526
+
527
+ // Now usable
528
+ const { embedding } = await ai.embed("openai/text-embedding-3-small", "text");
529
+ ```
530
+
468
531
  ### Cost Calculation
469
532
 
470
533
  ```typescript