octaflow 0.18.0 → 0.20.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/README.md CHANGED
@@ -203,7 +203,7 @@ next to what your steps actually do.
203
203
  | ↩️ | **Saga compensation** — run rollback handlers in reverse order on failure |
204
204
  | 🚑 | **Crash recovery** — a step whose worker died is re-queued while its attempt budget lasts |
205
205
  | 💓 | **Heartbeats** — a long step proves it is alive, so a dead one is caught in seconds, not minutes |
206
- | 🔭 | **Observability** — lifecycle events (run history) + per-step spans, both pluggable |
206
+ | 🔭 | **Observability** — lifecycle events (run history), per-step spans, and `createMeterObserver` turning the events into OpenTelemetry-style metrics — all pluggable, all structural |
207
207
  | 🤖 | **AI add-on** — instrumented models, token/cost capture, quota, daily rollups |
208
208
  | 🧱 | **Pluggable everything** — `WorkflowStore`, `Dispatcher`, `StepGate`, `FlowObserver`, hooks |
209
209
 
package/dist/ai/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { S as ok, b as noopLogger, f as defineStep, l as buildWorkflow, x as err } from "../core-DNWPwFaE.js";
2
- import { a as EMBEDDING_PROVIDERS, c as AiRefusalError, d as isAiRefusalError, f as readRefusalDetails, i as DEFAULT_EMBEDDING_PROVIDER, l as REFUSAL_FINISH_REASON, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as embeddingDimensionsFor, t as AI_PROVIDERS, u as createRefusalAwareModel } from "../provider-registry-DhNXw_CC.js";
2
+ import { a as readRefusalDetails, i as isAiRefusalError, n as REFUSAL_FINISH_REASON, r as createRefusalAwareModel, t as AiRefusalError } from "../refusal-BsL2HPDb.js";
3
+ import { a as EMBEDDING_PROVIDERS, i as DEFAULT_EMBEDDING_PROVIDER, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as embeddingDimensionsFor, t as AI_PROVIDERS } from "../provider-registry-DcRDsjtT.js";
3
4
  import { wrapEmbeddingModel, wrapLanguageModel } from "ai";
4
5
  //#region src/ai/instrumented-model.ts
