octaflow 0.21.0 → 0.23.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.
@@ -1,7 +1,7 @@
1
1
  import { E as RetryPolicy, g as TypedWorkflow, h as TypedStepContext, m as TypedStep, nt as Result, tt as FlowErrorShape } from "../index-BURAYZui.js";
2
2
  import { n as Logger } from "../logger-BCus3AOa.js";
3
3
  import { i as BuildStepContextArgs, o as WorkflowHooks } from "../hooks-BdxIcc92.js";
4
- 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";
4
+ import { C as isSubprocessorResidency, S as embeddingDimensionsFor, _ as EmbeddingProviderMeta, a as AiProcessingRegion, b as OpenAiCompatibleProviderId, c as AiProviderModelOption, d as AiVendorResidency, f as DEFAULT_AI_PROVIDER, g as EmbeddingProviderId, h as EMBEDDING_PROVIDER_IDS, i as AiEndpointResidency, l as AiResidencyError, m as EMBEDDING_PROVIDERS, n as AI_PROVIDER_IDS, o as AiProviderId, p as DEFAULT_EMBEDDING_PROVIDER, r as AiEndpointRegion, s as AiProviderMeta, t as AI_PROVIDERS, u as AiResidencyResult, v as OPENAI_COMPATIBLE_PROVIDER, w as resolveEndpointResidency, x as OpenAiCompatibleProviderMeta, y as OPENAI_COMPATIBLE_PROVIDER_ID } from "../provider-registry-BDKSe_iO.js";
5
5
  import { z } from "zod";
6
6
  import { EmbeddingModelV4, LanguageModelV4, SharedV4ProviderMetadata } from "@ai-sdk/provider";
7
7
  //#region src/ai/instrumented-model.d.ts
@@ -82,6 +82,13 @@ export interface TokenUsage {
82
82
  * pinned ids (`mistral-medium-2508`) fall to the fallback.
83
83
  */
84
84
  export declare const DEFAULT_MODEL_PRICING: Record<string, ModelPricing>;
85
+ /**
86
+ * A zero row for a model that costs nothing per token, such as one on a server
87
+ * you run. Add it per model id: `{ ...DEFAULT_MODEL_PRICING, 'qwen3-32b': ZERO_MODEL_PRICING }`.
88
+ * An id missing from the table prices at the priciest row, which is safe for a
89
+ * vendor and makes quota refuse a free model long before it should.
90
+ */
91
+ export declare const ZERO_MODEL_PRICING: ModelPricing;
85
92
  export interface CostEstimatorOptions {
86
93
  /** Pricing table keyed by model id. Defaults to `DEFAULT_MODEL_PRICING`. */
87
94
  pricing?: Record<string, ModelPricing>;
@@ -543,4 +550,4 @@ export declare function thinkingSettingsFor(providerId: string, modelId: string,
543
550
  budgetTokens: number;
544
551
  }): ThinkingSettings;
545
552
  //#endregion
546
- 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 };
553
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, AiEndpointRegion, AiEndpointResidency, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiResidencyError, AiResidencyResult, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, OpenAiCompatibleProviderId, OpenAiCompatibleProviderMeta, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
package/dist/ai/index.js CHANGED
@@ -1,6 +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
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
+ import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, i as DEFAULT_EMBEDDING_PROVIDER, l as embeddingDimensionsFor, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as OPENAI_COMPATIBLE_PROVIDER, t as AI_PROVIDERS, u as isSubprocessorResidency } from "../provider-registry-DHL-Ed-L.js";
4
4
  import { wrapEmbeddingModel, wrapLanguageModel } from "ai";
5
5
  //#region src/ai/instrumented-model.ts
6
6
  function createUsageAccumulator() {
@@ -266,6 +266,18 @@ const DEFAULT_MODEL_PRICING = {
266
266
  cacheWritePerMillion: 0
267
267
  }
268
268
  };
