octaflow 0.17.2 → 0.17.3
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 +6 -4
- package/dist/ai/index.d.ts +47 -48
- package/dist/dispatcher-pgboss/index.d.ts +26 -27
- package/dist/index.d.ts +14 -14
- package/dist/store-pg/index.d.ts +27 -28
- package/package.json +11 -22
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# octaflow
|
|
2
2
|
|
|
3
|
-
[](https://github.com/octabits-io/octabits/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/octaflow)
|
|
5
5
|
[](https://octaflow.octabits.io/)
|
|
6
6
|
[](./LICENSE)
|
|
@@ -299,6 +299,8 @@ enforces, and the correctness requirements a custom `WorkflowStore` has to meet.
|
|
|
299
299
|
|
|
300
300
|
## Status
|
|
301
301
|
|
|
302
|
-
Pre-1.0 — developed in [octabits
|
|
303
|
-
[
|
|
304
|
-
|
|
302
|
+
Pre-1.0 — developed in the [octabits platform monorepo](https://github.com/octabits-io/octabits)
|
|
303
|
+
under [`packages/octaflow`](https://github.com/octabits-io/octabits/tree/main/packages/octaflow)
|
|
304
|
+
(a standalone repository from 2026-07-14 to 2026-09-06; that history is merged in).
|
|
305
|
+
Independently versioned and published as the unscoped `octaflow`. The API is stable but may
|
|
306
|
+
still see breaking changes in 0.x minors.
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -4,14 +4,14 @@ import { i as BuildStepContextArgs, o as WorkflowHooks } from "../hooks-BdxIcc92
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { EmbeddingModelV4, LanguageModelV4 } from "@ai-sdk/provider";
|
|
6
6
|
//#region src/ai/instrumented-model.d.ts
|
|
7
|
-
interface AccumulatedUsage {
|
|
7
|
+
export interface AccumulatedUsage {
|
|
8
8
|
inputTokens: number;
|
|
9
9
|
outputTokens: number;
|
|
10
10
|
cacheReadTokens: number;
|
|
11
11
|
cacheWriteTokens: number;
|
|
12
12
|
modelId: string;
|
|
13
13
|
}
|
|
14
|
-
interface UsageAccumulator {
|
|
14
|
+
export interface UsageAccumulator {
|
|
15
15
|
/** Record usage from a single LLM call (additive — supports multiple calls per step). */
|
|
16
16
|
record(usage: AccumulatedUsage): void;
|
|
17
17
|
/** Total accumulated usage across all calls. */
|
|
@@ -19,20 +19,20 @@ interface UsageAccumulator {
|
|
|
19
19
|
/** Whether any usage was recorded. */
|
|
20
20
|
hasUsage(): boolean;
|
|
21
21
|
}
|
|
22
|
-
declare function createUsageAccumulator(): UsageAccumulator;
|
|
22
|
+
export declare function createUsageAccumulator(): UsageAccumulator;
|
|
23
23
|
/**
|
|
24
24
|
* Wrap a language model with usage-tracking middleware. The accumulator collects
|
|
25
25
|
* token usage from every doGenerate/doStream call routed through the wrapped model.
|
|
26
26
|
*/
|
|
27
|
-
declare function createInstrumentedModel(model: LanguageModelV4, accumulator: UsageAccumulator): LanguageModelV4;
|
|
27
|
+
export declare function createInstrumentedModel(model: LanguageModelV4, accumulator: UsageAccumulator): LanguageModelV4;
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/ai/instrumented-embedding-model.d.ts
|
|
30
|
-
interface EmbeddingAccumulatedUsage {
|
|
30
|
+
export interface EmbeddingAccumulatedUsage {
|
|
31
31
|
inputTokens: number;
|
|
32
32
|
callCount: number;
|
|
33
33
|
modelId: string;
|
|
34
34
|
}
|
|
35
|
-
interface EmbeddingUsageAccumulator {
|
|
35
|
+
export interface EmbeddingUsageAccumulator {
|
|
36
36
|
/** Record usage from a single doEmbed call (additive — supports multiple calls per batch). */
|
|
37
37
|
record(tokens: number, modelId: string): void;
|
|
38
38
|
/** Total accumulated usage across all calls. */
|
|
@@ -42,14 +42,14 @@ interface EmbeddingUsageAccumulator {
|
|
|
42
42
|
/** Clear all accumulated state — used when a long-lived accumulator is reused across flushes. */
|
|
43
43
|
reset(): void;
|
|
44
44
|
}
|
|
45
|
-
declare function createEmbeddingUsageAccumulator(): EmbeddingUsageAccumulator;
|
|
45
|
+
export declare function createEmbeddingUsageAccumulator(): EmbeddingUsageAccumulator;
|
|
46
46
|
/**
|
|
47
47
|
* Wrap an embedding model with usage-tracking middleware. The accumulator collects
|
|
48
48
|
* token usage from every doEmbed call routed through the wrapped model — both
|
|
49
49
|
* `embed()` (single value) and `embedMany()` (batched values) invoke doEmbed one or
|
|
50
50
|
* more times, and each invocation is recorded.
|
|
51
51
|
*/
|
|
52
|
-
declare function createInstrumentedEmbeddingModel(model: EmbeddingModelV4, accumulator: EmbeddingUsageAccumulator): EmbeddingModelV4;
|
|
52
|
+
export declare function createInstrumentedEmbeddingModel(model: EmbeddingModelV4, accumulator: EmbeddingUsageAccumulator): EmbeddingModelV4;
|
|
53
53
|
//#endregion
|
|
54
54
|
//#region src/ai/cost.d.ts
|
|
55
55
|
/**
|
|
@@ -59,31 +59,31 @@ declare function createInstrumentedEmbeddingModel(model: EmbeddingModelV4, accum
|
|
|
59
59
|
* The pricing table is injectable: pass your own to `createCostEstimator` for a
|
|
60
60
|
* different provider/model set. A default Anthropic/OpenAI-embedding table ships.
|
|
61
61
|
*/
|
|
62
|
-
interface ModelPricing {
|
|
62
|
+
export interface ModelPricing {
|
|
63
63
|
inputPerMillion: number;
|
|
64
64
|
outputPerMillion: number;
|
|
65
65
|
cacheReadPerMillion: number;
|
|
66
66
|
cacheWritePerMillion: number;
|
|
67
67
|
}
|
|
68
|
-
interface TokenUsage {
|
|
68
|
+
export interface TokenUsage {
|
|
69
69
|
inputTokens: number;
|
|
70
70
|
outputTokens: number;
|
|
71
71
|
cacheReadTokens: number;
|
|
72
72
|
cacheWriteTokens: number;
|
|
73
73
|
}
|
|
74
74
|
/** Default pricing (USD per million tokens), as of 2026-04. */
|
|
75
|
-
declare const DEFAULT_MODEL_PRICING: Record<string, ModelPricing>;
|
|
76
|
-
interface CostEstimatorOptions {
|
|
75
|
+
export declare const DEFAULT_MODEL_PRICING: Record<string, ModelPricing>;
|
|
76
|
+
export interface CostEstimatorOptions {
|
|
77
77
|
/** Pricing table keyed by model id. Defaults to `DEFAULT_MODEL_PRICING`. */
|
|
78
78
|
pricing?: Record<string, ModelPricing>;
|
|
79
79
|
/** Pricing used for unknown model ids. Defaults to the priciest entry in the table (safe overcounting). */
|
|
80
80
|
fallback?: ModelPricing;
|
|
81
81
|
}
|
|
82
|
-
type CostEstimator = (usage: TokenUsage, modelId: string) => number;
|
|
82
|
+
export type CostEstimator = (usage: TokenUsage, modelId: string) => number;
|
|
83
83
|
/** Build a cost estimator returning microdollars. */
|
|
84
|
-
declare function createCostEstimator(options?: CostEstimatorOptions): CostEstimator;
|
|
84
|
+
export declare function createCostEstimator(options?: CostEstimatorOptions): CostEstimator;
|
|
85
85
|
/** Convenience estimator using the default pricing table. */
|
|
86
|
-
declare const estimateCostMicros: CostEstimator;
|
|
86
|
+
export declare const estimateCostMicros: CostEstimator;
|
|
87
87
|
//#endregion
|
|
88
88
|
//#region src/ai/context.d.ts
|
|
89
89
|
/**
|
|
@@ -91,7 +91,7 @@ declare const estimateCostMicros: CostEstimator;
|
|
|
91
91
|
* `buildStepContext` hook in `createAiWorkflowHooks` and consumed by AI step
|
|
92
92
|
* handlers (which read `ctx.context.model` / `ctx.context.host`).
|
|
93
93
|
*/
|
|
94
|
-
interface AiContext<THost = unknown> {
|
|
94
|
+
export interface AiContext<THost = unknown> {
|
|
95
95
|
/** Instrumented language model — token usage is captured automatically. */
|
|
96
96
|
model: LanguageModelV4;
|
|
97
97
|
/** Host-provided per-step context (DI scope, domain services, …). */
|
|
@@ -105,7 +105,7 @@ interface AiContext<THost = unknown> {
|
|
|
105
105
|
//#endregion
|
|
106
106
|
//#region src/ai/define-ai-step.d.ts
|
|
107
107
|
/** An AI workflow step — a flow-core `TypedStep` whose context is an `AiContext`. */
|
|
108
|
-
type AiTypedStep<TInput extends Record<string, unknown> = Record<string, unknown>, TOutput extends Record<string, unknown> = Record<string, unknown>, THost = unknown, TDeps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}> = TypedStep<TInput, TOutput, TDeps, AiContext<THost>>;
|
|
108
|
+
export type AiTypedStep<TInput extends Record<string, unknown> = Record<string, unknown>, TOutput extends Record<string, unknown> = Record<string, unknown>, THost = unknown, TDeps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}> = TypedStep<TInput, TOutput, TDeps, AiContext<THost>>;
|
|
109
109
|
interface DefineAiStepConfig<TInput extends Record<string, unknown>, TOutput extends Record<string, unknown>, THost, TDeps extends Record<string, TypedStep<any, any, any, AiContext<THost>>>> {
|
|
110
110
|
type: string;
|
|
111
111
|
workflowInputSchema: z.ZodType<TInput>;
|
|
@@ -124,16 +124,16 @@ interface DefineAiStepConfig<TInput extends Record<string, unknown>, TOutput ext
|
|
|
124
124
|
* except the handler context is fixed to `AiContext<THost>`, so handlers get a
|
|
125
125
|
* ready-to-use `ctx.context.model` (instrumented) and `ctx.context.host`.
|
|
126
126
|
*/
|
|
127
|
-
declare function defineAiStep<TInput extends Record<string, unknown>, TOutput extends Record<string, unknown>, THost = unknown, TDeps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}>(config: DefineAiStepConfig<TInput, TOutput, THost, TDeps>): AiTypedStep<TInput, TOutput, THost, TDeps>;
|
|
127
|
+
export declare function defineAiStep<TInput extends Record<string, unknown>, TOutput extends Record<string, unknown>, THost = unknown, TDeps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}>(config: DefineAiStepConfig<TInput, TOutput, THost, TDeps>): AiTypedStep<TInput, TOutput, THost, TDeps>;
|
|
128
128
|
/** Build a typed AI workflow from `defineAiStep` definitions. */
|
|
129
|
-
declare function buildAiWorkflow<TInput extends Record<string, unknown>, THost = unknown, TSteps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}>(config: {
|
|
129
|
+
export declare function buildAiWorkflow<TInput extends Record<string, unknown>, THost = unknown, TSteps extends Record<string, TypedStep<any, any, any, AiContext<THost>>> = {}>(config: {
|
|
130
130
|
type: string;
|
|
131
131
|
inputSchema: z.ZodType<TInput>;
|
|
132
132
|
steps: TSteps;
|
|
133
133
|
}): TypedWorkflow<TInput, AiContext<THost>>;
|
|
134
134
|
//#endregion
|
|
135
135
|
//#region src/ai/hooks.d.ts
|
|
136
|
-
interface AiModelResolver<THost = unknown> {
|
|
136
|
+
export interface AiModelResolver<THost = unknown> {
|
|
137
137
|
/** Resolve the base (uninstrumented) model for a step. */
|
|
138
138
|
resolveModel(args: BuildStepContextArgs): Promise<LanguageModelV4> | LanguageModelV4;
|
|
139
139
|
/** Optional host context (DI scope, services) exposed to handlers as `ctx.context.host`. */
|
|
@@ -145,7 +145,7 @@ interface AiModelResolver<THost = unknown> {
|
|
|
145
145
|
*/
|
|
146
146
|
resolveKeySource?(): Promise<string> | string;
|
|
147
147
|
}
|
|
148
|
-
interface AiUsageRecorder {
|
|
148
|
+
export interface AiUsageRecorder {
|
|
149
149
|
/** Persist per-step token usage + cost (e.g. onto the step row). */
|
|
150
150
|
recordStepUsage(args: {
|
|
151
151
|
workflowId: number;
|
|
@@ -170,11 +170,11 @@ interface AiUsageRecorder {
|
|
|
170
170
|
date: string;
|
|
171
171
|
}): Promise<void>;
|
|
172
172
|
}
|
|
173
|
-
interface AiQuotaPolicy {
|
|
173
|
+
export interface AiQuotaPolicy {
|
|
174
174
|
/** Return an error (e.g. `ai_quota_exceeded`) to reject a workflow start. */
|
|
175
175
|
checkQuota(): Promise<Result<void, FlowErrorShape>>;
|
|
176
176
|
}
|
|
177
|
-
interface CreateAiWorkflowHooksDeps<THost = unknown> {
|
|
177
|
+
export interface CreateAiWorkflowHooksDeps<THost = unknown> {
|
|
178
178
|
modelResolver: AiModelResolver<THost>;
|
|
179
179
|
usageRecorder: AiUsageRecorder;
|
|
180
180
|
/** Optional quota guard. BYOK exemption etc. is the policy's concern. */
|
|
@@ -189,7 +189,7 @@ interface CreateAiWorkflowHooksDeps<THost = unknown> {
|
|
|
189
189
|
* usage rollups) into a set of flow-core lifecycle hooks. Pass the result as the
|
|
190
190
|
* engine's `hooks`. flow-core stays AI-free; everything AI lives here.
|
|
191
191
|
*/
|
|
192
|
-
declare function createAiWorkflowHooks<THost = unknown>(deps: CreateAiWorkflowHooksDeps<THost>): WorkflowHooks<AiContext<THost>>;
|
|
192
|
+
export declare function createAiWorkflowHooks<THost = unknown>(deps: CreateAiWorkflowHooksDeps<THost>): WorkflowHooks<AiContext<THost>>;
|
|
193
193
|
//#endregion
|
|
194
194
|
//#region src/ai/quota.d.ts
|
|
195
195
|
/**
|
|
@@ -198,7 +198,7 @@ declare function createAiWorkflowHooks<THost = unknown>(deps: CreateAiWorkflowHo
|
|
|
198
198
|
* return `null` for the whole config to exempt a scope entirely (e.g. a
|
|
199
199
|
* bring-your-own-key caller that shouldn't be metered against platform quota).
|
|
200
200
|
*/
|
|
201
|
-
interface AiQuotaConfig {
|
|
201
|
+
export interface AiQuotaConfig {
|
|
202
202
|
/** Max simultaneously-running workflows. `null` = unlimited. */
|
|
203
203
|
maxConcurrentWorkflows: number | null;
|
|
204
204
|
/** Max workflows started per calendar day (UTC). `null` = unlimited. */
|
|
@@ -211,14 +211,14 @@ interface AiQuotaConfig {
|
|
|
211
211
|
* flow does **not** apply these automatically — resolution policy lives in the
|
|
212
212
|
* injected {@link AiQuotaConfigResolver}.
|
|
213
213
|
*/
|
|
214
|
-
declare const DEFAULT_AI_QUOTA: AiQuotaConfig;
|
|
214
|
+
export declare const DEFAULT_AI_QUOTA: AiQuotaConfig;
|
|
215
215
|
/**
|
|
216
216
|
* Resolves the quota limits for a scope. Returning `null` exempts the scope
|
|
217
217
|
* from all quota enforcement (the check short-circuits to success).
|
|
218
218
|
*/
|
|
219
|
-
type AiQuotaConfigResolver = (partitionKey: string) => AiQuotaConfig | null | Promise<AiQuotaConfig | null>;
|
|
219
|
+
export type AiQuotaConfigResolver = (partitionKey: string) => AiQuotaConfig | null | Promise<AiQuotaConfig | null>;
|
|
220
220
|
/** A `[startDate, endDate]` inclusive query over the daily-usage rollup (dates are `YYYY-MM-DD`). */
|
|
221
|
-
interface AiUsageCountQuery {
|
|
221
|
+
export interface AiUsageCountQuery {
|
|
222
222
|
partitionKey: string;
|
|
223
223
|
/** Inclusive lower bound, `YYYY-MM-DD`. */
|
|
224
224
|
startDate: string;
|
|
@@ -232,16 +232,16 @@ interface AiUsageCountQuery {
|
|
|
232
232
|
* (e.g. excluding synthetic embedding rows from the count) lives in the
|
|
233
233
|
* consumer's SQL, keeping this layer policy-agnostic.
|
|
234
234
|
*/
|
|
235
|
-
interface AiQuotaStore {
|
|
235
|
+
export interface AiQuotaStore {
|
|
236
236
|
/** Number of workflows currently `running` for the scope. */
|
|
237
237
|
countRunningWorkflows(partitionKey: string): Promise<number>;
|
|
238
238
|
/** Sum of `workflowCount` in the daily rollup over the inclusive date range. */
|
|
239
239
|
sumWorkflowCount(query: AiUsageCountQuery): Promise<number>;
|
|
240
240
|
}
|
|
241
241
|
/** Reason a start was rejected — which window tripped. */
|
|
242
|
-
type AiQuotaExceededReason = 'concurrent_limit' | 'daily_limit' | 'monthly_limit';
|
|
242
|
+
export type AiQuotaExceededReason = 'concurrent_limit' | 'daily_limit' | 'monthly_limit';
|
|
243
243
|
/** Expected error value when a start is rejected by quota. Extends flow's structural error. */
|
|
244
|
-
interface AiQuotaExceededError {
|
|
244
|
+
export interface AiQuotaExceededError {
|
|
245
245
|
key: 'ai_quota_exceeded';
|
|
246
246
|
reason: AiQuotaExceededReason;
|
|
247
247
|
message: string;
|
|
@@ -250,7 +250,7 @@ interface AiQuotaExceededError {
|
|
|
250
250
|
/** The observed count at rejection (includes in-flight runs for the day/month windows). */
|
|
251
251
|
current: number;
|
|
252
252
|
}
|
|
253
|
-
interface CreateAiQuotaServiceDeps {
|
|
253
|
+
export interface CreateAiQuotaServiceDeps {
|
|
254
254
|
/** Count reads over the in-flight workflow table + daily rollup. */
|
|
255
255
|
store: AiQuotaStore;
|
|
256
256
|
/** Per-scope limit resolver. Return `null` to exempt the scope. */
|
|
@@ -258,7 +258,7 @@ interface CreateAiQuotaServiceDeps {
|
|
|
258
258
|
/** Clock injection for window computation (tests). Defaults to `() => new Date()`. */
|
|
259
259
|
now?: () => Date;
|
|
260
260
|
}
|
|
261
|
-
interface AiQuotaService {
|
|
261
|
+
export interface AiQuotaService {
|
|
262
262
|
/**
|
|
263
263
|
* Check all quota windows for the scope. Resolves `ok` when the start is
|
|
264
264
|
* allowed, or an {@link AiQuotaExceededError} naming the window that tripped.
|
|
@@ -271,11 +271,11 @@ interface AiQuotaService {
|
|
|
271
271
|
* Build a store-agnostic AI quota service. Enforcement order is concurrent →
|
|
272
272
|
* day → month; the first tripped window short-circuits with its error.
|
|
273
273
|
*/
|
|
274
|
-
declare function createAiQuotaService(deps: CreateAiQuotaServiceDeps): AiQuotaService;
|
|
274
|
+
export declare function createAiQuotaService(deps: CreateAiQuotaServiceDeps): AiQuotaService;
|
|
275
275
|
//#endregion
|
|
276
276
|
//#region src/ai/usage-aggregation.d.ts
|
|
277
277
|
/** An additive write into the daily-usage rollup for one run (workflow completion or embedding batch). */
|
|
278
|
-
interface DailyUsageDelta {
|
|
278
|
+
export interface DailyUsageDelta {
|
|
279
279
|
partitionKey: string;
|
|
280
280
|
/** Calendar day of the run, `YYYY-MM-DD`. */
|
|
281
281
|
date: string;
|
|
@@ -290,13 +290,13 @@ interface DailyUsageDelta {
|
|
|
290
290
|
estimatedCostMicros: number;
|
|
291
291
|
}
|
|
292
292
|
/** Inclusive `[startDate, endDate]` range query for the aggregate reads (`YYYY-MM-DD`). */
|
|
293
|
-
interface AiUsageRangeQuery {
|
|
293
|
+
export interface AiUsageRangeQuery {
|
|
294
294
|
partitionKey: string;
|
|
295
295
|
startDate: string;
|
|
296
296
|
endDate: string;
|
|
297
297
|
}
|
|
298
298
|
/** One row of the per-day aggregate (GROUP BY date). */
|
|
299
|
-
interface UsageSummaryRow {
|
|
299
|
+
export interface UsageSummaryRow {
|
|
300
300
|
date: string;
|
|
301
301
|
workflowCount: number;
|
|
302
302
|
inputTokens: number;
|
|
@@ -306,7 +306,7 @@ interface UsageSummaryRow {
|
|
|
306
306
|
estimatedCostMicros: number;
|
|
307
307
|
}
|
|
308
308
|
/** One row of the per-type aggregate (GROUP BY workflowType, keySource). */
|
|
309
|
-
interface UsageByTypeRow {
|
|
309
|
+
export interface UsageByTypeRow {
|
|
310
310
|
workflowType: string;
|
|
311
311
|
keySource: string;
|
|
312
312
|
workflowCount: number;
|
|
@@ -320,7 +320,7 @@ interface UsageByTypeRow {
|
|
|
320
320
|
* and aggregation engines. The `addDailyUsage` UPSERT and the two aggregate
|
|
321
321
|
* reads are the consumer's SQL; flow owns everything above the seam.
|
|
322
322
|
*/
|
|
323
|
-
interface AiUsageStore extends AiQuotaStore {
|
|
323
|
+
export interface AiUsageStore extends AiQuotaStore {
|
|
324
324
|
/** UPSERT-add a run's usage into the daily rollup (unique on partition+date+type+keySource). */
|
|
325
325
|
addDailyUsage(delta: DailyUsageDelta): Promise<void>;
|
|
326
326
|
/** Per-day totals over the range, ascending by date. */
|
|
@@ -329,7 +329,7 @@ interface AiUsageStore extends AiQuotaStore {
|
|
|
329
329
|
aggregateByWorkflowType(query: AiUsageRangeQuery): Promise<UsageByTypeRow[]>;
|
|
330
330
|
}
|
|
331
331
|
/** A completed LLM workflow's usage to roll up. */
|
|
332
|
-
interface WorkflowUsageInput {
|
|
332
|
+
export interface WorkflowUsageInput {
|
|
333
333
|
partitionKey: string;
|
|
334
334
|
/** Calendar day of completion, `YYYY-MM-DD`. */
|
|
335
335
|
date: string;
|
|
@@ -343,7 +343,7 @@ interface WorkflowUsageInput {
|
|
|
343
343
|
* tokens (no output, no cache); `workflowCount` increments once per flushed
|
|
344
344
|
* batch, not per inner embed call.
|
|
345
345
|
*/
|
|
346
|
-
interface EmbeddingUsageInput {
|
|
346
|
+
export interface EmbeddingUsageInput {
|
|
347
347
|
partitionKey: string;
|
|
348
348
|
/** Calendar day of the flush, `YYYY-MM-DD`. */
|
|
349
349
|
date: string;
|
|
@@ -354,7 +354,7 @@ interface EmbeddingUsageInput {
|
|
|
354
354
|
estimatedCostMicros: number;
|
|
355
355
|
}
|
|
356
356
|
/** Current-window usage snapshot for a scope. */
|
|
357
|
-
interface CurrentQuotaUsage {
|
|
357
|
+
export interface CurrentQuotaUsage {
|
|
358
358
|
today: {
|
|
359
359
|
workflowCount: number;
|
|
360
360
|
};
|
|
@@ -366,18 +366,18 @@ interface CurrentQuotaUsage {
|
|
|
366
366
|
};
|
|
367
367
|
}
|
|
368
368
|
/** Expected error value from aggregation reads/writes. Extends flow's structural error. */
|
|
369
|
-
interface AiUsageError {
|
|
369
|
+
export interface AiUsageError {
|
|
370
370
|
key: 'ai_usage_error';
|
|
371
371
|
message: string;
|
|
372
372
|
}
|
|
373
|
-
interface CreateAiUsageAggregationServiceDeps {
|
|
373
|
+
export interface CreateAiUsageAggregationServiceDeps {
|
|
374
374
|
store: AiUsageStore;
|
|
375
375
|
/** Clock injection for the current-window computation (tests). Defaults to `() => new Date()`. */
|
|
376
376
|
now?: () => Date;
|
|
377
377
|
/** Optional logger for write failures. Defaults to a no-op. */
|
|
378
378
|
logger?: Logger;
|
|
379
379
|
}
|
|
380
|
-
interface AiUsageAggregationService {
|
|
380
|
+
export interface AiUsageAggregationService {
|
|
381
381
|
/** Roll a completed LLM workflow's totals into the daily aggregate (UPSERT +1). */
|
|
382
382
|
recordWorkflowCompletion(data: WorkflowUsageInput): Promise<Result<void, AiUsageError>>;
|
|
383
383
|
/** Roll a flushed embedding batch into the daily aggregate (output/cache tokens = 0). */
|
|
@@ -392,6 +392,5 @@ interface AiUsageAggregationService {
|
|
|
392
392
|
}): Promise<Result<CurrentQuotaUsage, AiUsageError>>;
|
|
393
393
|
}
|
|
394
394
|
/** Build a store-agnostic AI usage-aggregation service. */
|
|
395
|
-
declare function createAiUsageAggregationService(deps: CreateAiUsageAggregationServiceDeps): AiUsageAggregationService;
|
|
396
|
-
//#endregion
|
|
397
|
-
export { AccumulatedUsage, AiContext, AiModelResolver, AiQuotaConfig, AiQuotaConfigResolver, AiQuotaExceededError, AiQuotaExceededReason, AiQuotaPolicy, AiQuotaService, AiQuotaStore, AiTypedStep, AiUsageAggregationService, AiUsageCountQuery, AiUsageError, AiUsageRangeQuery, AiUsageRecorder, AiUsageStore, CostEstimator, CostEstimatorOptions, CreateAiQuotaServiceDeps, CreateAiUsageAggregationServiceDeps, CreateAiWorkflowHooksDeps, CurrentQuotaUsage, DEFAULT_AI_QUOTA, DEFAULT_MODEL_PRICING, DailyUsageDelta, EmbeddingAccumulatedUsage, EmbeddingUsageAccumulator, EmbeddingUsageInput, ModelPricing, TokenUsage, UsageAccumulator, UsageByTypeRow, UsageSummaryRow, WorkflowUsageInput, buildAiWorkflow, createAiQuotaService, createAiUsageAggregationService, createAiWorkflowHooks, createCostEstimator, createEmbeddingUsageAccumulator, createInstrumentedEmbeddingModel, createInstrumentedModel, createUsageAccumulator, defineAiStep, estimateCostMicros };
|
|
395
|
+
export declare function createAiUsageAggregationService(deps: CreateAiUsageAggregationServiceDeps): AiUsageAggregationService;
|
|
396
|
+
//#endregion
|
|
@@ -9,7 +9,7 @@ import { PgBoss } from "pg-boss";
|
|
|
9
9
|
* plus the `partitionKey` — the worker needs the partition to reconstruct a
|
|
10
10
|
* partition-scoped engine before handing the job to `engine.handleStepJob`.
|
|
11
11
|
*/
|
|
12
|
-
declare const WIRE_STEP_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
12
|
+
export declare const WIRE_STEP_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
13
13
|
partitionKey: z.ZodString;
|
|
14
14
|
workflowId: z.ZodNumber;
|
|
15
15
|
stepId: z.ZodNumber;
|
|
@@ -20,8 +20,8 @@ declare const WIRE_STEP_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
|
20
20
|
timeout: "timeout";
|
|
21
21
|
}>>;
|
|
22
22
|
}, z.core.$strip>;
|
|
23
|
-
type WireStepPayload = z.infer<typeof WIRE_STEP_PAYLOAD_SCHEMA>;
|
|
24
|
-
interface StepQueueConfig {
|
|
23
|
+
export type WireStepPayload = z.infer<typeof WIRE_STEP_PAYLOAD_SCHEMA>;
|
|
24
|
+
export interface StepQueueConfig {
|
|
25
25
|
/** Retries before a job is dead-lettered. Default 2. */
|
|
26
26
|
retryLimit?: number;
|
|
27
27
|
/** Seconds between retries. Default 30. */
|
|
@@ -29,7 +29,7 @@ interface StepQueueConfig {
|
|
|
29
29
|
/** Seconds before an in-flight job is considered expired. Default 600. */
|
|
30
30
|
expireInSeconds?: number;
|
|
31
31
|
}
|
|
32
|
-
declare const DEFAULT_STEP_QUEUE_CONFIG: Required<StepQueueConfig>;
|
|
32
|
+
export declare const DEFAULT_STEP_QUEUE_CONFIG: Required<StepQueueConfig>;
|
|
33
33
|
/**
|
|
34
34
|
* The wire payload for a scheduled (or ad-hoc) workflow **start**. Carries the
|
|
35
35
|
* partition plus what `engine.startWorkflow` needs; the host resolves `workflowType`
|
|
@@ -43,7 +43,7 @@ declare const DEFAULT_STEP_QUEUE_CONFIG: Required<StepQueueConfig>;
|
|
|
43
43
|
* - `idempotencyKey` — used verbatim. On a schedule this means "start exactly one
|
|
44
44
|
* workflow, ever"; every later tick returns the first one.
|
|
45
45
|
*/
|
|
46
|
-
declare const WIRE_START_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
46
|
+
export declare const WIRE_START_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
47
47
|
partitionKey: z.ZodString;
|
|
48
48
|
workflowType: z.ZodString;
|
|
49
49
|
input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -51,7 +51,7 @@ declare const WIRE_START_PAYLOAD_SCHEMA: z.ZodObject<{
|
|
|
51
51
|
idempotencyKey: z.ZodOptional<z.ZodString>;
|
|
52
52
|
idempotencyKeyPrefix: z.ZodOptional<z.ZodString>;
|
|
53
53
|
}, z.core.$strip>;
|
|
54
|
-
type WireStartPayload = z.infer<typeof WIRE_START_PAYLOAD_SCHEMA>;
|
|
54
|
+
export type WireStartPayload = z.infer<typeof WIRE_START_PAYLOAD_SCHEMA>;
|
|
55
55
|
/**
|
|
56
56
|
* What a {@link WireStartPayload} becomes at delivery time: the same fields, plus the
|
|
57
57
|
* pg-boss job id and the **resolved** `idempotencyKey` to hand `engine.startWorkflow`.
|
|
@@ -59,12 +59,12 @@ type WireStartPayload = z.infer<typeof WIRE_START_PAYLOAD_SCHEMA>;
|
|
|
59
59
|
* `idempotencyKey` is verbatim when the payload set one, `${idempotencyKeyPrefix}:${jobId}`
|
|
60
60
|
* when it set a prefix, and `undefined` when it set neither.
|
|
61
61
|
*/
|
|
62
|
-
interface StartJobContext extends WireStartPayload {
|
|
62
|
+
export interface StartJobContext extends WireStartPayload {
|
|
63
63
|
/** pg-boss job id — unique per cron tick, stable across that job's retries. */
|
|
64
64
|
jobId: string;
|
|
65
65
|
}
|
|
66
66
|
/** Resolve the per-delivery idempotency key. Explicit key wins over a prefix. */
|
|
67
|
-
declare function resolveStartIdempotencyKey(payload: WireStartPayload, jobId: string): string | undefined;
|
|
67
|
+
export declare function resolveStartIdempotencyKey(payload: WireStartPayload, jobId: string): string | undefined;
|
|
68
68
|
//#endregion
|
|
69
69
|
//#region src/dispatcher-pgboss/queue.d.ts
|
|
70
70
|
/**
|
|
@@ -78,8 +78,8 @@ declare function resolveStartIdempotencyKey(payload: WireStartPayload, jobId: st
|
|
|
78
78
|
* single-connection database that is a deadlock. An existing queue is left
|
|
79
79
|
* alone, cache entry and all.
|
|
80
80
|
*/
|
|
81
|
-
declare function ensureStepQueue(boss: PgBoss, queueName: string, config?: StepQueueConfig): Promise<void>;
|
|
82
|
-
interface PgBossDispatcherDeps {
|
|
81
|
+
export declare function ensureStepQueue(boss: PgBoss, queueName: string, config?: StepQueueConfig): Promise<void>;
|
|
82
|
+
export interface PgBossDispatcherDeps {
|
|
83
83
|
boss: PgBoss;
|
|
84
84
|
queueName: string;
|
|
85
85
|
/** Partition this dispatcher is bound to — stamped into every enqueued job. */
|
|
@@ -87,8 +87,8 @@ interface PgBossDispatcherDeps {
|
|
|
87
87
|
config?: StepQueueConfig;
|
|
88
88
|
}
|
|
89
89
|
/** A flow-core `Dispatcher` backed by pg-boss. */
|
|
90
|
-
declare function createPgBossDispatcher(deps: PgBossDispatcherDeps): Dispatcher;
|
|
91
|
-
interface PgBossStepWorkerOptions {
|
|
90
|
+
export declare function createPgBossDispatcher(deps: PgBossDispatcherDeps): Dispatcher;
|
|
91
|
+
export interface PgBossStepWorkerOptions {
|
|
92
92
|
/** Steps fetched per poll. Default 1. */
|
|
93
93
|
batchSize?: number;
|
|
94
94
|
/** Base poll interval in seconds (pg-boss minimum 0.5). Default: pg-boss's own. */
|
|
@@ -118,7 +118,7 @@ interface PgBossStepWorkerOptions {
|
|
|
118
118
|
*/
|
|
119
119
|
concurrency?: number;
|
|
120
120
|
}
|
|
121
|
-
interface PgBossStepWorkerDeps {
|
|
121
|
+
export interface PgBossStepWorkerDeps {
|
|
122
122
|
boss: PgBoss;
|
|
123
123
|
queueName: string;
|
|
124
124
|
config?: StepQueueConfig;
|
|
@@ -127,13 +127,13 @@ interface PgBossStepWorkerDeps {
|
|
|
127
127
|
}
|
|
128
128
|
/** Handles a single step job. Reconstruct the partition-scoped engine and call
|
|
129
129
|
* `engine.executeStep(workflowId, stepId)`. Throw to trigger a pg-boss retry. */
|
|
130
|
-
type StepJobProcessor = (payload: WireStepPayload) => Promise<void>;
|
|
130
|
+
export type StepJobProcessor = (payload: WireStepPayload) => Promise<void>;
|
|
131
131
|
/** A pg-boss worker that drives `executeStep` for step jobs. */
|
|
132
|
-
declare function createPgBossStepWorker(deps: PgBossStepWorkerDeps): {
|
|
132
|
+
export declare function createPgBossStepWorker(deps: PgBossStepWorkerDeps): {
|
|
133
133
|
start: (process: StepJobProcessor) => Promise<void>;
|
|
134
134
|
stop: () => Promise<void>;
|
|
135
135
|
};
|
|
136
|
-
interface PgBossDlqWorkerDeps {
|
|
136
|
+
export interface PgBossDlqWorkerDeps {
|
|
137
137
|
boss: PgBoss;
|
|
138
138
|
queueName: string;
|
|
139
139
|
logger?: Logger;
|
|
@@ -141,17 +141,17 @@ interface PgBossDlqWorkerDeps {
|
|
|
141
141
|
}
|
|
142
142
|
/** Invoked for a step job that exhausted all retries. Typically calls
|
|
143
143
|
* `engine.handleStepExhausted(workflowId, stepId, reason)`. */
|
|
144
|
-
type DlqProcessor = (payload: WireStepPayload) => Promise<void>;
|
|
144
|
+
export type DlqProcessor = (payload: WireStepPayload) => Promise<void>;
|
|
145
145
|
/** A pg-boss worker on the step queue's dead-letter queue. */
|
|
146
|
-
declare function createPgBossDlqWorker(deps: PgBossDlqWorkerDeps): {
|
|
146
|
+
export declare function createPgBossDlqWorker(deps: PgBossDlqWorkerDeps): {
|
|
147
147
|
start: (onDlq: DlqProcessor) => Promise<void>;
|
|
148
148
|
stop: () => Promise<void>;
|
|
149
149
|
};
|
|
150
150
|
//#endregion
|
|
151
151
|
//#region src/dispatcher-pgboss/scheduler.d.ts
|
|
152
152
|
/** Create the start queue (idempotent). */
|
|
153
|
-
declare function ensureStartQueue(boss: PgBoss, queueName: string): Promise<void>;
|
|
154
|
-
interface PgBossSchedulerDeps {
|
|
153
|
+
export declare function ensureStartQueue(boss: PgBoss, queueName: string): Promise<void>;
|
|
154
|
+
export interface PgBossSchedulerDeps {
|
|
155
155
|
boss: PgBoss;
|
|
156
156
|
/** Queue scheduled start jobs are sent to (and the start worker reads). */
|
|
157
157
|
queueName: string;
|
|
@@ -159,7 +159,7 @@ interface PgBossSchedulerDeps {
|
|
|
159
159
|
partitionKey: string;
|
|
160
160
|
logger?: Logger;
|
|
161
161
|
}
|
|
162
|
-
interface ScheduleStartInput {
|
|
162
|
+
export interface ScheduleStartInput {
|
|
163
163
|
/** Unique key for this schedule within the queue (allows many crons per queue). */
|
|
164
164
|
key: string;
|
|
165
165
|
/** Cron expression (5- or 6-field). */
|
|
@@ -187,7 +187,7 @@ interface ScheduleStartInput {
|
|
|
187
187
|
tz?: string;
|
|
188
188
|
}
|
|
189
189
|
/** Registers cron schedules that enqueue workflow-start jobs. */
|
|
190
|
-
declare function createPgBossScheduler(deps: PgBossSchedulerDeps): {
|
|
190
|
+
export declare function createPgBossScheduler(deps: PgBossSchedulerDeps): {
|
|
191
191
|
/** Create or replace a cron schedule that starts a workflow. */
|
|
192
192
|
schedule(input: ScheduleStartInput): Promise<void>;
|
|
193
193
|
/** Remove a schedule by key. */
|
|
@@ -208,8 +208,8 @@ declare function createPgBossScheduler(deps: PgBossSchedulerDeps): {
|
|
|
208
208
|
* });
|
|
209
209
|
* ```
|
|
210
210
|
*/
|
|
211
|
-
type StartJobProcessor = (payload: StartJobContext) => Promise<void>;
|
|
212
|
-
interface PgBossStartWorkerDeps {
|
|
211
|
+
export type StartJobProcessor = (payload: StartJobContext) => Promise<void>;
|
|
212
|
+
export interface PgBossStartWorkerDeps {
|
|
213
213
|
boss: PgBoss;
|
|
214
214
|
queueName: string;
|
|
215
215
|
logger?: Logger;
|
|
@@ -219,9 +219,8 @@ interface PgBossStartWorkerDeps {
|
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
221
|
/** A pg-boss worker on the start queue that drives a host start callback. */
|
|
222
|
-
declare function createPgBossStartWorker(deps: PgBossStartWorkerDeps): {
|
|
222
|
+
export declare function createPgBossStartWorker(deps: PgBossStartWorkerDeps): {
|
|
223
223
|
start: (process: StartJobProcessor) => Promise<void>;
|
|
224
224
|
stop: () => Promise<void>;
|
|
225
225
|
};
|
|
226
|
-
//#endregion
|
|
227
|
-
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 };
|
|
226
|
+
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { a as WorkflowCompletedArgs, i as BuildStepContextArgs, n as BeforeStart
|
|
|
9
9
|
* Populate it at application startup (e.g. by registering every workflow's steps).
|
|
10
10
|
* Each registration carries the handler plus its optional retry/timeout policy.
|
|
11
11
|
*/
|
|
12
|
-
declare function createStepHandlerRegistry<TContext = unknown>(): StepHandlerRegistry<TContext>;
|
|
12
|
+
export declare function createStepHandlerRegistry<TContext = unknown>(): StepHandlerRegistry<TContext>;
|
|
13
13
|
//#endregion
|
|
14
14
|
//#region src/core/retry.d.ts
|
|
15
15
|
/**
|
|
@@ -21,11 +21,11 @@ declare function createStepHandlerRegistry<TContext = unknown>(): StepHandlerReg
|
|
|
21
21
|
* throw markRetryable(await client.readError(), true);
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
declare function markRetryable<E>(error: E, retryable?: boolean): E;
|
|
24
|
+
export declare function markRetryable<E>(error: E, retryable?: boolean): E;
|
|
25
25
|
/** An error the engine will always retry (within the step's attempt budget). */
|
|
26
|
-
declare function retryableError(message: string, options?: ErrorOptions): Error;
|
|
26
|
+
export declare function retryableError(message: string, options?: ErrorOptions): Error;
|
|
27
27
|
/** An error the engine will never retry, whatever its message says. */
|
|
28
|
-
declare function nonRetryableError(message: string, options?: ErrorOptions): Error;
|
|
28
|
+
export declare function nonRetryableError(message: string, options?: ErrorOptions): Error;
|
|
29
29
|
/**
|
|
30
30
|
* The explicit decision carried by an error, or `undefined` if it carries none.
|
|
31
31
|
* Callers deciding retryability themselves should consult this first.
|
|
@@ -35,7 +35,7 @@ declare function nonRetryableError(message: string, options?: ErrorOptions): Err
|
|
|
35
35
|
* still reports `true`. The outermost decision wins; the walk is depth-capped and
|
|
36
36
|
* cycle-safe.
|
|
37
37
|
*/
|
|
38
|
-
declare function explicitRetryability(error: unknown): boolean | undefined;
|
|
38
|
+
export declare function explicitRetryability(error: unknown): boolean | undefined;
|
|
39
39
|
/**
|
|
40
40
|
* Default classifier for a thrown error, used when nothing more specific applies.
|
|
41
41
|
* Checked in order:
|
|
@@ -51,10 +51,10 @@ declare function explicitRetryability(error: unknown): boolean | undefined;
|
|
|
51
51
|
* {@link nonRetryableError}, `defineStep`'s `isRetryable`, or the engine's
|
|
52
52
|
* `defaultRetryable` when the answer matters.
|
|
53
53
|
*/
|
|
54
|
-
declare function isRetryableError(error: unknown): boolean;
|
|
54
|
+
export declare function isRetryableError(error: unknown): boolean;
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region src/core/engine.d.ts
|
|
57
|
-
interface WorkflowEngineConfig {
|
|
57
|
+
export interface WorkflowEngineConfig {
|
|
58
58
|
/** The dispatcher's per-step expiry, in seconds. Used by the stuck-step sweeper. Default 600. */
|
|
59
59
|
stepExpirySeconds?: number;
|
|
60
60
|
/** Extra grace added to the stuck threshold beyond `stepExpirySeconds`. Default 300. */
|
|
@@ -82,7 +82,7 @@ interface WorkflowEngineConfig {
|
|
|
82
82
|
*/
|
|
83
83
|
defaultRetryable?: boolean;
|
|
84
84
|
}
|
|
85
|
-
interface WorkflowEngineDeps<TContext = unknown> {
|
|
85
|
+
export interface WorkflowEngineDeps<TContext = unknown> {
|
|
86
86
|
store: WorkflowStore;
|
|
87
87
|
dispatcher: Dispatcher;
|
|
88
88
|
registry: StepHandlerRegistry<TContext>;
|
|
@@ -104,7 +104,7 @@ interface WorkflowEngineDeps<TContext = unknown> {
|
|
|
104
104
|
now?: () => Date;
|
|
105
105
|
}
|
|
106
106
|
/** What one sweep of `recoverStuckWorkflows` did. */
|
|
107
|
-
interface RecoverySweepResult {
|
|
107
|
+
export interface RecoverySweepResult {
|
|
108
108
|
/** Stuck steps put back on the queue for another attempt. */
|
|
109
109
|
retriedSteps: number;
|
|
110
110
|
/** Stuck steps failed outright — attempt budget spent, or `onStuckStep: 'fail'`. */
|
|
@@ -115,12 +115,12 @@ interface RecoverySweepResult {
|
|
|
115
115
|
expiredWorkflows: number;
|
|
116
116
|
}
|
|
117
117
|
/** What `retryWorkflow` put back in flight. */
|
|
118
|
-
interface RetryWorkflowResult {
|
|
118
|
+
export interface RetryWorkflowResult {
|
|
119
119
|
workflowId: WorkflowId;
|
|
120
120
|
/** Keys of the steps reset to `pending` — the work that will run again. */
|
|
121
121
|
resetSteps: string[];
|
|
122
122
|
}
|
|
123
|
-
declare function createWorkflowEngine<TContext = unknown>(deps: WorkflowEngineDeps<TContext>): {
|
|
123
|
+
export declare function createWorkflowEngine<TContext = unknown>(deps: WorkflowEngineDeps<TContext>): {
|
|
124
124
|
validateDefinition: (definition: WorkflowDefinition) => Result<void, FlowError>;
|
|
125
125
|
startWorkflow: (definition: WorkflowDefinition, input: Record<string, unknown>, options?: StartOptions) => Promise<Result<WorkflowCreatedResult, FlowError>>;
|
|
126
126
|
start: <TInput extends Record<string, unknown>>(workflow: {
|
|
@@ -145,7 +145,7 @@ declare function createWorkflowEngine<TContext = unknown>(deps: WorkflowEngineDe
|
|
|
145
145
|
limit?: number;
|
|
146
146
|
}) => Promise<Result<WorkflowWithSteps[], FlowError>>;
|
|
147
147
|
};
|
|
148
|
-
type WorkflowEngine<TContext = unknown> = ReturnType<typeof createWorkflowEngine<TContext>>;
|
|
148
|
+
export type WorkflowEngine<TContext = unknown> = ReturnType<typeof createWorkflowEngine<TContext>>;
|
|
149
149
|
//#endregion
|
|
150
150
|
//#region src/core/in-memory-store.d.ts
|
|
151
151
|
/**
|
|
@@ -154,7 +154,7 @@ type WorkflowEngine<TContext = unknown> = ReturnType<typeof createWorkflowEngine
|
|
|
154
154
|
* mirror real adapters (the partition value is recorded but isolation is trivial
|
|
155
155
|
* since each instance owns its own maps).
|
|
156
156
|
*/
|
|
157
|
-
declare function createInMemoryWorkflowStore(partitionKey?: string): WorkflowStore & {
|
|
157
|
+
export declare function createInMemoryWorkflowStore(partitionKey?: string): WorkflowStore & {
|
|
158
158
|
/** Test helper: read everything currently stored. */
|
|
159
159
|
_dump(): {
|
|
160
160
|
workflows: WorkflowRecord[];
|
|
@@ -162,4 +162,4 @@ declare function createInMemoryWorkflowStore(partitionKey?: string): WorkflowSto
|
|
|
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,
|
|
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 };
|
package/dist/store-pg/index.d.ts
CHANGED
|
@@ -9,15 +9,15 @@ import { Pool } from "pg";
|
|
|
9
9
|
* `partition_key` is the generic multi-tenancy column (the engine/store are bound
|
|
10
10
|
* to one partition). Add Row Level Security on top if you need hard isolation.
|
|
11
11
|
*/
|
|
12
|
-
declare function flowStoreDdl(schema?: string): string;
|
|
12
|
+
export declare function flowStoreDdl(schema?: string): string;
|
|
13
13
|
/** Default-schema DDL string. */
|
|
14
|
-
declare const FLOW_STORE_DDL: string;
|
|
14
|
+
export declare const FLOW_STORE_DDL: string;
|
|
15
15
|
/** `CREATE SCHEMA IF NOT EXISTS` line for non-default schemas; empty for 'public'. */
|
|
16
|
-
declare function createSchemaDdl(schema: string): string;
|
|
16
|
+
export declare function createSchemaDdl(schema: string): string;
|
|
17
17
|
//#endregion
|
|
18
18
|
//#region src/store-pg/executor.d.ts
|
|
19
19
|
/** Minimal query result shape the adapters consume (a structural subset of `pg`'s `QueryResult`). */
|
|
20
|
-
interface SqlResult<R> {
|
|
20
|
+
export interface SqlResult<R> {
|
|
21
21
|
rows: R[];
|
|
22
22
|
rowCount: number | null;
|
|
23
23
|
}
|
|
@@ -31,7 +31,7 @@ interface SqlResult<R> {
|
|
|
31
31
|
* DB transaction; the passed executor is that same-connection handle. Adapters
|
|
32
32
|
* never nest transactions.
|
|
33
33
|
*/
|
|
34
|
-
interface SqlExecutor {
|
|
34
|
+
export interface SqlExecutor {
|
|
35
35
|
query<R = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<SqlResult<R>>;
|
|
36
36
|
transaction<T>(fn: (tx: SqlExecutor) => Promise<T>): Promise<T>;
|
|
37
37
|
}
|
|
@@ -41,24 +41,24 @@ interface SqlExecutor {
|
|
|
41
41
|
* `BEGIN`/`COMMIT` (rolling back and always releasing on error). This is the
|
|
42
42
|
* batteries-included executor used by the `createPg*` adapters.
|
|
43
43
|
*/
|
|
44
|
-
declare function poolExecutor(pool: Pool): SqlExecutor;
|
|
44
|
+
export declare function poolExecutor(pool: Pool): SqlExecutor;
|
|
45
45
|
/**
|
|
46
46
|
* Normalize a `Pool | SqlExecutor` argument to a {@link SqlExecutor}. Lets the
|
|
47
47
|
* read helpers accept either the batteries-included pool or a host's RLS-scoped
|
|
48
48
|
* executor without a breaking signature change. `SqlExecutor` is discriminated by
|
|
49
49
|
* its `transaction` method (a `pg` `Pool` has none).
|
|
50
50
|
*/
|
|
51
|
-
declare function toExecutor(db: Pool | SqlExecutor): SqlExecutor;
|
|
51
|
+
export declare function toExecutor(db: Pool | SqlExecutor): SqlExecutor;
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region src/store-pg/store.d.ts
|
|
54
|
-
interface PgWorkflowStoreDeps {
|
|
54
|
+
export interface PgWorkflowStoreDeps {
|
|
55
55
|
pool: Pool;
|
|
56
56
|
/** Partition this store instance is bound to (e.g. a tenant id). */
|
|
57
57
|
partitionKey: string;
|
|
58
58
|
/** Schema the flow tables live in. Default 'public'. */
|
|
59
59
|
schema?: string;
|
|
60
60
|
}
|
|
61
|
-
interface WorkflowStoreDeps {
|
|
61
|
+
export interface WorkflowStoreDeps {
|
|
62
62
|
/** How the store talks to Postgres (pool-backed, RLS-scoped, …). */
|
|
63
63
|
exec: SqlExecutor;
|
|
64
64
|
/** Partition this store instance is bound to (e.g. a tenant id). */
|
|
@@ -76,7 +76,7 @@ interface WorkflowStoreDeps {
|
|
|
76
76
|
* plain pool; a host that wants Row Level Security injects an executor whose
|
|
77
77
|
* `transaction` sets the tenant GUC, so the store's own transactions run scoped.
|
|
78
78
|
*/
|
|
79
|
-
declare function createWorkflowStore(deps: WorkflowStoreDeps): WorkflowStore;
|
|
79
|
+
export declare function createWorkflowStore(deps: WorkflowStoreDeps): WorkflowStore;
|
|
80
80
|
/**
|
|
81
81
|
* A `WorkflowStore` backed by a `pg` {@link Pool} — the batteries-included
|
|
82
82
|
* adapter that owns its own connections/transactions (via {@link poolExecutor})
|
|
@@ -84,20 +84,20 @@ declare function createWorkflowStore(deps: WorkflowStoreDeps): WorkflowStore;
|
|
|
84
84
|
* that need Row Level Security or their own migrations should instead build an
|
|
85
85
|
* executor and call {@link createWorkflowStore}.
|
|
86
86
|
*/
|
|
87
|
-
declare function createPgWorkflowStore(deps: PgWorkflowStoreDeps): WorkflowStore;
|
|
87
|
+
export declare function createPgWorkflowStore(deps: PgWorkflowStoreDeps): WorkflowStore;
|
|
88
88
|
/** Convenience: apply the flow-store schema to a database. */
|
|
89
|
-
declare function applySchema(pool: Pool, ddl: string): Promise<void>;
|
|
89
|
+
export declare function applySchema(pool: Pool, ddl: string): Promise<void>;
|
|
90
90
|
//#endregion
|
|
91
91
|
//#region src/store-pg/gate.d.ts
|
|
92
92
|
/** DDL for the gate's two tables. Apply once at deploy time (or via `applySchema`). */
|
|
93
|
-
declare function flowGateDdl(opts?: {
|
|
93
|
+
export declare function flowGateDdl(opts?: {
|
|
94
94
|
schema?: string;
|
|
95
95
|
rateBucketTable?: string;
|
|
96
96
|
leaseTable?: string;
|
|
97
97
|
}): string;
|
|
98
98
|
/** Default-schema gate DDL string. */
|
|
99
|
-
declare const FLOW_GATE_DDL: string;
|
|
100
|
-
interface PgStepGateConfig {
|
|
99
|
+
export declare const FLOW_GATE_DDL: string;
|
|
100
|
+
export interface PgStepGateConfig {
|
|
101
101
|
pool: Pool;
|
|
102
102
|
/** Partition this gate is bound to (matches the engine/store partition). */
|
|
103
103
|
partitionKey: string;
|
|
@@ -117,7 +117,7 @@ interface PgStepGateConfig {
|
|
|
117
117
|
lease?: string;
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
|
-
interface StepGateConfig extends Omit<PgStepGateConfig, 'pool'> {
|
|
120
|
+
export interface StepGateConfig extends Omit<PgStepGateConfig, 'pool'> {
|
|
121
121
|
/** How the gate talks to Postgres (pool-backed, RLS-scoped, …). */
|
|
122
122
|
exec: SqlExecutor;
|
|
123
123
|
}
|
|
@@ -128,30 +128,30 @@ interface StepGateConfig extends Omit<PgStepGateConfig, 'pool'> {
|
|
|
128
128
|
* Global concurrency caps + rate limits shared across all workers; drop-in for
|
|
129
129
|
* the in-memory gate via `WorkflowEngineDeps.gate`.
|
|
130
130
|
*/
|
|
131
|
-
declare function createStepGate(config: StepGateConfig): StepGate;
|
|
131
|
+
export declare function createStepGate(config: StepGateConfig): StepGate;
|
|
132
132
|
/**
|
|
133
133
|
* A Postgres-backed {@link StepGate} over a `pg` {@link Pool} — the
|
|
134
134
|
* batteries-included adapter (via {@link poolExecutor}). Hosts that need Row
|
|
135
135
|
* Level Security should build an executor and call {@link createStepGate}.
|
|
136
136
|
*/
|
|
137
|
-
declare function createPgStepGate(config: PgStepGateConfig): StepGate;
|
|
137
|
+
export declare function createPgStepGate(config: PgStepGateConfig): StepGate;
|
|
138
138
|
//#endregion
|
|
139
139
|
//#region src/store-pg/event-sink.d.ts
|
|
140
140
|
/**
|
|
141
141
|
* DDL for the append-only run-history table. Apply once at deploy time (alongside
|
|
142
142
|
* `flowStoreDdl`), or call `applySchema(pool, flowEventDdl())`.
|
|
143
143
|
*/
|
|
144
|
-
declare function flowEventDdl(schema?: string): string;
|
|
144
|
+
export declare function flowEventDdl(schema?: string): string;
|
|
145
145
|
/** Default-schema event-table DDL string. */
|
|
146
|
-
declare const FLOW_EVENT_DDL: string;
|
|
147
|
-
interface PgEventSinkDeps {
|
|
146
|
+
export declare const FLOW_EVENT_DDL: string;
|
|
147
|
+
export interface PgEventSinkDeps {
|
|
148
148
|
pool: Pool;
|
|
149
149
|
/** Partition this sink is bound to (e.g. a tenant id). */
|
|
150
150
|
partitionKey: string;
|
|
151
151
|
/** Schema the flow tables live in. Default 'public'. */
|
|
152
152
|
schema?: string;
|
|
153
153
|
}
|
|
154
|
-
interface EventSinkDeps {
|
|
154
|
+
export interface EventSinkDeps {
|
|
155
155
|
/** How the sink talks to Postgres (pool-backed, RLS-scoped, …). */
|
|
156
156
|
exec: SqlExecutor;
|
|
157
157
|
/** Partition this sink is bound to (e.g. a tenant id). */
|
|
@@ -164,7 +164,7 @@ interface EventSinkDeps {
|
|
|
164
164
|
* fire-and-forget (it never throws and never blocks the engine); call `flush()` to await the
|
|
165
165
|
* in-flight inserts — useful in tests and before shutdown.
|
|
166
166
|
*/
|
|
167
|
-
interface PgEventSink extends FlowObserver {
|
|
167
|
+
export interface PgEventSink extends FlowObserver {
|
|
168
168
|
flush(): Promise<void>;
|
|
169
169
|
}
|
|
170
170
|
/**
|
|
@@ -174,22 +174,21 @@ interface PgEventSink extends FlowObserver {
|
|
|
174
174
|
* `record` is fire-and-forget (never throws, never blocks the engine); `flush()`
|
|
175
175
|
* awaits the in-flight inserts.
|
|
176
176
|
*/
|
|
177
|
-
declare function createEventSink(deps: EventSinkDeps): PgEventSink;
|
|
177
|
+
export declare function createEventSink(deps: EventSinkDeps): PgEventSink;
|
|
178
178
|
/**
|
|
179
179
|
* A `FlowObserver` backed by a `pg` {@link Pool} — the batteries-included sink
|
|
180
180
|
* (via {@link poolExecutor}). Hosts that need Row Level Security should build an
|
|
181
181
|
* executor and call {@link createEventSink} instead.
|
|
182
182
|
*/
|
|
183
|
-
declare function createPgEventSink(deps: PgEventSinkDeps): PgEventSink;
|
|
183
|
+
export declare function createPgEventSink(deps: PgEventSinkDeps): PgEventSink;
|
|
184
184
|
/**
|
|
185
185
|
* Read a workflow's run history, ordered oldest-first. Accepts either a
|
|
186
186
|
* `pg` {@link Pool} (batteries-included) or a host's {@link SqlExecutor} (e.g.
|
|
187
187
|
* RLS-scoped) — both route through the same seam.
|
|
188
188
|
*/
|
|
189
|
-
declare function readFlowEvents(db: Pool | SqlExecutor, params: {
|
|
189
|
+
export declare function readFlowEvents(db: Pool | SqlExecutor, params: {
|
|
190
190
|
workflowId: WorkflowId;
|
|
191
191
|
partitionKey: string;
|
|
192
192
|
schema?: string;
|
|
193
193
|
}): Promise<FlowEvent[]>;
|
|
194
|
-
//#endregion
|
|
195
|
-
export { EventSinkDeps, FLOW_EVENT_DDL, FLOW_GATE_DDL, FLOW_STORE_DDL, PgEventSink, PgEventSinkDeps, PgStepGateConfig, PgWorkflowStoreDeps, SqlExecutor, SqlResult, StepGateConfig, WorkflowStoreDeps, applySchema, createEventSink, createPgEventSink, createPgStepGate, createPgWorkflowStore, createSchemaDdl, createStepGate, createWorkflowStore, flowEventDdl, flowGateDdl, flowStoreDdl, poolExecutor, readFlowEvents, toExecutor };
|
|
194
|
+
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "octaflow",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.3",
|
|
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,9 +29,6 @@
|
|
|
29
29
|
"engines": {
|
|
30
30
|
"node": ">=22"
|
|
31
31
|
},
|
|
32
|
-
"simple-git-hooks": {
|
|
33
|
-
"commit-msg": "pnpm commitlint --edit $1"
|
|
34
|
-
},
|
|
35
32
|
"files": [
|
|
36
33
|
"dist",
|
|
37
34
|
"README.md",
|
|
@@ -42,11 +39,12 @@
|
|
|
42
39
|
},
|
|
43
40
|
"repository": {
|
|
44
41
|
"type": "git",
|
|
45
|
-
"url": "https://github.com/octabits-io/
|
|
42
|
+
"url": "https://github.com/octabits-io/octabits.git",
|
|
43
|
+
"directory": "packages/octaflow"
|
|
46
44
|
},
|
|
47
45
|
"homepage": "https://octaflow.octabits.io/",
|
|
48
46
|
"bugs": {
|
|
49
|
-
"url": "https://github.com/octabits-io/
|
|
47
|
+
"url": "https://github.com/octabits-io/octabits/issues"
|
|
50
48
|
},
|
|
51
49
|
"keywords": [
|
|
52
50
|
"workflow",
|
|
@@ -82,22 +80,17 @@
|
|
|
82
80
|
}
|
|
83
81
|
},
|
|
84
82
|
"devDependencies": {
|
|
85
|
-
"@ai-sdk/provider": "^4.0.
|
|
86
|
-
"@changesets/changelog-github": "^1.0.0",
|
|
87
|
-
"@changesets/cli": "^3.0.1",
|
|
88
|
-
"@commitlint/cli": "^21.2.2",
|
|
89
|
-
"@commitlint/config-conventional": "^21.2.2",
|
|
83
|
+
"@ai-sdk/provider": "^4.0.10",
|
|
90
84
|
"@testcontainers/postgresql": "^12.1.0",
|
|
91
|
-
"@types/node": "^26.4.
|
|
85
|
+
"@types/node": "^26.4.1",
|
|
92
86
|
"@types/pg": "^8.23.1",
|
|
93
|
-
"ai": "^7.0.
|
|
87
|
+
"ai": "^7.0.93",
|
|
94
88
|
"pg": "^8.23.0",
|
|
95
|
-
"pg-boss": "^12.
|
|
96
|
-
"simple-git-hooks": "^2.14.0",
|
|
89
|
+
"pg-boss": "^12.30.0",
|
|
97
90
|
"testcontainers": "^12.1.0",
|
|
98
|
-
"tsdown": "^0.
|
|
91
|
+
"tsdown": "^0.23.0",
|
|
99
92
|
"typescript": "^7.0.2",
|
|
100
|
-
"vitest": "^
|
|
93
|
+
"vitest": "^5.0.0",
|
|
101
94
|
"zod": "^4.5.4"
|
|
102
95
|
},
|
|
103
96
|
"scripts": {
|
|
@@ -107,10 +100,6 @@
|
|
|
107
100
|
"test:unit": "vitest run --project unit",
|
|
108
101
|
"test:integration": "vitest run --project integration",
|
|
109
102
|
"lint": "node scripts/check-boundaries.mjs",
|
|
110
|
-
"typecheck": "tsc --noEmit"
|
|
111
|
-
"changeset": "changeset",
|
|
112
|
-
"changeset:version": "GITHUB_TOKEN=$(passage show github/token) changeset version",
|
|
113
|
-
"changeset:publish": "pnpm build && echo \"//registry.npmjs.org/:_authToken=$(passage show npm/token/octabits)\" > .npmrc && { changeset publish; s=$?; rm -f .npmrc; exit $s; }",
|
|
114
|
-
"release": "bash scripts/release.sh"
|
|
103
|
+
"typecheck": "tsc --noEmit"
|
|
115
104
|
}
|
|
116
105
|
}
|