5
6
  function createUsageAccumulator() {
@@ -1,4 +1,5 @@
1
- import { a as EMBEDDING_PROVIDERS, t as AI_PROVIDERS, u as createRefusalAwareModel } from "../../provider-registry-DhNXw_CC.js";
1
+ import { r as createRefusalAwareModel } from "../../refusal-BsL2HPDb.js";
2
+ import { a as EMBEDDING_PROVIDERS, t as AI_PROVIDERS } from "../../provider-registry-DcRDsjtT.js";
2
3
  //#region src/ai/providers/index.ts
3
4
  const LLM_LOADERS = {
4
5
  anthropic: async (apiKey, baseURL) => {
@@ -0,0 +1,2 @@
1
+ import { a as AiProviderMeta, c as DEFAULT_AI_PROVIDER, d as EMBEDDING_PROVIDER_IDS, f as EmbeddingProviderId, i as AiProviderId, l as DEFAULT_EMBEDDING_PROVIDER, m as embeddingDimensionsFor, n as AI_PROVIDER_IDS, o as AiProviderModelOption, p as EmbeddingProviderMeta, r as AiProcessingRegion, s as AiVendorResidency, t as AI_PROVIDERS, u as EMBEDDING_PROVIDERS } from "../provider-registry-bXGOmyeh.js";
2
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, embeddingDimensionsFor };
@@ -0,0 +1,2 @@
1
+ import { a as EMBEDDING_PROVIDERS, i as DEFAULT_EMBEDDING_PROVIDER, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as embeddingDimensionsFor, t as AI_PROVIDERS } from "../provider-registry-DcRDsjtT.js";
2
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, embeddingDimensionsFor };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { $ as computeReadiness, A as StepConditionHandler, B as StepStatus, C as defineWaitStep, D as StartOptions, E as RetryPolicy, F as StepHandlerNotFoundError, G as WorkflowNotFoundError, H as WorkflowCreatedResult, I as StepHandlerRegistry, J as WorkflowStatus, K as WorkflowNotRetryableError, L as StepId, M as StepError, N as StepExecutionContext, O as StepCompensateHandler, P as StepHandler, Q as ReadinessPlan, R as StepRecord, S as defineSubWorkflowStep, T as InvalidWorkflowDefinitionError, U as WorkflowDefinition, V as WaitTimeoutPolicy, W as WorkflowId, X as JoinRule, Y as WorkflowWithSteps, Z as PlannedSkip, _ as WorkflowOutput, a as STEP_DISPLAY_STATUS, b as defineSleepStep, c as WORKFLOW_STATUS_SCHEMA, d as toPublicWorkflow, et as isTerminalStepStatus, f as StepDeps, g as TypedWorkflow, h as TypedStepContext, i as PublicWorkflowStep, it as ok, j as StepDefinition, k as StepCompensationContext, l as toDisplayStepStatus, m as TypedStep, n as PUBLIC_WORKFLOW_STEP_SCHEMA, nt as Result, o as STEP_DISPLAY_STATUS_SCHEMA, p as StepOutput, q as WorkflowRecord, r as PublicWorkflow, rt as err, s as StepDisplayStatus, t as PUBLIC_WORKFLOW_SCHEMA, tt as FlowErrorShape, u as toPublicStep, v as buildWorkflow, w as FlowError, x as defineStep, y as defineMapStep, z as StepRegistration } from "./index-BURAYZui.js";
2
2
  import { n as Logger, r as noopLogger, t as LogAttributes } from "./logger-BCus3AOa.js";
3
- import { A as WorkflowStore, C as CreateWorkflowStep, D as ListWorkflowsFilters, E as FinishWorkflowParams, O as ReopenWorkflowParams, S as CreateWorkflowParams, T as FailStepParams, _ as StepGateDecision, a as FlowTracer, b as AddChildStep, c as RecordingTracer, d as noopObserver, f as noopTracer, g as StepGate, h as RateRule, i as FlowSpan, k as TransactionalScope, l as createRecordingObserver, m as InMemoryStepGateConfig, n as FlowEventType, o as RecordedSpan, p as ConcurrencyRule, r as FlowObserver, s as RecordingObserver, t as FlowEvent, u as createRecordingTracer, v as StepGateRequest, w as CreatedWorkflow, x as CompleteStepParams, y as createInMemoryStepGate } from "./observability-B5KgSJfF.js";
3
+ import { A as ListWorkflowsFilters, C as AddChildStep, D as CreatedWorkflow, E as CreateWorkflowStep, M as TransactionalScope, N as WorkflowStore, O as FailStepParams, S as createInMemoryStepGate, T as CreateWorkflowParams, _ as InMemoryStepGateConfig, a as FlowSpan, b as StepGateDecision, c as RecordingObserver, d as createMeterObserver, f as createRecordingObserver, g as ConcurrencyRule, h as noopTracer, i as FlowObserver, j as ReopenWorkflowParams, k as FinishWorkflowParams, l as RecordingTracer, m as noopObserver, n as FlowEventType, o as FlowTracer, p as createRecordingTracer, r as FlowMeter, s as RecordedSpan, t as FlowEvent, u as combineObservers, v as RateRule, w as CompleteStepParams, x as StepGateRequest, y as StepGate } from "./observability-Bu-SXLcS.js";
4
4
  import { i as EnqueueOptions, n as DispatchStepPayload, r as Dispatcher, t as DispatchKind } from "./dispatcher-g7Ct0J6w.js";
5
5
  import { a as WorkflowCompletedArgs, i as BuildStepContextArgs, n as BeforeStartArgs, o as WorkflowHooks, r as BeforeStartResult, t as AfterStepArgs } from "./hooks-BdxIcc92.js";
6
6
  //#region src/core/registry.d.ts
@@ -162,4 +162,4 @@ export declare function createInMemoryWorkflowStore(partitionKey?: string): Work
162
162
  };
163
163
  };
164
164
  //#endregion