269
+ /**
270
+ * A zero row for a model that costs nothing per token, such as one on a server
271
+ * you run. Add it per model id: `{ ...DEFAULT_MODEL_PRICING, 'qwen3-32b': ZERO_MODEL_PRICING }`.
272
+ * An id missing from the table prices at the priciest row, which is safe for a
273
+ * vendor and makes quota refuse a free model long before it should.
274
+ */
275
+ const ZERO_MODEL_PRICING = Object.freeze({
276
+ inputPerMillion: 0,
277
+ outputPerMillion: 0,
278
+ cacheReadPerMillion: 0,
279
+ cacheWritePerMillion: 0
280
+ });
269
281
  function priciest(pricing) {
270
282
  let best;
271
283
  for (const p of Object.values(pricing)) if (!best || p.outputPerMillion > best.outputPerMillion) best = p;
@@ -650,4 +662,4 @@ function thinkingSettingsFor(providerId, modelId, opts) {
650
662
  return { temperature: opts.temperature };
651
663
  }
652
664
  //#endregion
653
- export { AI_PROVIDERS, AI_PROVIDER_IDS, AiRefusalError, DEFAULT_AI_PROVIDER, DEFAULT_AI_QUOTA, DEFAULT_EMBEDDING_PROVIDER, DEFAULT_MODEL_PRICING, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, REFUSAL_FINISH_REASON, anthropicThinkingSettings, buildAiWorkflow, createAiQuotaService, createAiUsageAggregationService, createAiWorkflowHooks, createCostEstimator, createEmbeddingUsageAccumulator, createInstrumentedEmbeddingModel, createInstrumentedModel, createRefusalAwareModel, createUsageAccumulator, defineAiStep, embeddingDimensionsFor, estimateCostMicros, isAiRefusalError, readRefusalDetails, supportsAdaptiveThinking, supportsToolSearch, thinkingSettingsFor };
665
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, AiRefusalError, DEFAULT_AI_PROVIDER, DEFAULT_AI_QUOTA, DEFAULT_EMBEDDING_PROVIDER, DEFAULT_MODEL_PRICING, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, REFUSAL_FINISH_REASON, ZERO_MODEL_PRICING, anthropicThinkingSettings, buildAiWorkflow, createAiQuotaService, createAiUsageAggregationService, createAiWorkflowHooks, createCostEstimator, createEmbeddingUsageAccumulator, createInstrumentedEmbeddingModel, createInstrumentedModel, createRefusalAwareModel, createUsageAccumulator, defineAiStep, embeddingDimensionsFor, estimateCostMicros, isAiRefusalError, isSubprocessorResidency, readRefusalDetails, resolveEndpointResidency, supportsAdaptiveThinking, supportsToolSearch, thinkingSettingsFor };
@@ -1,4 +1,4 @@
1
- import { f as EmbeddingProviderId, i as AiProviderId } from "../../provider-registry-bXGOmyeh.js";
1
+ import { b as OpenAiCompatibleProviderId, g as EmbeddingProviderId, i as AiEndpointResidency, o as AiProviderId } from "../../provider-registry-BDKSe_iO.js";
2
2
  import { EmbeddingModelV4, LanguageModelV4 } from "@ai-sdk/provider";
3
3
  //#region src/ai/providers/index.d.ts
4
4
  export type LanguageModelFactory = (modelId: string) => LanguageModelV4;
