octaflow 0.35.0 → 0.36.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.
Files changed (37) hide show
  1. package/README.md +9 -79
  2. package/dist/{core-COMWflJl.js → core-YqnPwR-v.js} +109 -1
  3. package/dist/{dispatcher-BQErUGy_.d.ts → dispatcher-ltwBJjKc.d.ts} +10 -1
  4. package/dist/drizzle/index.d.ts +0 -103
  5. package/dist/drizzle/index.js +2 -105
  6. package/dist/index.d.ts +56 -4
  7. package/dist/index.js +18 -3
  8. package/dist/pg-boss/index.d.ts +1 -2
  9. package/dist/postgres/index.d.ts +0 -58
  10. package/dist/postgres/index.js +2 -363
  11. package/package.json +2 -63
  12. package/skills/add-a-case-loop/SKILL.md +1 -1
  13. package/skills/add-a-decision/SKILL.md +1 -1
  14. package/skills/add-an-ai-proposal-workflow/SKILL.md +8 -6
  15. package/bin/octaflow-runner.mjs +0 -209
  16. package/dist/ai/index.d.ts +0 -1018
  17. package/dist/ai/index.js +0 -1828
  18. package/dist/ai/providers/index.d.ts +0 -326
  19. package/dist/ai/providers/index.js +0 -1035
  20. package/dist/ai/registry.d.ts +0 -2
  21. package/dist/ai/registry.js +0 -1
  22. package/dist/ai/runner/index.d.ts +0 -138
  23. package/dist/ai/runner/index.js +0 -803
  24. package/dist/gate-BRq-t3K_.js +0 -109
  25. package/dist/hooks-DHomzpiq.d.ts +0 -56
  26. package/dist/hub-CTf95SkP.d.ts +0 -125
  27. package/dist/logger-BCus3AOa.d.ts +0 -10
  28. package/dist/logger-epkdcXDA.js +0 -18
  29. package/dist/model-DztyiOGz.js +0 -274
  30. package/dist/model-providers-DQU57vAf.d.ts +0 -212
  31. package/dist/model-runner-2ONkybAq.d.ts +0 -194
  32. package/dist/provider-errors-DZWjl8di.js +0 -422
  33. package/dist/provider-probe-BDg4c1Rk.d.ts +0 -187
  34. package/dist/provider-probe-CwZWwFlo.js +0 -271
  35. package/dist/provider-registry-B91lgOmu.js +0 -217
  36. package/dist/provider-registry-C_mOfdHH.d.ts +0 -134
  37. package/skills/serve-a-model-from-a-runner/SKILL.md +0 -154
package/README.md CHANGED
@@ -202,7 +202,6 @@ next to what your steps actually do.
202
202
  | 💤 | **Durable sleep** — hold a step in the queue for N ms (survives restarts) |
203
203
  | 🔀 | **Conditional branching** — `when` guards skip a step and its branch; `join: 'any'` converges |
204
204
  | 🎯 | **Decisions** — typed choices with a confidence from a swappable decider (a function, a model, your own); below a threshold a person settles it |
205
- | 🧭 | **Case loops** — `defineCaseLoop` (`octaflow/ai`): a manager agent chooses every next move of a case, each move its own workflow ending in the same tail (result → decide → next); policy refuses a choice with its reason inside the exit's schema, a move with a step that could fail is refused at definition time, and a manager that cannot decide closes the case for a person |
206
205
  | ⏳ | **Deadlines** — a budget on a suspended step (fail, or continue with a stand-in answer) and on a whole run |
207
206
  | ♻️ | **Retry a failed run** — `retryWorkflow` resumes from the failure point; completed steps keep their output |
208
207
  | 🧹 | **Delete the runs about a record** — `purgeWorkflows({ entityRef })` cancels and deletes them with their sub-workflow runs and steps, for an erasure or a deleted record; refuses only while a step is executing |
@@ -216,9 +215,7 @@ next to what your steps actually do.
216
215
  | 🚑 | **Crash recovery** — a step whose worker died is re-queued while its attempt budget lasts |
217
216
  | 💓 | **Heartbeats** — a long step proves it is alive, so a dead one is caught in seconds, not minutes |
218
217
  | 🔭 | **Observability** — lifecycle events (run history), per-step spans, and `createMeterObserver` turning the events into OpenTelemetry-style metrics — all pluggable, all structural |
219
- | 🤖 | **AI add-on** — instrumented models, token/cost capture, quota, daily rollups, a `usage` sink that books each step into `@octabits-io/metering` (the paid APIs around the model in the same table, priced at read time), refusal-aware models, lenient JSON from local models (`withJsonRepair`), a vendor's refusal explained by key and hint (`explainProviderError`), a per-run circuit breaker, a connection test (`testProvider`), Ollama's native API as language and embedding models (`createOllama` in `octaflow/ai/providers`: `num_ctx`, thinking and `keep_alive` per model or per call, no dependency) |
220
- | 🗂️ | **Model providers an administrator manages** — `createModelProviders` (`octaflow/ai`): providers as rows, each with its kind, server, region, a key that crosses a cipher seam, and its models with declared capabilities (temperature, JSON mode, vision, video, tools, embedding); `createPgModelProviderStore` + `modelProviderDdl` (`octaflow/postgres`), `modelProviderColumns` (`octaflow/drizzle`); `createModelResolver` (`octaflow/ai/providers`) builds the AI SDK model from a row, shapes each call to what the model declares, hands the host its `destination` for the disclosure guard, and rebuilds after a write |
221
- | 🏃 | **Model runners** — a model the app cannot reach, served by a process that connects *out*: a provider row of kind `runner` carries tags instead of a URL, a runner registered with a token (`octaflow/ai/runner`: `createModelRunnerHub`, shown once, kept as a hash) subscribes with its tags, claims the calls by long-poll through `@octabits-io/server/fetch/octaflow`'s `createModelRunnerHandler` and posts the answers back; the mailbox is three tables (`createPgModelRunnerStore` + `modelRunnerDdl`; `modelRunnerColumns`, `modelRunnerRequestColumns`, `modelRunnerChunkColumns`) whose rows live only while a call is in flight, a streamed answer's parts chunk by chunk among them; nobody online fails the call at once, so the breaker trips and the probe answers in milliseconds; `octaflow-runner` is the runner as a process (Ollama or any OpenAI-compatible server) |
218
+ | 🤖 | **The model layer** — AI steps with token and cost capture, quotas, the model decider, agents that end by choosing an exit, case loops, managed providers and model runners: [`@octabits-io/models`](../models/README.md) (`./octaflow` is its binding to this engine; it was `octaflow/ai` until 0.36) |
222
219
  | 🧱 | **Pluggable everything** — `WorkflowStore`, `Dispatcher`, `StepGate`, `FlowObserver`, hooks |