165
- export { AddChildStep, AfterStepArgs, BeforeStartArgs, BeforeStartResult, BuildStepContextArgs, CompleteStepParams, ConcurrencyRule, CreateWorkflowParams, CreateWorkflowStep, CreatedWorkflow, DispatchKind, DispatchStepPayload, Dispatcher, EnqueueOptions, FailStepParams, FinishWorkflowParams, FlowError, FlowErrorShape, FlowEvent, FlowEventType, FlowObserver, FlowSpan, FlowTracer, InMemoryStepGateConfig, InvalidWorkflowDefinitionError, JoinRule, ListWorkflowsFilters, LogAttributes, Logger, PUBLIC_WORKFLOW_SCHEMA, PUBLIC_WORKFLOW_STEP_SCHEMA, PlannedSkip, PublicWorkflow, PublicWorkflowStep, RateRule, ReadinessPlan, RecordedSpan, RecordingObserver, RecordingTracer, ReopenWorkflowParams, Result, RetryPolicy, STEP_DISPLAY_STATUS, STEP_DISPLAY_STATUS_SCHEMA, StartOptions, StepCompensateHandler, StepCompensationContext, StepConditionHandler, StepDefinition, StepDeps, StepDisplayStatus, StepError, StepExecutionContext, StepGate, StepGateDecision, StepGateRequest, StepHandler, StepHandlerNotFoundError, StepHandlerRegistry, StepId, StepOutput, StepRecord, StepRegistration, StepStatus, TransactionalScope, TypedStep, TypedStepContext, TypedWorkflow, WORKFLOW_STATUS_SCHEMA, WaitTimeoutPolicy, WorkflowCompletedArgs, WorkflowCreatedResult, WorkflowDefinition, WorkflowHooks, WorkflowId, WorkflowNotFoundError, WorkflowNotRetryableError, WorkflowOutput, WorkflowRecord, WorkflowStatus, WorkflowStore, WorkflowWithSteps, buildWorkflow, computeReadiness, createInMemoryStepGate, createRecordingObserver, createRecordingTracer, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, isTerminalStepStatus, noopLogger, noopObserver, noopTracer, ok, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
165
+ export { AddChildStep, AfterStepArgs, BeforeStartArgs, BeforeStartResult, BuildStepContextArgs, CompleteStepParams, ConcurrencyRule, CreateWorkflowParams, CreateWorkflowStep, CreatedWorkflow, DispatchKind, DispatchStepPayload, Dispatcher, EnqueueOptions, FailStepParams, FinishWorkflowParams, FlowError, FlowErrorShape, FlowEvent, FlowEventType, FlowMeter, FlowObserver, FlowSpan, FlowTracer, InMemoryStepGateConfig, InvalidWorkflowDefinitionError, JoinRule, ListWorkflowsFilters, LogAttributes, Logger, PUBLIC_WORKFLOW_SCHEMA, PUBLIC_WORKFLOW_STEP_SCHEMA, PlannedSkip, PublicWorkflow, PublicWorkflowStep, RateRule, ReadinessPlan, RecordedSpan, RecordingObserver, RecordingTracer, ReopenWorkflowParams, Result, RetryPolicy, STEP_DISPLAY_STATUS, STEP_DISPLAY_STATUS_SCHEMA, StartOptions, StepCompensateHandler, StepCompensationContext, StepConditionHandler, StepDefinition, StepDeps, StepDisplayStatus, StepError, StepExecutionContext, StepGate, StepGateDecision, StepGateRequest, StepHandler, StepHandlerNotFoundError, StepHandlerRegistry, StepId, StepOutput, StepRecord, StepRegistration, StepStatus, TransactionalScope, TypedStep, TypedStepContext, TypedWorkflow, WORKFLOW_STATUS_SCHEMA, WaitTimeoutPolicy, WorkflowCompletedArgs, WorkflowCreatedResult, WorkflowDefinition, WorkflowHooks, WorkflowId, WorkflowNotFoundError, WorkflowNotRetryableError, WorkflowOutput, WorkflowRecord, WorkflowStatus, WorkflowStore, WorkflowWithSteps, buildWorkflow, combineObservers, computeReadiness, createInMemoryStepGate, createMeterObserver, createRecordingObserver, createRecordingTracer, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, isTerminalStepStatus, noopLogger, noopObserver, noopTracer, ok, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
package/dist/index.js CHANGED
@@ -153,6 +153,85 @@ function createRecordingObserver() {
153
153
  }
154
154
  };
155
155
  }