@@ -66,4 +66,81 @@ export interface LazyEmbeddingModelMeta {
66
66
  * next call rather than cached.
67
67
  */
68
68
  export declare function createLazyEmbeddingModel(meta: LazyEmbeddingModelMeta, load: () => Promise<EmbeddingModelV4>): EmbeddingModelV4;
69
+ export type AiProviderConfigErrorKey = 'ai_residency_undeclared' | 'ai_residency_invalid' | 'ai_base_url_invalid' | 'ai_model_required' | 'ai_embedding_dimensions_invalid';
70
+ /**
71
+ * A provider configuration that cannot work. Thrown before any SDK is loaded
72
+ * or any request is made: it is a deployment mistake, found at wiring time.
73
+ */
74
+ export declare class AiProviderConfigError extends Error {
75
+ readonly key: AiProviderConfigErrorKey;
76
+ constructor(key: AiProviderConfigErrorKey, message: string);
77
+ }
78
+ export interface OpenAiCompatibleEndpointConfig {
79
+ /** The API root including its version segment, e.g. `http://vllm.ai.svc:8000/v1`. Required: there is no default host. */
80
+ baseUrl: string;
81
+ /** Sent as `Authorization: Bearer …` when set. Most self-hosted servers need none. */
82
+ apiKey?: string;
83
+ /** Where the endpoint processes payloads. Required, validated by `resolveEndpointResidency`. */
84
+ residency: AiEndpointResidency;
85
+ /** Reported as the model's `provider`. Defaults to `openai-compatible`. */
86
+ name?: string;
87
+ headers?: Record<string, string>;
88
+ /** A fetch implementation, for middleware or tests. Defaults to the global `fetch`. */
89
+ fetch?: typeof globalThis.fetch;
90
+ }
91
+ export interface OpenAiCompatibleModelProviderConfig extends OpenAiCompatibleEndpointConfig {
92
+ /** The model a call without an id uses. Required: a server you run has no registry default. */
93
+ defaultModel: string;
94
+ /** Cheap model for classifier-style passes. Defaults to `defaultModel`. */
95
+ classifierModel?: string;
96
+ /** Set when the server enforces a JSON schema on output (vLLM does); otherwise `generateObject` uses JSON mode. */
97
+ structuredOutputs?: boolean;
98
+ /**
99
+ * Ask for token usage on streamed responses. Defaults to `true`, because the
100
+ * instrumented model meters what the stream reports and a stream without it
101
+ * reports zero tokens. Turn it off only for a server that rejects the option.
102
+ */
103
+ includeUsage?: boolean;
104
+ }
105
+ export interface OpenAiCompatibleModelProvider {
106
+ providerId: OpenAiCompatibleProviderId;
107
+ /** The declared residency, validated — what a badge or an audit record shows. */
108
+ residency: AiEndpointResidency;
109
+ classifierModelId: string;
110
+ /** A Chat Completions model, wrapped for refusal detection like the vendor ones. */
111
+ languageModel(modelId?: string): LanguageModelV4;
112
+ }
113
+ export interface OpenAiCompatibleEmbeddingProviderConfig extends OpenAiCompatibleEndpointConfig {
114
+ model: string;
115
+ /**
116
+ * The model's vector width, which must match your `vector(N)` column.
117
+ * Required: a guessed width, such as the registry's 1536 fallback, silently
118
+ * breaks a 1024-wide model like `bge-m3` at the first insert.
119
+ */
120
+ dimensions: number;
121
+ }
122
+ export interface OpenAiCompatibleEmbeddingProvider {
123
+ providerId: OpenAiCompatibleProviderId;
124
+ residency: AiEndpointResidency;
125
+ modelId: string;
126
+ dimensions: number;
127
+ embeddingModel(): EmbeddingModelV4;
128
+ }
129
+ /**
130
+ * A model server you run, or any host with the OpenAI-compatible API, as
131
+ * refusal-aware models. Language models go through **Chat Completions**, which
132
+ * is what vLLM, Ollama and llama.cpp speak — not the Responses API that
133
+ * `@ai-sdk/openai` defaults to.
134
+ *
135
+ * ```ts
136
+ * const models = await createOpenAiCompatibleModelProvider({
137
+ * baseUrl: 'http://vllm.ai.svc:8000/v1',
138
+ * residency: { region: 'self-hosted' },
139
+ * defaultModel: 'qwen3-32b',
140
+ * });
141
+ * ```
142
+ */
143
+ export declare function createOpenAiCompatibleModelProvider(config: OpenAiCompatibleModelProviderConfig): Promise<OpenAiCompatibleModelProvider>;
144
+ /** An embedding model on an OpenAI-compatible endpoint, with its declared width. */
145
+ export declare function createOpenAiCompatibleEmbeddingProvider(config: OpenAiCompatibleEmbeddingProviderConfig): Promise<OpenAiCompatibleEmbeddingProvider>;
69
146
  //#endregion
@@ -1,5 +1,5 @@
1
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
+ import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, t as AI_PROVIDERS } from "../../provider-registry-DHL-Ed-L.js";
3
3
  //#region src/ai/providers/index.ts