223
220
 
224
221
  ---
@@ -242,8 +239,8 @@ pnpm add drizzle-orm
242
239
  # pg-boss dispatcher, workers, cron scheduler
243
240
  pnpm add pg-boss
244
241
 
245
- # the AI add-on
246
- pnpm add ai @ai-sdk/provider
242
+ # the model layer on this engine: AI steps, agents, case loops (its ./octaflow subpath)
243
+ pnpm add @octabits-io/models ai @ai-sdk/provider
247
244
  ```
248
245
 
249
246
  > Pure in-memory usage (great for tests and single-process apps) needs **nothing** beyond
@@ -251,10 +248,10 @@ pnpm add ai @ai-sdk/provider
251
248
 
252
249
  ### The Postgres tables
253
250
 
254
- `octaflow/postgres` owns nine tables and ships their DDL: `flowStoreDdl()` (`flow_workflow`,
255
- `flow_workflow_step`), `flowEventDdl()` (`flow_step_event`), `flowGateDdl()`
256
- (`flow_rate_bucket`, `flow_step_lease`), `modelProviderDdl()` (`model_provider`) and
257
- `modelRunnerDdl()` (`model_runner`, `model_runner_request`, `model_runner_chunk`). Each is idempotent `CREATE TABLE IF NOT EXISTS`, takes
251
+ `octaflow/postgres` owns five tables and ships their DDL: `flowStoreDdl()` (`flow_workflow`,
252
+ `flow_workflow_step`), `flowEventDdl()` (`flow_step_event`) and `flowGateDdl()`
253
+ (`flow_rate_bucket`, `flow_step_lease`). The model providers' and runners' tables, here until
254
+ 0.36, are `@octabits-io/models/postgres`'s. Each is idempotent `CREATE TABLE IF NOT EXISTS`, takes
258
255
  a `schema`, and is meant to be pasted into your own migration system; `applySchema(pool, ddl)`
259
256
  is the dev and test shortcut.
260
257
 
@@ -272,8 +269,7 @@ column set, so a host on Drizzle declares it in its own schema and drizzle-kit o
272
269
  migration. Where the store's queries are one SQL statement by nature — every one of octaflow's
273
270
  is — `./drizzle` ships the columns only, and the store stays the SQL one. So
274
271
  `octaflow/drizzle` exports `flowWorkflowColumns`, `flowWorkflowStepColumns`,
275
- `flowStepEventColumns`, `flowRateBucketColumns`, `flowStepLeaseColumns`, `modelProviderColumns`,
276
- `modelRunnerColumns`, `modelRunnerRequestColumns` and `modelRunnerChunkColumns` (`drizzle-orm` an
272
+ `flowStepEventColumns`, `flowRateBucketColumns` and `flowStepLeaseColumns` (`drizzle-orm` an
277
273
  optional peer) and nothing that runs a query. The foreign keys, the composite keys, the unique
278
274
  constraint and the indexes are yours to declare on the `pgTable`; each column set's doc lists
279
275
  the ones its DDL creates, and two of them the store relies on:
@@ -318,71 +314,6 @@ The store stays plain SQL, bound to the `schema` you hand `createPgWorkflowStore
318
314
  declare the tables under the same schema and names. A test in the package holds every column
319
315
  set and its DDL equal, column for column: a column added to one side alone fails the build.
320
316
 
321
- ### Model runners — a model that connects out
322
-
323
- A model the app cannot reach: a laptop with the model loaded for a demo, a GPU box behind
324
- someone's firewall, a machine that is only on when it is needed. The runner never opens a
325
- port. It connects *out* to the app with a token, subscribes with its tags, claims the model
326
- calls that carry those tags and posts the answers back — the shape of a self-hosted CI
327
- runner. The mailbox is Postgres, because the call runs in the worker and the door the runner
328
- knocks on runs in the API; a request row lives only while the call is in flight.
329
-
330
- ```ts
331
- // the app — once, beside the providers
332
- import { createModelRunnerHub } from 'octaflow/ai/runner';
333
- import { createPgModelRunnerStore } from 'octaflow/postgres';
334
-
335
- const runners = createModelRunnerHub({ store: createPgModelRunnerStore({ executor }) });
336
- const resolver = createModelResolver({ providers, runners, wrap });
337
-
338
- // an administrator: the provider row carries tags, the runner gets its token once
339
- await providers.save({ id: 'mac', kind: 'runner', label: 'The Mac', region: 'self-hosted', tags: ['qwen'], models: [{ id: 'qwen3:32b', settings: { numCtx: 16_384 } }] });
340
- const { token } = (await runners.registerRunner({ id: 'dani-mac', label: "Dani's Mac", tags: ['qwen', 'mac'] })).value;
341
-
342
- // the API: the door, behind the host's rate limit
343
- import { createModelRunnerHandler } from '@octabits-io/server/fetch/octaflow';
344
- export const POST = compose(withErrorMapping())(createModelRunnerHandler({ prefix: '/api/model-runner', hub: runners }));
345
-
346
- // the runner, on the machine with the model — the bin, or the loop in your own process
347
- // npx octaflow-runner --url https://app.example/api/model-runner --token omr_… --ollama http://localhost:11434
348
- import { createHttpRunnerClient, runModelRunner } from 'octaflow/ai/runner';
349
- import { createOllama } from 'octaflow/ai/providers';
350
- await runModelRunner({
351
- client: createHttpRunnerClient({ url: 'https://app.example/api/model-runner', token }),
352
- backend: createOllama({ baseUrl: 'http://localhost:11434' }),
353
- });
354
- ```
355
-
356
- **`octaflow-runner`**, the bin, is the runner as a process: `--url` and `--token` (or
357
- `OCTAFLOW_RUNNER_URL` / `OCTAFLOW_RUNNER_TOKEN`), one backend — `--ollama <url>` for Ollama's
358
- native API, `--openai-compatible <url>` (with `--api-key`) for mlx_lm.server, vLLM or llama.cpp
359
- through the optional `@ai-sdk/openai-compatible` peer — and `--concurrency`. At start it says
360
- who the token belongs to, which models the app's provider rows declare for its tags (the door
361
- tells it) and which of them the local server has, with the `ollama pull` for a missing one;
362
- `--check` does that and exits. A door it cannot reach is retried with a backoff, forever.
363
- The skill `serve-a-model-from-a-runner` walks through the four pieces.
364
-
365
- A runner may claim a request when it has **every tag** of the request — the provider row's
366
- tags — as a CI job's labels must all be on the runner. A call with nobody online for its
367
- tags fails at once with `provider_unreachable`, so `withCircuitBreaker` trips and
368
- `testProvider` reports it in milliseconds instead of a timeout; whether another provider is
369
- tried is the host's resolver's choice, through the same disclosure gate. A claim lasts 30 s
370
- without a heartbeat; an expired claim is requeued once and failed the second time. The
371
- region is the administrator's declaration about where runners with these tags are, as for
372
- every provider, and the disclosure gate reads it the same way.
373
-
374
- The wire is the AI SDK's own call and answer as JSON — binary file data as base64, a URL
375
- restored on the other side — so the runner's backend is any `LanguageModelV4`: `createOllama`
376
- from this package, or `@ai-sdk/openai-compatible` for mlx_lm.server, vLLM and llama.cpp.
377
- `streamText` streams: the runner runs `doStream` and posts the parts in chunks as they come
378
- (every 100 ms, or 64 parts), a third table carries them, and the app emits each chunk as it
379
- lands; a chunk the door refuses tells the runner the caller gave up, and it cancels the
380
- stream. A runner on the older wire answers a stream whole, and the app emits that as parts
381
- too. Files reach the runner as bytes, since the runner model declares no URL support and the
382
- SDK downloads on the app's side. Embeddings go the same way.
383
-
384
- ---
385
-
386
317
  ---