156
+ /** Seconds-scale duration buckets, the OpenTelemetry semantic-convention set. */
157
+ const DURATION_SECONDS_BOUNDARIES = [
158
+ .005,
159
+ .01,
160
+ .025,
161
+ .05,
162
+ .075,
163
+ .1,
164
+ .25,
165
+ .5,
166
+ .75,
167
+ 1,
168
+ 2.5,
169
+ 5,
170
+ 7.5,
171
+ 10,
172
+ 30,
173
+ 60,
174
+ 300
175
+ ];
176
+ /**
177
+ * A `FlowObserver` that turns the event stream into metrics:
178
+ *
179
+ * - `octaflow.workflow.events` (counter) — every workflow transition, by
180
+ * `workflow_type` and `event`.
181
+ * - `octaflow.step.events` (counter) — every step transition, by
182
+ * `workflow_type`, `step_key`, `step_type` and `event`.
183
+ * - `octaflow.step.duration` (histogram, seconds) — one point per
184
+ * `step.completed` / `step.failed`, by `workflow_type`, `step_key` and
185
+ * `outcome`.
186
+ *
187
+ * Attributes are the definitions' names, never ids — a workflow id in a
188
+ * metric attribute is a cardinality leak. Pass it as `observer` to the engine;
189
+ * combine with a history sink through `combineObservers`.
190
+ */
191
+ function createMeterObserver(meter) {
192
+ const workflowEvents = meter.counter("octaflow.workflow.events", {
193
+ description: "Workflow lifecycle transitions.",
194
+ unit: "{event}"
195
+ });
196
+ const stepEvents = meter.counter("octaflow.step.events", {
197
+ description: "Step lifecycle transitions.",
198
+ unit: "{event}"
199
+ });
200
+ const stepDuration = meter.histogram("octaflow.step.duration", {
201
+ description: "Wall-clock duration of one step run.",
202
+ unit: "s",
203
+ boundaries: DURATION_SECONDS_BOUNDARIES
204
+ });
205
+ return { record(event) {
206
+ const workflowType = event.workflowType ?? "";
207
+ if (event.type.startsWith("workflow.")) {
208
+ workflowEvents.add(1, {
209
+ workflow_type: workflowType,
210
+ event: event.type
211
+ });
212
+ return;
213
+ }
214
+ stepEvents.add(1, {
215
+ workflow_type: workflowType,
216
+ step_key: event.stepKey ?? "",
217
+ step_type: event.stepType ?? "",
218
+ event: event.type
219
+ });
220
+ if ((event.type === "step.completed" || event.type === "step.failed") && event.durationMs !== void 0) stepDuration.record(event.durationMs / 1e3, {
221
+ workflow_type: workflowType,
222
+ step_key: event.stepKey ?? "",
223
+ outcome: event.type === "step.completed" ? "completed" : "failed"
224
+ });
225
+ } };
226
+ }
227
+ /** Fan one event out to several observers (history sink + metrics, say). Each is guarded. */
228
+ function combineObservers(...observers) {
229
+ return { record(event) {
230
+ for (const observer of observers) try {
231
+ observer.record(event);
232
+ } catch {}
233
+ } };
234
+ }
156
235
  const noopSpan = {
157
236
  setAttribute() {},
158
237
  recordError() {},
@@ -2154,4 +2233,4 @@ function createInMemoryWorkflowStore(partitionKey = "default") {
2154
2233
  };
2155
2234
  }
2156
2235
  //#endregion