4
4
  const LLM_LOADERS = {
5
5
  anthropic: async (apiKey, baseURL) => {
@@ -103,5 +103,87 @@ function createLazyEmbeddingModel(meta, load) {
103
103
  doEmbed: (options) => model().then((m) => m.doEmbed(options))
104
104
  };
105
105
  }
106
+ /**
107
+ * A provider configuration that cannot work. Thrown before any SDK is loaded
108
+ * or any request is made: it is a deployment mistake, found at wiring time.
109
+ */
110
+ var AiProviderConfigError = class extends Error {
111
+ key;
112
+ constructor(key, message) {
113
+ super(message);
114
+ this.name = "AiProviderConfigError";
115
+ this.key = key;
116
+ }
117
+ };
118
+ function checkEndpoint(config) {
119
+ const residency = resolveEndpointResidency(config.residency);
120
+ if (!residency.ok) throw new AiProviderConfigError(residency.error.key, residency.error.message);
121
+ let url;
122
+ try {
123
+ url = new URL(config.baseUrl);
124
+ } catch {
125
+ url = void 0;
126
+ }
127
+ if (url === void 0 || url.protocol !== "http:" && url.protocol !== "https:") throw new AiProviderConfigError("ai_base_url_invalid", `baseUrl must be an absolute http(s) URL, got ${JSON.stringify(config.baseUrl)}`);
128
+ return residency.value;
129
+ }
130
+ function requireModel(modelId, field) {
131
+ if (typeof modelId !== "string" || modelId.trim() === "") throw new AiProviderConfigError("ai_model_required", `${field} is required for an OpenAI-compatible endpoint`);
132
+ return modelId;
133
+ }
134
+ async function loadOpenAiCompatible(config, options = {}) {
135
+ const { createOpenAICompatible } = await import("@ai-sdk/openai-compatible");
136
+ return createOpenAICompatible({
137
+ name: config.name ?? "openai-compatible",
138
+ baseURL: config.baseUrl.replace(/\/+$/, ""),
139
+ apiKey: config.apiKey,
140
+ headers: config.headers,
141
+ fetch: config.fetch,
142
+ includeUsage: options.includeUsage ?? true,
143
+ supportsStructuredOutputs: options.structuredOutputs
144
+ });
145
+ }
146
+ /**
147
+ * A model server you run, or any host with the OpenAI-compatible API, as
148
+ * refusal-aware models. Language models go through **Chat Completions**, which
149
+ * is what vLLM, Ollama and llama.cpp speak — not the Responses API that
150
+ * `@ai-sdk/openai` defaults to.
151
+ *
152
+ * ```ts
153
+ * const models = await createOpenAiCompatibleModelProvider({
154
+ * baseUrl: 'http://vllm.ai.svc:8000/v1',
155
+ * residency: { region: 'self-hosted' },
156
+ * defaultModel: 'qwen3-32b',
157
+ * });
158
+ * ```
159
+ */
160
+ async function createOpenAiCompatibleModelProvider(config) {
161
+ const residency = checkEndpoint(config);
162
+ const defaultModel = requireModel(config.defaultModel, "defaultModel");
163
+ const provider = await loadOpenAiCompatible(config, {
164
+ structuredOutputs: config.structuredOutputs,
165
+ includeUsage: config.includeUsage
166
+ });
167
+ return {
168
+ providerId: OPENAI_COMPATIBLE_PROVIDER_ID,
169
+ residency,
170
+ classifierModelId: config.classifierModel ?? defaultModel,
171
+ languageModel: (modelId) => createRefusalAwareModel(provider.chatModel(modelId ?? defaultModel))
172
+ };
173
+ }
174
+ /** An embedding model on an OpenAI-compatible endpoint, with its declared width. */
175
+ async function createOpenAiCompatibleEmbeddingProvider(config) {
176
+ const residency = checkEndpoint(config);
177
+ const modelId = requireModel(config.model, "model");
178
+ if (!Number.isInteger(config.dimensions) || config.dimensions <= 0) throw new AiProviderConfigError("ai_embedding_dimensions_invalid", `dimensions must be a positive integer matching your vector column, got ${JSON.stringify(config.dimensions)}`);
179
+ const provider = await loadOpenAiCompatible(config);
180
+ return {
181
+ providerId: OPENAI_COMPATIBLE_PROVIDER_ID,
182
+ residency,
183
+ modelId,
184
+ dimensions: config.dimensions,
185
+ embeddingModel: () => provider.embeddingModel(modelId)
186
+ };
187
+ }
106
188
  //#endregion
107
- export { createEmbeddingModelFactory, createEmbeddingModelProvider, createLanguageModelFactory, createLanguageModelProvider, createLazyEmbeddingModel };
189
+ export { AiProviderConfigError, createEmbeddingModelFactory, createEmbeddingModelProvider, createLanguageModelFactory, createLanguageModelProvider, createLazyEmbeddingModel, createOpenAiCompatibleEmbeddingProvider, createOpenAiCompatibleModelProvider };
@@ -1,2 +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 };
1
+ import { C as isSubprocessorResidency, S as embeddingDimensionsFor, _ as EmbeddingProviderMeta, a as AiProcessingRegion, b as OpenAiCompatibleProviderId, c as AiProviderModelOption, d as AiVendorResidency, f as DEFAULT_AI_PROVIDER, g as EmbeddingProviderId, h as EMBEDDING_PROVIDER_IDS, i as AiEndpointResidency, l as AiResidencyError, m as EMBEDDING_PROVIDERS, n as AI_PROVIDER_IDS, o as AiProviderId, p as DEFAULT_EMBEDDING_PROVIDER, r as AiEndpointRegion, s as AiProviderMeta, t as AI_PROVIDERS, u as AiResidencyResult, v as OPENAI_COMPATIBLE_PROVIDER, w as resolveEndpointResidency, x as OpenAiCompatibleProviderMeta, y as OPENAI_COMPATIBLE_PROVIDER_ID } from "../provider-registry-BDKSe_iO.js";
2
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, AiEndpointRegion, AiEndpointResidency, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiResidencyError, AiResidencyResult, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, OpenAiCompatibleProviderId, OpenAiCompatibleProviderMeta, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
@@ -1,2 +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 };
1
+ import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, i as DEFAULT_EMBEDDING_PROVIDER, l as embeddingDimensionsFor, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as OPENAI_COMPATIBLE_PROVIDER, t as AI_PROVIDERS, u as isSubprocessorResidency } from "../provider-registry-DHL-Ed-L.js";
2
+ export { AI_PROVIDERS, AI_PROVIDER_IDS, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
@@ -1,2 +1,226 @@
1
- import { C as WireStartPayload, S as WIRE_STEP_PAYLOAD_SCHEMA, T as resolveStartIdempotencyKey, _ as ensureStepQueue, a as createPgBossScheduler, b as StepQueueConfig, c as DlqProcessor, d as PgBossStepWorkerDeps, f as PgBossStepWorkerOptions, g as createPgBossStepWorker, h as createPgBossDlqWorker, i as StartJobProcessor, l as PgBossDispatcherDeps, m as createPgBossDispatcher, n as PgBossStartWorkerDeps, o as createPgBossStartWorker, p as StepJobProcessor, r as ScheduleStartInput, s as ensureStartQueue, t as PgBossSchedulerDeps, u as PgBossDlqWorkerDeps, v as DEFAULT_STEP_QUEUE_CONFIG, w as WireStepPayload, x as WIRE_START_PAYLOAD_SCHEMA, y as StartJobContext } from "../scheduler-YCFUqjXf.js";
2
- export { DEFAULT_STEP_QUEUE_CONFIG, DlqProcessor, PgBossDispatcherDeps, PgBossDlqWorkerDeps, PgBossSchedulerDeps, PgBossStartWorkerDeps, PgBossStepWorkerDeps, PgBossStepWorkerOptions, ScheduleStartInput, StartJobContext, StartJobProcessor, StepJobProcessor, StepQueueConfig, WIRE_START_PAYLOAD_SCHEMA, WIRE_STEP_PAYLOAD_SCHEMA, WireStartPayload, WireStepPayload, createPgBossDispatcher, createPgBossDlqWorker, createPgBossScheduler, createPgBossStartWorker, createPgBossStepWorker, ensureStartQueue, ensureStepQueue, resolveStartIdempotencyKey };
1
+ import "../index-BURAYZui.js";
2
+ import { n as Logger } from "../logger-BCus3AOa.js";
3
+ import { r as Dispatcher } from "../dispatcher-g7Ct0J6w.js";
4
+ import { z } from "zod";
5
+ import { PgBoss } from "pg-boss";
6
+ //#region src/pg-boss/payload.d.ts
7
+ /**
8
+ * The wire payload for a step job. It is the flow-core `DispatchStepPayload`
9
+ * plus the `partitionKey` — the worker needs the partition to reconstruct a
10
+ * partition-scoped engine before handing the job to `engine.handleStepJob`.
11
+ */
12
+ export declare const WIRE_STEP_PAYLOAD_SCHEMA: z.ZodObject<{
13
+ partitionKey: z.ZodString;
14
+ workflowId: z.ZodNumber;
15
+ stepId: z.ZodNumber;
16
+ stepKey: z.ZodString;
17
+ stepType: z.ZodString;
18
+ kind: z.ZodDefault<z.ZodEnum<{
19
+ execute: "execute";
20
+ timeout: "timeout";
21
+ }>>;
22
+ }, z.core.$strip>;
23
+ export type WireStepPayload = z.infer<typeof WIRE_STEP_PAYLOAD_SCHEMA>;
24
+ export interface StepQueueConfig {
25
+ /** Retries before a job is dead-lettered. Default 2. */
26
+ retryLimit?: number;
27
+ /** Seconds between retries. Default 30. */
28
+ retryDelay?: number;
29
+ /** Seconds before an in-flight job is considered expired. Default 600. */
30
+ expireInSeconds?: number;
31
+ }
32
+ export declare const DEFAULT_STEP_QUEUE_CONFIG: Required<StepQueueConfig>;
33
+ /**
34
+ * The wire payload for a scheduled (or ad-hoc) workflow **start**. Carries the
35
+ * partition plus what `engine.startWorkflow` needs; the host resolves `workflowType`
36
+ * to a definition.
37
+ *
38
+ * Two mutually exclusive ways to ask for start idempotency, because a cron schedule
39
+ * stores its payload **once** and pg-boss redelivers that same payload on every tick:
40
+ *
41
+ * - `idempotencyKeyPrefix` — the usual choice. The start worker appends the job id,
42
+ * so each tick gets a distinct key while a redelivery of the *same* tick reuses it.
43
+ * - `idempotencyKey` — used verbatim. On a schedule this means "start exactly one
44
+ * workflow, ever"; every later tick returns the first one.
45
+ */
46
+ export declare const WIRE_START_PAYLOAD_SCHEMA: z.ZodObject<{
47
+ partitionKey: z.ZodString;
48
+ workflowType: z.ZodString;
49
+ input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
50
+ entityRef: z.ZodOptional<z.ZodString>;
51
+ idempotencyKey: z.ZodOptional<z.ZodString>;
52
+ idempotencyKeyPrefix: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>;
54
+ export type WireStartPayload = z.infer<typeof WIRE_START_PAYLOAD_SCHEMA>;
55
+ /**
56
+ * What a {@link WireStartPayload} becomes at delivery time: the same fields, plus the
57
+ * pg-boss job id and the **resolved** `idempotencyKey` to hand `engine.startWorkflow`.
58
+ *
59
+ * `idempotencyKey` is verbatim when the payload set one, `${idempotencyKeyPrefix}:${jobId}`
60
+ * when it set a prefix, and `undefined` when it set neither.
61
+ */
62
+ export interface StartJobContext extends WireStartPayload {
63
+ /** pg-boss job id — unique per cron tick, stable across that job's retries. */
64
+ jobId: string;
65
+ }
66
+ /** Resolve the per-delivery idempotency key. Explicit key wins over a prefix. */
67
+ export declare function resolveStartIdempotencyKey(payload: WireStartPayload, jobId: string): string | undefined;
68
+ //#endregion
69
+ //#region src/pg-boss/queue.d.ts
70
+ /**
71
+ * Create the step queue and its dead-letter queue if they do not exist. Call
72
+ * once at startup; the dispatcher also runs it from `prepare` and lazily on a
73
+ * plain first enqueue.
74
+ *
75
+ * Only what is missing is created: pg-boss's `createQueue` evicts the queue's
76
+ * entry from its per-instance cache, and a `send` that misses that cache reads
77
+ * the queue on pg-boss's *own* connection — inside a store transaction on a
78
+ * single-connection database that is a deadlock. An existing queue is left
79
+ * alone, cache entry and all.
80
+ */
81
+ export declare function ensureStepQueue(boss: PgBoss, queueName: string, config?: StepQueueConfig): Promise<void>;
82
+ export interface PgBossDispatcherDeps {
83
+ boss: PgBoss;
84
+ queueName: string;
85
+ /** Partition this dispatcher is bound to — stamped into every enqueued job. */
86
+ partitionKey: string;
87
+ config?: StepQueueConfig;
88
+ }
89
+ /** A flow-core `Dispatcher` backed by pg-boss. */
90
+ export declare function createPgBossDispatcher(deps: PgBossDispatcherDeps): Dispatcher;
91
+ export interface PgBossStepWorkerOptions {
92
+ /** Steps fetched per poll. Default 1. */
93
+ batchSize?: number;
94
+ /** Base poll interval in seconds (pg-boss minimum 0.5). Default: pg-boss's own. */
95
+ pollingIntervalSeconds?: number;
96
+ /**
97
+ * Poll interval used while pg-boss's LISTEN/NOTIFY is active for the queue, where
98
+ * polling is only a backstop. Ignored when notify is off or unavailable.
99
+ */
100
+ notifyPollingIntervalSeconds?: number;
101
+ /**
102
+ * Keep fetching with no delay while every fetch returns a full `batchSize` batch;
103
+ * the first short fetch ends the burst. Ignored when `batchSize` is 1.
104
+ *
105
+ * **Worth enabling for throughput.** Without it a worker spends most of its time
106
+ * waiting out the poll interval: it drains a batch in milliseconds, then sleeps.
107
+ * See the performance table in the README.
108
+ */
109
+ burstWhenBatchFull?: boolean;
110
+ /** Burst while the queue's cached ready count exceeds this. Reacts on pg-boss's stats cadence. */
111
+ burstWhenReadyExceeds?: number;
112
+ /**
113
+ * How many steps from one fetched batch run at a time. Default 1 (serial).
114
+ *
115
+ * Raising this only helps once the worker is not poll-bound — pair it with
116
+ * `burstWhenBatchFull`. Each in-flight step needs a store connection, so keep
117
+ * `concurrency × workers` within your Postgres pool and `max_connections`.
118
+ */
119
+ concurrency?: number;
120
+ }
121
+ export interface PgBossStepWorkerDeps {
122
+ boss: PgBoss;
123
+ queueName: string;
124
+ config?: StepQueueConfig;
125
+ logger?: Logger;
126
+ workerOptions?: PgBossStepWorkerOptions;
127
+ }
128
+ /** Handles a single step job. Reconstruct the partition-scoped engine and call
129
+ * `engine.executeStep(workflowId, stepId)`. Throw to trigger a pg-boss retry. */
130
+ export type StepJobProcessor = (payload: WireStepPayload) => Promise<void>;
131
+ /** A pg-boss worker that drives `executeStep` for step jobs. */
132
+ export declare function createPgBossStepWorker(deps: PgBossStepWorkerDeps): {
133
+ start: (process: StepJobProcessor) => Promise<void>;
134
+ stop: () => Promise<void>;
135
+ };
136
+ export interface PgBossDlqWorkerDeps {
137
+ boss: PgBoss;
138
+ queueName: string;
139
+ logger?: Logger;
140
+ pollingIntervalSeconds?: number;
141
+ }
142
+ /** Invoked for a step job that exhausted all retries. Typically calls
143
+ * `engine.handleStepExhausted(workflowId, stepId, reason)`. */
144
+ export type DlqProcessor = (payload: WireStepPayload) => Promise<void>;
145
+ /** A pg-boss worker on the step queue's dead-letter queue. */
146
+ export declare function createPgBossDlqWorker(deps: PgBossDlqWorkerDeps): {
147
+ start: (onDlq: DlqProcessor) => Promise<void>;
148
+ stop: () => Promise<void>;
149
+ };
150
+ //#endregion
151
+ //#region src/pg-boss/scheduler.d.ts
152
+ /** Create the start queue (idempotent). */
153
+ export declare function ensureStartQueue(boss: PgBoss, queueName: string): Promise<void>;
154
+ export interface PgBossSchedulerDeps {
155
+ boss: PgBoss;
156
+ /** Queue scheduled start jobs are sent to (and the start worker reads). */
157
+ queueName: string;
158
+ /** Partition stamped into every scheduled start payload. */
159
+ partitionKey: string;
160
+ logger?: Logger;
161
+ }
162
+ export interface ScheduleStartInput {
163
+ /** Unique key for this schedule within the queue (allows many crons per queue). */
164
+ key: string;
165
+ /** Cron expression (5- or 6-field). */
166
+ cron: string;
167
+ /** Workflow type to start (the host resolves it to a definition). */
168
+ workflowType: string;
169
+ input?: Record<string, unknown>;
170
+ entityRef?: string;
171
+ /**
172
+ * Per-tick start idempotency. The start worker resolves this to
173
+ * `${idempotencyKeyPrefix}:${jobId}`, so each cron tick gets a distinct key while a
174
+ * redelivery of the same tick reuses it — the usual thing you want on a schedule.
175
+ */
176
+ idempotencyKeyPrefix?: string;
177
+ /**
178
+ * Verbatim start idempotency key.
179
+ *
180
+ * A schedule stores its payload **once**, so this same key rides every tick — and
181
+ * start keys never expire. On a cron schedule that means **exactly one workflow,
182
+ * ever**; every later tick returns the first one. That is occasionally what you
183
+ * want ("run this once and never again"); if it isn't, use `idempotencyKeyPrefix`.
184
+ */
185
+ idempotencyKey?: string;
186
+ /** Optional IANA time zone (default UTC). */
187
+ tz?: string;
188
+ }
189
+ /** Registers cron schedules that enqueue workflow-start jobs. */
190
+ export declare function createPgBossScheduler(deps: PgBossSchedulerDeps): {
191
+ /** Create or replace a cron schedule that starts a workflow. */
192
+ schedule(input: ScheduleStartInput): Promise<void>;
193
+ /** Remove a schedule by key. */
194
+ unschedule(key: string): Promise<void>;
195
+ /** List the schedules registered on this queue. */
196
+ list(): Promise<import("pg-boss").Schedule[]>;
197
+ };
198
+ /**
199
+ * Invoked for each start job — typically resolves the type and calls `engine.startWorkflow`.
200
+ *
201
+ * The context's `idempotencyKey` is already resolved for **this delivery** (see
202
+ * {@link resolveStartIdempotencyKey}), so forwarding it is the right default:
203
+ *
204
+ * ```ts
205
+ * await starter.start(async (job) => {
206
+ * const wf = workflowsByType[job.workflowType];
207
+ * await engine.startWorkflow(wf.definition, job.input, { idempotencyKey: job.idempotencyKey });
208
+ * });
209
+ * ```
210
+ */
211
+ export type StartJobProcessor = (payload: StartJobContext) => Promise<void>;
212
+ export interface PgBossStartWorkerDeps {
213
+ boss: PgBoss;
214
+ queueName: string;
215
+ logger?: Logger;
216
+ workerOptions?: {
217
+ batchSize?: number;
218
+ pollingIntervalSeconds?: number;
219
+ };
220
+ }
221
+ /** A pg-boss worker on the start queue that drives a host start callback. */
222
+ export declare function createPgBossStartWorker(deps: PgBossStartWorkerDeps): {
223
+ start: (process: StartJobProcessor) => Promise<void>;
224
+ stop: () => Promise<void>;
225
+ };
226
+ //#endregion