387
318
 
388
319
  ## Documentation
@@ -405,7 +336,7 @@ Full docs — concepts, every feature, production wiring and the API reference
405
336
  | [Postgres & pg-boss](https://octaflow.octabits.io/running/postgres-and-pg-boss/) | production wiring, workers, DLQ, cron |
406
337
  | [Cancellation & recovery](https://octaflow.octabits.io/running/cancellation-and-recovery/) | cancelling a run, sweeping steps a crash left behind, retrying a failed run, and deleting the runs about a record |
407
338
  | [Observability](https://octaflow.octabits.io/running/observability/) · [Live progress](https://octaflow.octabits.io/running/live-progress/) | lifecycle events, spans, and streaming them to a browser |
408
- | [The AI add-on](https://octaflow.octabits.io/extending/ai/) | token/cost capture, quota, usage rollups |
339
+ | [The AI add-on](https://octaflow.octabits.io/extending/ai/) | token/cost capture, quota, usage rollups — `@octabits-io/models/octaflow` |
409
340
  | [Extending](https://octaflow.octabits.io/extending/interfaces/) | custom stores, dispatchers and gates |
410
341
  | [API reference](https://octaflow.octabits.io/reference/api/) | every export, by entry point |
411
342
 
@@ -429,7 +360,6 @@ Runnable, focused examples live in [`examples/`](./examples) — see [`examples/
429
360
  | 10 | `10-saga-compensation.ts` | reverse-order rollback on failure |
430
361
  | 11 | `11-observability.ts` | observer events + tracer spans |
431
362
  | 12 | `12-postgres-pgboss-production.ts` | full pg store + gate + event sink + pg-boss + cron |
432
- | 13 | `13-ai-workflow.ts` | AI add-on (instrumented model + cost) |
433
363
  | 14 | `14-live-progress.ts` | `FlowObserver` → SSE fan-out (build your own dashboard) |
434
364
  | 15 | `15-conditional-branching.ts` | `when` guards + a `join: 'any'` convergence |
435
365
  | 16 | `16-deadlines-and-retry.ts` | wait deadlines, run deadlines, `retryWorkflow`, heartbeats |
@@ -1,4 +1,112 @@
1
1
  import { z } from "zod";
2
+ //#region src/core/gate.ts
3
+ /**
4
+ * The rule keys a request is held to, in the order they are checked: the
5
+ * step's type, then each resource it declares, without repeats. The shipped
6
+ * gates look up their `concurrency` and `rateLimit` rules by these keys, so a
7
+ * rule keyed `'llm:local'` holds every step that names that resource, whatever
8
+ * its type, and a rule keyed by a type still holds that type alone. A custom
9
+ * gate that wants the same vocabulary calls this.
10
+ */
11
+ function gateRuleKeys(req) {
12
+ const keys = [req.stepType];
13
+ for (const resource of req.resources ?? []) if (!keys.includes(resource)) keys.push(resource);
14
+ return keys;
15
+ }
16
+ /**
17
+ * A per-process {@link StepGate}: concurrency caps (held slots) plus token-bucket
18
+ * rate limits (throughput), each keyed by a step type or by a resource a step
19
+ * declares ({@link gateRuleKeys}). Both are optional; a step none of whose keys
20
+ * has a rule is always admitted, and a step with several keys must pass every
21
+ * rule among them.
22
+ *
23
+ * Concurrency is reserved first, then the rate tokens — so a rate denial does not
24
+ * waste a concurrency slot, and a denial by a later rule gives back what earlier
25
+ * ones granted. Good for single-worker deployments; swap in a shared-store gate
26
+ * for multi-worker concurrency control.
27
+ */
28
+ function createInMemoryStepGate(config = {}) {
29
+ const now = config.now ?? (() => Date.now());
30
+ const concurrencyRetry = Math.max(1, config.concurrencyRetrySeconds ?? 1);
31
+ const running = /* @__PURE__ */ new Map();
32
+ const buckets = /* @__PURE__ */ new Map();
33
+ const capacityOf = (rule) => rule.burst ?? Math.max(1, Math.ceil(rule.perSecond));
34
+ function rateCheck(key) {
35
+ const rule = config.rateLimit?.[key];
36
+ if (!rule) return { ok: true };
37
+ const capacity = capacityOf(rule);
38
+ const tNow = now();
39
+ let b = buckets.get(key);
40
+ if (!b) {
41
+ b = {
42
+ tokens: capacity,
43
+ updatedMs: tNow
44
+ };
45
+ buckets.set(key, b);
46
+ }
47
+ const elapsedSec = Math.max(0, (tNow - b.updatedMs) / 1e3);
48
+ b.tokens = Math.min(capacity, b.tokens + elapsedSec * rule.perSecond);
49
+ b.updatedMs = tNow;
50
+ if (b.tokens >= 1) {
51
+ b.tokens -= 1;
52
+ return { ok: true };
53
+ }
54
+ const needed = 1 - b.tokens;
55
+ return {
56
+ ok: false,
57
+ retryAfterSeconds: Math.max(1, Math.ceil(needed / rule.perSecond))
58
+ };
59
+ }
60
+ /** Give back a token a denied request had already taken from an earlier bucket. */
61
+ function refund(key) {
62
+ const rule = config.rateLimit?.[key];
63
+ const b = buckets.get(key);
64
+ if (rule && b) b.tokens = Math.min(capacityOf(rule), b.tokens + 1);
65
+ }
66
+ return { async acquire(req) {
67
+ const keys = gateRuleKeys(req);
68
+ const held = [];
69
+ let released = false;
70
+ const release = () => {
71
+ if (released) return;
72
+ released = true;
73
+ for (const key of held) running.set(key, Math.max(0, (running.get(key) ?? 1) - 1));
74
+ };
75
+ for (const key of keys) {
76
+ const cRule = config.concurrency?.[key];
77
+ if (!cRule) continue;
78
+ const current = running.get(key) ?? 0;
79
+ if (current >= cRule.maxConcurrent) {
80
+ release();
81
+ return {
82
+ admitted: false,
83
+ retryAfterSeconds: concurrencyRetry
84
+ };
85
+ }
86
+ running.set(key, current + 1);
87
+ held.push(key);
88
+ }
89
+ const taken = [];
90
+ for (const key of keys) {
91
+ if (!config.rateLimit?.[key]) continue;
92
+ const rate = rateCheck(key);
93
+ if (!rate.ok) {
94
+ for (const t of taken) refund(t);
95
+ release();
96
+ return {
97
+ admitted: false,
98
+ retryAfterSeconds: rate.retryAfterSeconds
99
+ };
100
+ }
101
+ taken.push(key);
102
+ }
103
+ return {
104
+ admitted: true,
105
+ release
106
+ };
107
+ } };
108
+ }
109
+ //#endregion
2
110
  //#region src/core/retry.ts
3
111
  /**
4
112
  * Realm-safe marker for an explicit retryability decision. `Symbol.for` so a
@@ -882,4 +990,4 @@ function toPublicWorkflow(workflow) {
882
990
  };
883
991
  }
884
992
  //#endregion
885
- export { nonRetryableError as C, markRetryable as S, defineStep as _, WORKFLOW_STATUS_SCHEMA as a, explicitRetryability as b, toPublicWorkflow as c, defineDecisionStep as d, functionDecider as f, defineSleepStep as g, defineMapStep as h, STEP_DISPLAY_STATUS_SCHEMA as i, defineDecisionOutcomeStep as l, buildWorkflow as m, PUBLIC_WORKFLOW_STEP_SCHEMA as n, toDisplayStepStatus as o, resolveDecision as p, STEP_DISPLAY_STATUS as r, toPublicStep as s, PUBLIC_WORKFLOW_SCHEMA as t, defineDecisionReviewStep as u, defineSubWorkflowStep as v, retryableError as w, isRetryableError as x, defineWaitStep as y };
993
+ export { nonRetryableError as C, gateRuleKeys as E, markRetryable as S, createInMemoryStepGate as T, defineStep as _, WORKFLOW_STATUS_SCHEMA as a, explicitRetryability as b, toPublicWorkflow as c, defineDecisionStep as d, functionDecider as f, defineSleepStep as g, defineMapStep as h, STEP_DISPLAY_STATUS_SCHEMA as i, defineDecisionOutcomeStep as l, buildWorkflow as m, PUBLIC_WORKFLOW_STEP_SCHEMA as n, toDisplayStepStatus as o, resolveDecision as p, STEP_DISPLAY_STATUS as r, toPublicStep as s, PUBLIC_WORKFLOW_SCHEMA as t, defineDecisionReviewStep as u, defineSubWorkflowStep as v, retryableError as w, isRetryableError as x, defineWaitStep as y };
@@ -1,4 +1,13 @@
1
1
  import { St as Result, lt as WorkflowId, nt as StepId, xt as FlowErrorShape } from "./index-DZUO24Rz.js";
2
+ //#region src/core/logger.d.ts
3
+ type LogAttributes = Record<string, unknown>;
4
+ interface Logger {
5
+ info(message: string, attributes?: LogAttributes): void;
6
+ warn(message: string, attributes?: LogAttributes): void;
7
+ error(message: string, error?: Error, attributes?: LogAttributes): void;
8
+ }
9
+ declare const noopLogger: Logger;
10
+ //#endregion
2
11
  //#region src/core/dispatcher.d.ts
3
12
  /**
4
13
  * What a step job is for. A queue carries two kinds of work for a step, and
@@ -61,4 +70,4 @@ interface Dispatcher {
61
70
  enqueueStepIn?(handle: unknown, payload: DispatchStepPayload, options?: EnqueueOptions): Promise<Result<void, FlowErrorShape>>;
62
71
  }
63
72
  //#endregion
64
- export { EnqueueOptions as i, DispatchStepPayload as n, Dispatcher as r, DispatchKind as t };
73
+ export { LogAttributes as a, EnqueueOptions as i, DispatchStepPayload as n, Logger as o, Dispatcher as r, noopLogger as s, DispatchKind as t };
@@ -170,107 +170,4 @@ export declare const flowStepLeaseColumns: {
170
170
  /** A lease past this instant is reaped on the next acquire. */
171
171
  expiresAt: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>>;
172
172
  };
173
- /**
174
- * `model_provider` — one row per provider an administrator manages
175
- * (`createModelProviders` in `octaflow/ai`, over `createPgModelProviderStore`).
176
- * `id` is the primary key; nothing else is declared beyond the columns. A host
177
- * whose customers bring their own keys adds its scope column beside these and
178
- * makes the key composite.
179
- *
180
- * ```ts
181
- * import { pgTable } from 'drizzle-orm/pg-core';
182
- * import { modelProviderColumns } from 'octaflow/drizzle';
183
- *
184
- * export const modelProvider = pgTable('model_provider', modelProviderColumns);
185
- * ```
186
- */
187
- export declare const modelProviderColumns: {
188
- id: import("drizzle-orm").IsPrimaryKey<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"id", [string, ...string[]]>>>;
189
- kind: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"kind", [string, ...string[]]>>;
190
- label: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"label", [string, ...string[]]>>;
191
- baseUrl: import("drizzle-orm/pg-core").PgTextBuilderInitial<"base_url", [string, ...string[]]>;
192
- region: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"region", [string, ...string[]]>>;
193
- apiKey: import("drizzle-orm/pg-core").PgTextBuilderInitial<"api_key", [string, ...string[]]>;
194
- keyHint: import("drizzle-orm/pg-core").PgTextBuilderInitial<"key_hint", [string, ...string[]]>;
195
- headers: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm").$Type<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"headers">, Record<string, string>>>>;
196
- tags: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm").$Type<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"tags">, string[]>>>;
197
- models: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm").$Type<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"models">, unknown[]>>>;
198
- defaultModel: import("drizzle-orm/pg-core").PgTextBuilderInitial<"default_model", [string, ...string[]]>;
199
- enabled: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgBooleanBuilderInitial<"enabled">>>;
200
- updatedAt: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>>>;
201
- updatedBy: import("drizzle-orm/pg-core").PgTextBuilderInitial<"updated_by", [string, ...string[]]>;
202
- };
203
- /**
204
- * `model_runner` — one row per runner an administrator registered
205
- * (`createModelRunnerHub` in `octaflow/ai/runner`, over
206
- * `createPgModelRunnerStore`). `id` is the primary key; the DDL adds a unique
207
- * index on `token_hash`, which the host mirrors. No scope column, as for the
208
- * providers.
209
- *
210
- * ```ts
211
- * import { pgTable, uniqueIndex } from 'drizzle-orm/pg-core';
212
- * import { modelRunnerColumns } from 'octaflow/drizzle';
213
- *
214
- * export const modelRunner = pgTable('model_runner', modelRunnerColumns, (t) => [uniqueIndex('model_runner_token_hash_idx').on(t.tokenHash)]);
215
- * ```
216
- */
217
- export declare const modelRunnerColumns: {
218
- id: import("drizzle-orm").IsPrimaryKey<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"id", [string, ...string[]]>>>;
219
- label: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"label", [string, ...string[]]>>;
220
- tags: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm").$Type<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"tags">, string[]>>>;
221
- concurrency: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgIntegerBuilderInitial<"concurrency">>>;
222
- tokenHash: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"token_hash", [string, ...string[]]>>;
223
- lastSeenAt: import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>;
224
- createdAt: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>>>;
225
- createdBy: import("drizzle-orm/pg-core").PgTextBuilderInitial<"created_by", [string, ...string[]]>;
226
- };
227
- /**
228
- * `model_runner_request` — the mailbox: one row per model call in flight,
229
- * deleted as soon as the caller read the answer. The DDL's index is the
230
- * claim's, `(created_at) WHERE status = 'pending'`, which the host mirrors.
231
- *
232
- * ```ts
233
- * import { index, pgTable } from 'drizzle-orm/pg-core';
234
- * import { modelRunnerRequestColumns } from 'octaflow/drizzle';
235
- *
236
- * export const modelRunnerRequest = pgTable('model_runner_request', modelRunnerRequestColumns, (t) => [
237
- * index('model_runner_request_pending_idx').on(t.createdAt).where(sql`${t.status} = 'pending'`),
238
- * ]);
239
- * ```
240
- */
241
- export declare const modelRunnerRequestColumns: {
242
- id: import("drizzle-orm").IsPrimaryKey<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"id", [string, ...string[]]>>>;
243
- providerId: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"provider_id", [string, ...string[]]>>;
244
- tags: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm").$Type<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"tags">, string[]>>>;
245
- model: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"model", [string, ...string[]]>>;
246
- kind: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"kind", [string, ...string[]]>>;
247
- payload: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"payload">>;
248
- status: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"status", [string, ...string[]]>>>;
249
- claimedBy: import("drizzle-orm/pg-core").PgTextBuilderInitial<"claimed_by", [string, ...string[]]>;
250
- claimedAt: import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>;
251
- leaseUntil: import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>;
252
- attempts: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgIntegerBuilderInitial<"attempts">>>;
253
- result: import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"result">;
254
- error: import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"error">;
255
- createdAt: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>>>;
256
- finishedAt: import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>;
257
- };
258
- /**
259
- * `model_runner_chunk` — the parts of a `stream` request as the runner posted
260
- * them, a batch per row, read and deleted with the request. The key is
261
- * composite, `(request_id, seq)`, and the host declares it.
262
- *
263
- * ```ts
264
- * import { pgTable, primaryKey } from 'drizzle-orm/pg-core';
265
- * import { modelRunnerChunkColumns } from 'octaflow/drizzle';
266
- *
267
- * export const modelRunnerChunk = pgTable('model_runner_chunk', modelRunnerChunkColumns, (t) => [primaryKey({ columns: [t.requestId, t.seq] })]);
268
- * ```
269
- */
270
- export declare const modelRunnerChunkColumns: {
271
- requestId: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTextBuilderInitial<"request_id", [string, ...string[]]>>;
272
- seq: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgIntegerBuilderInitial<"seq">>;
273
- parts: import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgJsonbBuilderInitial<"parts">>;
274
- createdAt: import("drizzle-orm").HasDefault<import("drizzle-orm").NotNull<import("drizzle-orm/pg-core").PgTimestampBuilderInitial<string>>>;
275
- };
276
173
  //#endregion
@@ -1,4 +1,4 @@
1
- import { bigint, bigserial, boolean, doublePrecision, integer, jsonb, text, timestamp } from "drizzle-orm/pg-core";
1
+ import { bigint, bigserial, doublePrecision, integer, jsonb, text, timestamp } from "drizzle-orm/pg-core";
2
2
  //#region src/drizzle/index.ts
3
3
  /**
4
4
  * `octaflow/drizzle` — the engine's tables as Drizzle column sets.
@@ -195,108 +195,5 @@ const flowStepLeaseColumns = {
195
195
  /** A lease past this instant is reaped on the next acquire. */
196
196
  expiresAt: timestamptz("expires_at").notNull()
197
197
  };
198
- /**
199
- * `model_provider` — one row per provider an administrator manages
200
- * (`createModelProviders` in `octaflow/ai`, over `createPgModelProviderStore`).
201
- * `id` is the primary key; nothing else is declared beyond the columns. A host
202
- * whose customers bring their own keys adds its scope column beside these and
203
- * makes the key composite.
204
- *
205
- * ```ts
206
- * import { pgTable } from 'drizzle-orm/pg-core';
207
- * import { modelProviderColumns } from 'octaflow/drizzle';
208
- *
209
- * export const modelProvider = pgTable('model_provider', modelProviderColumns);
210
- * ```
211
- */
212
- const modelProviderColumns = {
213
- id: text("id").primaryKey(),
214
- kind: text("kind").notNull(),
215
- label: text("label").notNull(),
216
- baseUrl: text("base_url"),
217
- region: text("region").notNull(),
218
- apiKey: text("api_key"),
219
- keyHint: text("key_hint"),
220
- headers: jsonb("headers").$type().notNull().default({}),
221
- tags: jsonb("tags").$type().notNull().default([]),
222
- models: jsonb("models").$type().notNull().default([]),
223
- defaultModel: text("default_model"),
224
- enabled: boolean("enabled").notNull().default(true),
225
- updatedAt: timestamptz("updated_at").notNull().defaultNow(),
226
- updatedBy: text("updated_by")
227
- };
228
- /**
229
- * `model_runner` — one row per runner an administrator registered
230
- * (`createModelRunnerHub` in `octaflow/ai/runner`, over
231
- * `createPgModelRunnerStore`). `id` is the primary key; the DDL adds a unique
232
- * index on `token_hash`, which the host mirrors. No scope column, as for the
233
- * providers.
234
- *
235
- * ```ts
236
- * import { pgTable, uniqueIndex } from 'drizzle-orm/pg-core';
237
- * import { modelRunnerColumns } from 'octaflow/drizzle';
238
- *
239
- * export const modelRunner = pgTable('model_runner', modelRunnerColumns, (t) => [uniqueIndex('model_runner_token_hash_idx').on(t.tokenHash)]);
240
- * ```
241
- */
242
- const modelRunnerColumns = {
243
- id: text("id").primaryKey(),
244
- label: text("label").notNull(),
245
- tags: jsonb("tags").$type().notNull().default([]),
246
- concurrency: integer("concurrency").notNull().default(1),
247
- tokenHash: text("token_hash").notNull(),
248
- lastSeenAt: timestamptz("last_seen_at"),
249
- createdAt: timestamptz("created_at").notNull().defaultNow(),
250
- createdBy: text("created_by")
251
- };
252
- /**
253
- * `model_runner_request` — the mailbox: one row per model call in flight,
254
- * deleted as soon as the caller read the answer. The DDL's index is the
255
- * claim's, `(created_at) WHERE status = 'pending'`, which the host mirrors.
256
- *
257
- * ```ts
258
- * import { index, pgTable } from 'drizzle-orm/pg-core';
259
- * import { modelRunnerRequestColumns } from 'octaflow/drizzle';
260
- *
261
- * export const modelRunnerRequest = pgTable('model_runner_request', modelRunnerRequestColumns, (t) => [
262
- * index('model_runner_request_pending_idx').on(t.createdAt).where(sql`${t.status} = 'pending'`),
263
- * ]);
264
- * ```
265
- */
266
- const modelRunnerRequestColumns = {
267
- id: text("id").primaryKey(),
268
- providerId: text("provider_id").notNull(),
269
- tags: jsonb("tags").$type().notNull().default([]),
270
- model: text("model").notNull(),
271
- kind: text("kind").notNull(),
272
- payload: jsonb("payload").notNull(),
273
- status: text("status").notNull().default("pending"),
274
- claimedBy: text("claimed_by"),
275
- claimedAt: timestamptz("claimed_at"),
276
- leaseUntil: timestamptz("lease_until"),
277
- attempts: integer("attempts").notNull().default(0),
278
- result: jsonb("result"),
279
- error: jsonb("error"),
280
- createdAt: timestamptz("created_at").notNull().defaultNow(),
281
- finishedAt: timestamptz("finished_at")
282
- };
283
- /**
284
- * `model_runner_chunk` — the parts of a `stream` request as the runner posted
285
- * them, a batch per row, read and deleted with the request. The key is
286
- * composite, `(request_id, seq)`, and the host declares it.
287
- *
288
- * ```ts
289
- * import { pgTable, primaryKey } from 'drizzle-orm/pg-core';
290
- * import { modelRunnerChunkColumns } from 'octaflow/drizzle';
291
- *
292
- * export const modelRunnerChunk = pgTable('model_runner_chunk', modelRunnerChunkColumns, (t) => [primaryKey({ columns: [t.requestId, t.seq] })]);
293
- * ```
294
- */
295
- const modelRunnerChunkColumns = {
296
- requestId: text("request_id").notNull(),
297
- seq: integer("seq").notNull(),
298
- parts: jsonb("parts").notNull(),
299
- createdAt: timestamptz("created_at").notNull().defaultNow()
300
- };
301
198
  //#endregion
302
- export { flowRateBucketColumns, flowStepEventColumns, flowStepLeaseColumns, flowWorkflowColumns, flowWorkflowStepColumns, modelProviderColumns, modelRunnerChunkColumns, modelRunnerColumns, modelRunnerRequestColumns };
199
+ export { flowRateBucketColumns, flowStepEventColumns, flowStepLeaseColumns, flowWorkflowColumns, flowWorkflowStepColumns };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,60 @@
1
1
  import { $ as StepHandler, A as StepOutput, B as defineWaitStep, C as defineDecisionOutcomeStep, Ct as err, D as resolveDecision, E as functionDecider, F as buildWorkflow, G as StepCompensateHandler, H as InvalidWorkflowDefinitionError, I as defineMapStep, J as StepDefinition, K as StepCompensationContext, L as defineSleepStep, M as TypedStepContext, N as TypedWorkflow, O as DefineStepConfig, P as WorkflowOutput, Q as StepFailurePolicy, R as defineStep, S as DecisionStep, St as Result, T as defineDecisionStep, U as RetryPolicy, V as FlowError, W as StartOptions, X as StepError, Y as StepDelay, Z as StepExecutionContext, _ as DecisionOutput, _t as PlannedSkip, a as STEP_DISPLAY_STATUS, at as StepStatus, b as DecisionResponse, bt as isTerminalStepStatus, c as WORKFLOW_STATUS_SCHEMA, ct as WorkflowDefinition, d as toPublicWorkflow, dt as WorkflowNotRetryableError, et as StepHandlerNotFoundError, f as Decider, ft as WorkflowRecord, g as DecisionOutcome, gt as JoinRule, h as DecisionChoices, ht as WorkflowWithSteps, i as PublicWorkflowStep, it as StepRegistration, j as TypedStep, k as StepDeps, l as toDisplayStepStatus, lt as WorkflowId, m as DecisionAnswers, mt as WorkflowStepRunningError, n as PUBLIC_WORKFLOW_STEP_SCHEMA, nt as StepId, o as STEP_DISPLAY_STATUS_SCHEMA, ot as WaitTimeoutPolicy, p as DecisionAnswer, pt as WorkflowStatus, q as StepConditionHandler, r as PublicWorkflow, rt as StepRecord, s as StepDisplayStatus, st as WorkflowCreatedResult, t as PUBLIC_WORKFLOW_SCHEMA, tt as StepHandlerRegistry, u as toPublicStep, ut as WorkflowNotFoundError, v as DecisionQuestions, vt as ReadinessPlan, w as defineDecisionReviewStep, wt as ok, x as DecisionReview, xt as FlowErrorShape, y as DecisionRequest, yt as computeReadiness, z as defineSubWorkflowStep } from "./index-DZUO24Rz.js";
2
- import { n as Logger, r as noopLogger, t as LogAttributes } from "./logger-BCus3AOa.js";
2
+ import { a as LogAttributes, i as EnqueueOptions, n as DispatchStepPayload, o as Logger, r as Dispatcher, s as noopLogger, t as DispatchKind } from "./dispatcher-ltwBJjKc.js";
3
3
  import { A as FinishWorkflowParams, C as gateRuleKeys, D as CreateWorkflowStep, E as CreateWorkflowParams, F as WorkflowTreeFilter, M as ReopenWorkflowParams, N as TransactionalScope, O as CreatedWorkflow, P as WorkflowStore, S as createInMemoryStepGate, T as CompleteStepParams, _ 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 ListWorkflowsFilters, k as FailStepParams, 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 AddChildStep, x as StepGateRequest, y as StepGate } from "./observability-BLUEjdto.js";
4
- import { i as EnqueueOptions, n as DispatchStepPayload, r as Dispatcher, t as DispatchKind } from "./dispatcher-BQErUGy_.js";
5
- import { a as WorkflowCompletedArgs, i as BuildStepContextArgs, n as BeforeStartArgs, o as WorkflowHooks, r as BeforeStartResult, t as AfterStepArgs } from "./hooks-DHomzpiq.js";
4
+ //#region src/core/hooks.d.ts
5
+ export interface BeforeStartArgs {
6
+ definition: WorkflowDefinition;
7
+ input: Record<string, unknown>;
8
+ options?: StartOptions;
9
+ }
10
+ export interface BeforeStartResult {
11
+ /** Extra metadata persisted on the workflow row (merged over `options.metadata`). */
12
+ metadata?: Record<string, unknown>;
13
+ }
14
+ export interface BuildStepContextArgs {
15
+ workflowId: WorkflowId;
16
+ stepId: StepId;
17
+ stepKey: string;
18
+ partitionKey: string;
19
+ workflow: WorkflowRecord;
20
+ step: StepRecord;
21
+ }
22
+ export interface AfterStepArgs<TContext> {
23
+ workflowId: WorkflowId;
24
+ stepId: StepId;
25
+ partitionKey: string;
26
+ workflow: WorkflowRecord;
27
+ step: StepRecord;
28
+ output: Record<string, unknown>;
29
+ /** The same context object that was handed to the step handler. */
30
+ context: TContext;
31
+ }
32
+ export interface WorkflowCompletedArgs {
33
+ workflowId: WorkflowId;
34
+ partitionKey: string;
35
+ workflow: WorkflowRecord;
36
+ }
37
+ export interface WorkflowHooks<TContext = unknown> {
38
+ /**
39
+ * Runs before a workflow is created. Return an error to reject the start
40
+ * (e.g. quota exceeded) — the engine passes the error through untouched.
41
+ */
42
+ onBeforeStart?(args: BeforeStartArgs): Promise<Result<BeforeStartResult, FlowErrorShape>>;
43
+ /**
44
+ * Produces the per-step `context` handed to the handler (and later to
45
+ * `onAfterStep`). This is where the AI add-on resolves and instruments a model.
46
+ * If omitted, handlers receive `undefined` as their context.
47
+ */
48
+ buildStepContext?(args: BuildStepContextArgs): TContext | Promise<TContext>;
49
+ /**
50
+ * Runs after a step handler succeeds, before the step is marked completed.
51
+ * The AI add-on reads token usage off `context` here and persists cost.
52
+ */
53
+ onAfterStep?(args: AfterStepArgs<TContext>): Promise<void>;
54
+ /** Runs once when a workflow reaches `completed` (e.g. daily usage rollup). */
55
+ onWorkflowCompleted?(args: WorkflowCompletedArgs): Promise<void>;
56
+ }
57
+ //#endregion
6
58
  //#region src/core/registry.d.ts
7
59
  /**
8
60
  * Creates an in-memory step handler registry.
@@ -168,4 +220,4 @@ export declare function createInMemoryWorkflowStore(partitionKey?: string): Work
168
220
  };
169
221
  };
170
222
  //#endregion
171
- export { AddChildStep, AfterStepArgs, BeforeStartArgs, BeforeStartResult, BuildStepContextArgs, CompleteStepParams, ConcurrencyRule, CreateWorkflowParams, CreateWorkflowStep, CreatedWorkflow, Decider, DecisionAnswer, DecisionAnswers, DecisionChoices, DecisionOutcome, DecisionOutput, DecisionQuestions, DecisionRequest, DecisionResponse, DecisionReview, DecisionStep, DefineStepConfig, 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, StepDelay, StepDeps, StepDisplayStatus, StepError, StepExecutionContext, StepFailurePolicy, 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, WorkflowStepRunningError, WorkflowStore, WorkflowTreeFilter, WorkflowWithSteps, buildWorkflow, combineObservers, computeReadiness, createInMemoryStepGate, createMeterObserver, createRecordingObserver, createRecordingTracer, defineDecisionOutcomeStep, defineDecisionReviewStep, defineDecisionStep, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, functionDecider, gateRuleKeys, isTerminalStepStatus, noopLogger, noopObserver, noopTracer, ok, resolveDecision, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
223
+ export { AddChildStep, CompleteStepParams, ConcurrencyRule, CreateWorkflowParams, CreateWorkflowStep, CreatedWorkflow, Decider, DecisionAnswer, DecisionAnswers, DecisionChoices, DecisionOutcome, DecisionOutput, DecisionQuestions, DecisionRequest, DecisionResponse, DecisionReview, DecisionStep, DefineStepConfig, 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, StepDelay, StepDeps, StepDisplayStatus, StepError, StepExecutionContext, StepFailurePolicy, StepGate, StepGateDecision, StepGateRequest, StepHandler, StepHandlerNotFoundError, StepHandlerRegistry, StepId, StepOutput, StepRecord, StepRegistration, StepStatus, TransactionalScope, TypedStep, TypedStepContext, TypedWorkflow, WORKFLOW_STATUS_SCHEMA, WaitTimeoutPolicy, WorkflowCreatedResult, WorkflowDefinition, WorkflowId, WorkflowNotFoundError, WorkflowNotRetryableError, WorkflowOutput, WorkflowRecord, WorkflowStatus, WorkflowStepRunningError, WorkflowStore, WorkflowTreeFilter, WorkflowWithSteps, buildWorkflow, combineObservers, computeReadiness, createInMemoryStepGate, createMeterObserver, createRecordingObserver, createRecordingTracer, defineDecisionOutcomeStep, defineDecisionReviewStep, defineDecisionStep, defineMapStep, defineSleepStep, defineStep, defineSubWorkflowStep, defineWaitStep, err, functionDecider, gateRuleKeys, isTerminalStepStatus, noopLogger, noopObserver, noopTracer, ok, resolveDecision, toDisplayStepStatus, toPublicStep, toPublicWorkflow };
package/dist/index.js CHANGED
@@ -1,6 +1,21 @@
1
- import { n as err, r as ok, t as noopLogger } from "./logger-epkdcXDA.js";
2
- import { n as gateRuleKeys, t as createInMemoryStepGate } from "./gate-BRq-t3K_.js";
3
- import { C as nonRetryableError, S as markRetryable, _ as defineStep, a as WORKFLOW_STATUS_SCHEMA, b as explicitRetryability, c as toPublicWorkflow, d as defineDecisionStep, f as functionDecider, g as defineSleepStep, h as defineMapStep, i as STEP_DISPLAY_STATUS_SCHEMA, l as defineDecisionOutcomeStep, m as buildWorkflow, n as PUBLIC_WORKFLOW_STEP_SCHEMA, o as toDisplayStepStatus, p as resolveDecision, r as STEP_DISPLAY_STATUS, s as toPublicStep, t as PUBLIC_WORKFLOW_SCHEMA, u as defineDecisionReviewStep, v as defineSubWorkflowStep, w as retryableError, x as isRetryableError, y as defineWaitStep } from "./core-COMWflJl.js";
1
+ import { C as nonRetryableError, E as gateRuleKeys, S as markRetryable, T as createInMemoryStepGate, _ as defineStep, a as WORKFLOW_STATUS_SCHEMA, b as explicitRetryability, c as toPublicWorkflow, d as defineDecisionStep, f as functionDecider, g as defineSleepStep, h as defineMapStep, i as STEP_DISPLAY_STATUS_SCHEMA, l as defineDecisionOutcomeStep, m as buildWorkflow, n as PUBLIC_WORKFLOW_STEP_SCHEMA, o as toDisplayStepStatus, p as resolveDecision, r as STEP_DISPLAY_STATUS, s as toPublicStep, t as PUBLIC_WORKFLOW_SCHEMA, u as defineDecisionReviewStep, v as defineSubWorkflowStep, w as retryableError, x as isRetryableError, y as defineWaitStep } from "./core-YqnPwR-v.js";
2
+ //#region src/core/result.ts
3
+ const ok = (value) => ({
4
+ ok: true,
5
+ value
6
+ });
7
+ const err = (error) => ({
8
+ ok: false,
9
+ error
10
+ });
11
+ //#endregion
12
+ //#region src/core/logger.ts
13
+ const noopLogger = {
14
+ info() {},
15
+ warn() {},
16
+ error() {}
17
+ };
18
+ //#endregion
4
19
  //#region src/core/readiness.ts
5
20
  /** Statuses a step can no longer move out of on its own. */
6
21
  const TERMINAL_STATUSES = /* @__PURE__ */ new Set([
@@ -1,6 +1,5 @@
1
1
  import "../index-DZUO24Rz.js";
2
- import { n as Logger } from "../logger-BCus3AOa.js";
3
- import { r as Dispatcher } from "../dispatcher-BQErUGy_.js";
2
+ import { o as Logger, r as Dispatcher } from "../dispatcher-ltwBJjKc.js";
4
3
  import { z } from "zod";
5
4
  import { PgBoss, Schedule } from "pg-boss";
6
5
  //#region src/pg-boss/payload.d.ts