2157
- export { PUBLIC_WORKFLOW_SCHEMA, PUBLIC_WORKFLOW_STEP_SCHEMA, STEP_DISPLAY_STATUS, STEP_DISPLAY_STATUS_SCHEMA, WORKFLOW_STATUS_SCHEMA, buildWorkflow, computeReadiness, createInMemoryStepGate, createInMemoryWorkflowStore, createRecordingObserver, createRecordingTracer, createStepHandlerRegistry, createWorkflowEngine, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, explicitRetryability, isRetryableError, isTerminalStepStatus, markRetryable, nonRetryableError, noopLogger, noopObserver, noopTracer, ok, retryableError, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
2236
+ export { PUBLIC_WORKFLOW_SCHEMA, PUBLIC_WORKFLOW_STEP_SCHEMA, STEP_DISPLAY_STATUS, STEP_DISPLAY_STATUS_SCHEMA, WORKFLOW_STATUS_SCHEMA, buildWorkflow, combineObservers, computeReadiness, createInMemoryStepGate, createInMemoryWorkflowStore, createMeterObserver, createRecordingObserver, createRecordingTracer, createStepHandlerRegistry, createWorkflowEngine, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, explicitRetryability, isRetryableError, isTerminalStepStatus, markRetryable, nonRetryableError, noopLogger, noopObserver, noopTracer, ok, retryableError, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
@@ -316,6 +316,45 @@ interface RecordingObserver extends FlowObserver {
316
316
  clear(): void;
317
317
  }
318
318
  declare function createRecordingObserver(): RecordingObserver;
319
+ /**
320
+ * The slice of a metrics API the engine's meter observer needs. Structural:
321
+ * `@octabits-io/framework/telemetry`'s meter and an OpenTelemetry `Meter`
322
+ * both fit (the SDK's `createCounter`/`createHistogram` need a two-line
323
+ * adapter, the framework's meter none).
324
+ */
325
+ interface FlowMeter {
326
+ counter(name: string, options?: {
327
+ description?: string;
328
+ unit?: string;
329
+ }): {
330
+ add(value: number, attributes?: Record<string, string | number | boolean>): void;
331
+ };
332
+ histogram(name: string, options?: {
333
+ description?: string;
334
+ unit?: string;
335
+ boundaries?: readonly number[];
336
+ }): {
337
+ record(value: number, attributes?: Record<string, string | number | boolean>): void;
338
+ };
339
+ }
340
+ /**
341
+ * A `FlowObserver` that turns the event stream into metrics:
342
+ *
343
+ * - `octaflow.workflow.events` (counter) — every workflow transition, by
344
+ * `workflow_type` and `event`.
345
+ * - `octaflow.step.events` (counter) — every step transition, by
346
+ * `workflow_type`, `step_key`, `step_type` and `event`.
347
+ * - `octaflow.step.duration` (histogram, seconds) — one point per
348
+ * `step.completed` / `step.failed`, by `workflow_type`, `step_key` and
349
+ * `outcome`.
350
+ *
351
+ * Attributes are the definitions' names, never ids — a workflow id in a
352
+ * metric attribute is a cardinality leak. Pass it as `observer` to the engine;
353
+ * combine with a history sink through `combineObservers`.
354
+ */
355
+ declare function createMeterObserver(meter: FlowMeter): FlowObserver;
356
+ /** Fan one event out to several observers (history sink + metrics, say). Each is guarded. */
357
+ declare function combineObservers(...observers: FlowObserver[]): FlowObserver;
319
358
  /** A minimal span handle. Maps 1:1 onto an OpenTelemetry span in an adapter. */
320
359
  interface FlowSpan {
321
360
  setAttribute(key: string, value: string | number | boolean): void;
@@ -342,4 +381,4 @@ interface RecordingTracer extends FlowTracer {
342
381
  }
343
382
  declare function createRecordingTracer(): RecordingTracer;
344
383
  //#endregion
345
- export { WorkflowStore as A, CreateWorkflowStep as C, ListWorkflowsFilters as D, FinishWorkflowParams as E, ReopenWorkflowParams as O, CreateWorkflowParams as S, FailStepParams as T, StepGateDecision as _, FlowTracer as a, AddChildStep as b, RecordingTracer as c, noopObserver as d, noopTracer as f, StepGate as g, RateRule as h, FlowSpan as i, TransactionalScope as k, createRecordingObserver as l, InMemoryStepGateConfig as m, FlowEventType as n, RecordedSpan as o, ConcurrencyRule as p, FlowObserver as r, RecordingObserver as s, FlowEvent as t, createRecordingTracer as u, StepGateRequest as v, CreatedWorkflow as w, CompleteStepParams as x, createInMemoryStepGate as y };
384
+ export { ListWorkflowsFilters as A, AddChildStep as C, CreatedWorkflow as D, CreateWorkflowStep as E, TransactionalScope as M, WorkflowStore as N, FailStepParams as O, createInMemoryStepGate as S, CreateWorkflowParams as T, InMemoryStepGateConfig as _, FlowSpan as a, StepGateDecision as b, RecordingObserver as c, createMeterObserver as d, createRecordingObserver as f, ConcurrencyRule as g, noopTracer as h, FlowObserver as i, ReopenWorkflowParams as j, FinishWorkflowParams as k, RecordingTracer as l, noopObserver as m, FlowEventType as n, FlowTracer as o, createRecordingTracer as p, FlowMeter as r, RecordedSpan as s, FlowEvent as t, combineObservers as u, RateRule as v, CompleteStepParams as w, StepGateRequest as x, StepGate as y };
@@ -0,0 +1,121 @@
1
+ //#region src/ai/provider-registry.ts
2
+ /**
3
+ * The provider registry — pure metadata about the vendors a BYOK deployment
4
+ * can point at: ids, default and cheap models, where a key is created, and
5
+ * **where the vendor processes what you send it**. Dependency-free, so a
6
+ * browser bundle (a provider/model picker, a residency badge) can import it;
7
+ * the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
8
+ *
9
+ * Adding a provider: an id here with its metadata, a factory in
10
+ * `providers/`, and pricing rows in `cost.ts`.
11
+ */
12
+ const AI_PROVIDER_IDS = ["anthropic", "mistral"];
13
+ const EMBEDDING_PROVIDER_IDS = ["openai", "mistral"];
14
+ /** What an unset provider resolves to. */
15
+ const DEFAULT_AI_PROVIDER = "anthropic";
16
+ const DEFAULT_EMBEDDING_PROVIDER = "openai";
17
+ const AI_PROVIDERS = {
18
+ anthropic: {
19
+ id: "anthropic",
20
+ label: "Anthropic",
21
+ residency: {
22
+ region: "third-country",
23
+ legalName: "Anthropic PBC",
24
+ country: "US"
25
+ },
26
+ defaultModel: "claude-sonnet-5",
27
+ classifierModel: "claude-haiku-4-5",
28
+ testModel: "claude-haiku-4-5",
29
+ keyPrefix: "sk-ant-",
30
+ consoleKeyUrl: "https://console.anthropic.com/settings/keys",
31
+ modelOptions: [
32
+ {
33
+ label: "Claude Opus 5",
34
+ value: "claude-opus-5"
35
+ },
36
+ {
37
+ label: "Claude Opus 4.8",
38
+ value: "claude-opus-4-8"
39
+ },
40
+ {
41
+ label: "Claude Sonnet 5",
42
+ value: "claude-sonnet-5"
43
+ },
44
+ {
45
+ label: "Claude Haiku 4.5",
46
+ value: "claude-haiku-4-5"
47
+ }
48
+ ]
49
+ },
50
+ mistral: {
51
+ id: "mistral",
52
+ label: "Mistral",
53
+ residency: {
54
+ region: "eu",
55
+ legalName: "Mistral AI SAS",
56
+ country: "FR"
57
+ },
58
+ defaultModel: "mistral-medium-latest",
59
+ classifierModel: "mistral-small-latest",
60
+ testModel: "mistral-small-latest",
61
+ keyPrefix: null,
62
+ consoleKeyUrl: "https://console.mistral.ai/api-keys",
63
+ modelOptions: [
64
+ {
65
+ label: "Mistral Medium 3.5",
66
+ value: "mistral-medium-latest"
67
+ },
68
+ {
69
+ label: "Mistral Large 3",
70
+ value: "mistral-large-latest"
71
+ },
72
+ {
73
+ label: "Mistral Small 4",
74
+ value: "mistral-small-latest"
75
+ }
76
+ ]
77
+ }
78
+ };
79
+ const EMBEDDING_PROVIDERS = {
80
+ openai: {
81
+ id: "openai",
82
+ label: "OpenAI",
83
+ residency: {
84
+ region: "third-country",
85
+ legalName: "OpenAI, L.L.C.",
86
+ country: "US"
87
+ },
88
+ defaultModel: "text-embedding-3-small",
89
+ consoleKeyUrl: "https://platform.openai.com/api-keys",
90
+ dimensionsByModel: {
91
+ "text-embedding-3-small": 1536,
92
+ "text-embedding-3-large": 3072
93
+ }
94
+ },
95
+ mistral: {
96
+ id: "mistral",
97
+ label: "Mistral",
98
+ residency: {
99
+ region: "eu",
100
+ legalName: "Mistral AI SAS",
101
+ country: "FR"
102
+ },
103
+ defaultModel: "mistral-embed",
104
+ consoleKeyUrl: "https://console.mistral.ai/api-keys",
105
+ dimensionsByModel: { "mistral-embed": 1024 }
106
+ }
107
+ };
108
+ /**
109
+ * Vector dimensions for an embedding model id. Unknown ids fall back to
110
+ * `fallback` (default 1536, the common OpenAI-compatible dimension) so
111
+ * free-form model ids keep a working column.
112
+ */
113
+ function embeddingDimensionsFor(modelId, fallback = 1536) {
114
+ for (const meta of Object.values(EMBEDDING_PROVIDERS)) {
115
+ const dims = meta.dimensionsByModel[modelId];
116
+ if (dims !== void 0) return dims;
117
+ }
118
+ return fallback;
119
+ }
120
+ //#endregion
121
+ export { EMBEDDING_PROVIDERS as a, DEFAULT_EMBEDDING_PROVIDER as i, AI_PROVIDER_IDS as n, EMBEDDING_PROVIDER_IDS as o, DEFAULT_AI_PROVIDER as r, embeddingDimensionsFor as s, AI_PROVIDERS as t };
@@ -101,124 +101,4 @@ function createRefusalAwareModel(model) {
101
101
  });
102
102
  }
103
103
  //#endregion
104
- //#region src/ai/provider-registry.ts
105
- /**
106
- * The provider registry — pure metadata about the vendors a BYOK deployment
107
- * can point at: ids, default and cheap models, where a key is created, and
108
- * **where the vendor processes what you send it**. Dependency-free, so a
109
- * browser bundle (a provider/model picker, a residency badge) can import it;
110
- * the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
111
- *
112
- * Adding a provider: an id here with its metadata, a factory in
113
- * `providers/`, and pricing rows in `cost.ts`.
114
- */
115
- const AI_PROVIDER_IDS = ["anthropic", "mistral"];
116
- const EMBEDDING_PROVIDER_IDS = ["openai", "mistral"];
117
- /** What an unset provider resolves to. */
118
- const DEFAULT_AI_PROVIDER = "anthropic";
119
- const DEFAULT_EMBEDDING_PROVIDER = "openai";
120
- const AI_PROVIDERS = {
121
- anthropic: {
122
- id: "anthropic",
123
- label: "Anthropic",
124
- residency: {
125
- region: "third-country",
126
- legalName: "Anthropic PBC",
127
- country: "US"
128
- },
129
- defaultModel: "claude-sonnet-5",
130
- classifierModel: "claude-haiku-4-5",
131
- testModel: "claude-haiku-4-5",
132
- keyPrefix: "sk-ant-",
133
- consoleKeyUrl: "https://console.anthropic.com/settings/keys",
134
- modelOptions: [
135
- {
136
- label: "Claude Opus 5",
137
- value: "claude-opus-5"
138
- },
139
- {
140
- label: "Claude Opus 4.8",
141
- value: "claude-opus-4-8"
142
- },
143
- {
144
- label: "Claude Sonnet 5",
145
- value: "claude-sonnet-5"
146
- },
147
- {
148
- label: "Claude Haiku 4.5",
149
- value: "claude-haiku-4-5"
150
- }
151
- ]
152
- },
153
- mistral: {
154
- id: "mistral",
155
- label: "Mistral",
156
- residency: {
157
- region: "eu",
158
- legalName: "Mistral AI SAS",
159
- country: "FR"
160
- },
161
- defaultModel: "mistral-medium-latest",
162
- classifierModel: "mistral-small-latest",
163
- testModel: "mistral-small-latest",
164
- keyPrefix: null,
165
- consoleKeyUrl: "https://console.mistral.ai/api-keys",
166
- modelOptions: [
167
- {
168
- label: "Mistral Medium 3.5",
169
- value: "mistral-medium-latest"
170
- },
171
- {
172
- label: "Mistral Large 3",
173
- value: "mistral-large-latest"
174
- },
175
- {
176
- label: "Mistral Small 4",
177
- value: "mistral-small-latest"
178
- }
179
- ]
180
- }
181
- };
182
- const EMBEDDING_PROVIDERS = {
183
- openai: {
184
- id: "openai",
185
- label: "OpenAI",
186
- residency: {
187
- region: "third-country",
188
- legalName: "OpenAI, L.L.C.",
189
- country: "US"
190
- },
191
- defaultModel: "text-embedding-3-small",
192
- consoleKeyUrl: "https://platform.openai.com/api-keys",
193
- dimensionsByModel: {
194
- "text-embedding-3-small": 1536,
195
- "text-embedding-3-large": 3072
196
- }
197
- },
198
- mistral: {
199
- id: "mistral",
200
- label: "Mistral",
201
- residency: {
202
- region: "eu",
203
- legalName: "Mistral AI SAS",
204
- country: "FR"
205
- },
206
- defaultModel: "mistral-embed",
207
- consoleKeyUrl: "https://console.mistral.ai/api-keys",
208
- dimensionsByModel: { "mistral-embed": 1024 }
209
- }
210
- };
211
- /**
212
- * Vector dimensions for an embedding model id. Unknown ids fall back to
213
- * `fallback` (default 1536, the common OpenAI-compatible dimension) so
214
- * free-form model ids keep a working column.
215
- */
216
- function embeddingDimensionsFor(modelId, fallback = 1536) {
217
- for (const meta of Object.values(EMBEDDING_PROVIDERS)) {
218
- const dims = meta.dimensionsByModel[modelId];
219
- if (dims !== void 0) return dims;
220
- }
221
- return fallback;
222
- }
223
- //#endregion
224
- export { EMBEDDING_PROVIDERS as a, AiRefusalError as c, isAiRefusalError as d, readRefusalDetails as f, DEFAULT_EMBEDDING_PROVIDER as i, REFUSAL_FINISH_REASON as l, AI_PROVIDER_IDS as n, EMBEDDING_PROVIDER_IDS as o, DEFAULT_AI_PROVIDER as r, embeddingDimensionsFor as s, AI_PROVIDERS as t, createRefusalAwareModel as u };
104
+ export { readRefusalDetails as a, isAiRefusalError as i, REFUSAL_FINISH_REASON as n, createRefusalAwareModel as r, AiRefusalError as t };
@@ -1,5 +1,5 @@
1
1
  import { W as WorkflowId } from "../index-BURAYZui.js";
2
- import { A as WorkflowStore, g as StepGate, h as RateRule, p as ConcurrencyRule, r as FlowObserver, t as FlowEvent } from "../observability-B5KgSJfF.js";
2
+ import { N as WorkflowStore, g as ConcurrencyRule, i as FlowObserver, t as FlowEvent, v as RateRule, y as StepGate } from "../observability-Bu-SXLcS.js";
3
3
  import { Pool } from "pg";
4
4
  //#region src/store-pg/ddl.d.ts
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "octaflow",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Durable DAG workflow engine: Zod-typed steps over Postgres + pg-boss, with an optional AI add-on (token/cost/quota). Layered single package.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,6 +29,11 @@
29
29
  "types": "./dist/ai/providers/index.d.ts",
30
30
  "import": "./dist/ai/providers/index.js",
31
31
  "default": "./dist/ai/providers/index.js"
32
+ },
33
+ "./ai/registry": {
34
+ "types": "./dist/ai/registry.d.ts",
35
+ "import": "./dist/ai/registry.js",
36
+ "default": "./dist/ai/registry.js"
32
37
  }
33
38
  },
34
39
  "engines": {