@voltro/plugin-ai-flows 0.70.0 → 0.71.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,91 +1,93 @@
1
- import { A as e, C as t, D as n, E as r, M as i, O as a, S as o, T as s, _ as c, a as l, b as u, c as d, d as f, f as p, g as m, h, i as ee, j as g, k as te, l as ne, m as re, n as ie, o as ae, p as oe, r as se, s as ce, t as le, u as ue, v as de, w as fe, x as pe, y as me } from "./ir-BOv5uwYI.js";
2
- import { FLOW_RUN_WORKFLOW as _, HUMAN_RESPONSE_SIGNAL_PREFIX as he, humanResponseSignalName as v } from "./workflow.js";
3
- import { FlowBriefIncomplete as ge, FlowCapabilityMissing as y, FlowDependencyError as _e, FlowNotAwaitingResponse as ve, FlowNotFound as ye, FlowRunNotFound as b, FlowValidationError as be } from "./errors.js";
4
- import { n as xe, t as Se } from "./cadence-_9Izk_fL.js";
5
- import { Cause as Ce, Effect as x, Schema as S } from "effect";
6
- import { definePlugin as we, pluginInstanceName as Te } from "@voltro/protocol";
7
- import { boolean as Ee, eq as C, id as De, inSet as Oe, integer as w, json as T, queryFor as E, registerRetention as ke, table as Ae, text as D, timestamp as O } from "@voltro/database";
8
- import { tenant as je } from "@voltro/plugin-multitenancy/mixin";
9
- import { audit as Me } from "@voltro/plugin-audit/mixin";
10
- import { softDelete as Ne } from "@voltro/plugin-soft-delete/mixin";
11
- import { awaitSignalSuspending as Pe, step as k } from "@voltro/workflow";
12
- import { defineTool as A, estimateCostUsd as Fe, gatewayCostUsd as Ie, generateImage as Le, generateObject as Re, generateObjectWithTools as ze, generateSpeech as Be, generateText as j, generateVideo as Ve } from "@voltro/ai";
1
+ import { A as e, C as t, D as n, E as r, F as i, I as a, L as o, M as s, N as c, O as l, P as u, S as d, T as f, _ as p, a as m, b as ee, c as h, d as g, f as te, g as ne, h as re, i as ie, j as _, k as ae, l as oe, m as se, n as ce, o as le, p as ue, r as de, s as fe, t as pe, u as me, v as he, w as ge, x as _e, y as ve } from "./ir-B0rox9qW.js";
2
+ import { FLOW_RUN_WORKFLOW as v, HUMAN_RESPONSE_SIGNAL_PREFIX as ye, flowRunWorkflow as y, humanResponseSignalName as b } from "./workflow.js";
3
+ import { FlowBriefIncomplete as be, FlowCapabilityMissing as x, FlowDependencyError as xe, FlowNotAwaitingResponse as Se, FlowNotFound as Ce, FlowReviewDeliveryError as we, FlowRunNotFound as S, FlowValidationError as Te } from "./errors.js";
4
+ import { n as Ee, t as De } from "./cadence-_9Izk_fL.js";
5
+ import { Cause as Oe, Effect as C, Schema as w } from "effect";
6
+ import { WorkflowRunHandleSchema as ke, definePlugin as Ae, pluginInstanceName as je } from "@voltro/protocol";
7
+ import { boolean as Me, eq as T, id as Ne, inSet as Pe, integer as E, json as D, queryFor as O, registerRetention as Fe, table as Ie, text as k, timestamp as A } from "@voltro/database";
8
+ import { tenant as Le } from "@voltro/plugin-multitenancy/mixin";
9
+ import { audit as Re } from "@voltro/plugin-audit/mixin";
10
+ import { softDelete as ze } from "@voltro/plugin-soft-delete/mixin";
11
+ import { awaitSignalSuspending as Be, step as j } from "@voltro/workflow";
12
+ import { defineTool as M, estimateCostUsd as Ve, gatewayCostUsd as He, generateImage as Ue, generateObject as We, generateObjectJson as Ge, generateObjectWithTools as Ke, generateSpeech as qe, generateText as Je, generateVideo as Ye } from "@voltro/ai";
13
+ import { createHash as Xe } from "node:crypto";
13
14
  //#region src/table.ts
14
- var M = Ae("_voltro_ai_flows", {
15
- id: De({ prefix: "aifl" }),
16
- name: D(),
17
- description: D().nullable(),
18
- mode: D().default("deterministic"),
19
- status: D().default("draft"),
20
- visibility: D().default("private"),
21
- orchestratorModel: D().nullable(),
22
- orchestratorInstructions: D().nullable(),
23
- maxSteps: w().default(30),
24
- steps: T().nullable(),
25
- inputSchema: T().nullable(),
26
- chainTo: T().nullable(),
27
- cadence: T().nullable(),
28
- humanTimeoutMs: w().nullable(),
29
- isEnabled: Ee().default(!0),
30
- metadata: T().nullable(),
31
- icon: D().nullable(),
32
- color: D().nullable(),
33
- avatarUrl: D().nullable(),
34
- usageCount: w().default(0),
35
- ownerId: D().nullable()
36
- }).renamedFrom("ai_flows").with(je(), Me(), Ne()).index(["status"]).index(["visibility"]), N = Ae("_voltro_ai_flow_runs", {
37
- id: De({ prefix: "aifr" }),
38
- flowRef: D(),
39
- flowName: D().nullable(),
40
- mode: D().default("deterministic"),
41
- status: D().default("pending"),
42
- source: D().nullable(),
43
- requestId: D(),
44
- input: T().nullable(),
45
- output: T().nullable(),
46
- steps: T().nullable(),
47
- currentStep: w().default(0),
48
- totalSteps: w().default(0),
49
- humanResponse: T().nullable(),
50
- chainPending: T().nullable(),
51
- chainRefusal: D().nullable(),
52
- costMicroUsd: w().default(0),
53
- durationMs: w().nullable(),
54
- error: D().nullable(),
55
- errorMessage: D().nullable(),
56
- startedAt: O().nullable(),
57
- completedAt: O().nullable(),
58
- cancelledAt: O().nullable(),
59
- sessionId: D().nullable(),
60
- sessionName: D().nullable(),
61
- ownerId: D().nullable(),
62
- metadata: T().nullable()
63
- }).renamedFrom("ai_flow_runs").with(je(), Me()).index(["flowRef"]).index(["status"]).index(["requestId"]), He = [M, N], Ue = 168, We = "VOLTRO_AI_FLOW_HUMAN_REVIEW_TIMEOUT_HOURS", Ge = 2160, Ke = "VOLTRO_AI_FLOW_RUNS_TTL_HOURS", qe = 5, Je = "VOLTRO_AI_FLOW_MAX_CHAIN_DEPTH", P = { current: {} }, Ye = (e) => {
64
- P.current = e;
65
- }, F = () => P.current, Xe = () => {
66
- P.current = {};
67
- }, Ze = (e, t) => {
15
+ var N = Ie("_voltro_ai_flows", {
16
+ id: Ne({ prefix: "aifl" }),
17
+ name: k(),
18
+ description: k().nullable(),
19
+ mode: k().default("deterministic"),
20
+ status: k().default("draft"),
21
+ visibility: k().default("private"),
22
+ orchestratorModel: k().nullable(),
23
+ orchestratorInstructions: k().nullable(),
24
+ maxSteps: E().default(30),
25
+ steps: D().nullable(),
26
+ inputSchema: D().nullable(),
27
+ chainTo: D().nullable(),
28
+ cadence: D().nullable(),
29
+ humanTimeoutMs: E().nullable(),
30
+ isEnabled: Me().default(!0),
31
+ metadata: D().nullable(),
32
+ icon: k().nullable(),
33
+ color: k().nullable(),
34
+ avatarUrl: k().nullable(),
35
+ usageCount: E().default(0),
36
+ ownerId: k().nullable()
37
+ }).renamedFrom("ai_flows").with(Le(), Re(), ze()).index(["status"]).index(["visibility"]), P = Ie("_voltro_ai_flow_runs", {
38
+ id: Ne({ prefix: "aifr" }),
39
+ flowRef: k(),
40
+ flowName: k().nullable(),
41
+ mode: k().default("deterministic"),
42
+ status: k().default("pending"),
43
+ source: k().nullable(),
44
+ requestId: k(),
45
+ workflowStart: D().nullable(),
46
+ input: D().nullable(),
47
+ output: D().nullable(),
48
+ steps: D().nullable(),
49
+ currentStep: E().default(0),
50
+ totalSteps: E().default(0),
51
+ humanResponse: D().nullable(),
52
+ chainPending: D().nullable(),
53
+ chainRefusal: k().nullable(),
54
+ costMicroUsd: E().default(0),
55
+ durationMs: E().nullable(),
56
+ error: k().nullable(),
57
+ errorMessage: k().nullable(),
58
+ startedAt: A().nullable(),
59
+ completedAt: A().nullable(),
60
+ cancelledAt: A().nullable(),
61
+ sessionId: k().nullable(),
62
+ sessionName: k().nullable(),
63
+ ownerId: k().nullable(),
64
+ metadata: D().nullable()
65
+ }).renamedFrom("ai_flow_runs").with(Le(), Re()).index(["flowRef"]).index(["status"]).index(["requestId"]), Ze = [N, P], Qe = 168, $e = "VOLTRO_AI_FLOW_HUMAN_REVIEW_TIMEOUT_HOURS", et = 2160, tt = "VOLTRO_AI_FLOW_RUNS_TTL_HOURS", nt = 5, rt = "VOLTRO_AI_FLOW_MAX_CHAIN_DEPTH", F = { current: {} }, it = (e) => {
66
+ F.current = e;
67
+ }, I = () => F.current, at = () => {
68
+ F.current = {};
69
+ }, ot = (e, t) => {
68
70
  if (e === void 0 || e.trim() === "") return t * 36e5;
69
71
  let n = Number(e);
70
72
  return !Number.isFinite(n) || n < 0 ? t * 36e5 : n * 36e5;
71
- }, Qe = (e) => Number.isFinite(e) && e > 0 ? e : Infinity, $e = (e) => {
73
+ }, st = (e) => Number.isFinite(e) && e > 0 ? e : Infinity, ct = (e) => {
72
74
  let t = e.env ?? process.env;
73
- return Qe(e.step?.timeoutMs ?? e.flow?.humanTimeoutMs ?? e.deps?.humanReviewTimeoutMs ?? F().humanReviewTimeoutMs ?? Ze(t.VOLTRO_AI_FLOW_HUMAN_REVIEW_TIMEOUT_HOURS, 168));
74
- }, et = (e) => {
75
- let t = e?.env ?? process.env, n = Number(t[Je]), r = e?.maxChainDepth ?? F().maxChainDepth ?? (Number.isFinite(n) && n >= 1 ? n : 5);
75
+ return st(e.step?.timeoutMs ?? e.flow?.humanTimeoutMs ?? e.deps?.humanReviewTimeoutMs ?? I().humanReviewTimeoutMs ?? ot(t.VOLTRO_AI_FLOW_HUMAN_REVIEW_TIMEOUT_HOURS, 168));
76
+ }, lt = (e) => {
77
+ let t = e?.env ?? process.env, n = Number(t[rt]), r = e?.maxChainDepth ?? I().maxChainDepth ?? (Number.isFinite(n) && n >= 1 ? n : 5);
76
78
  return Number.isFinite(r) && r >= 1 ? r : 5;
77
- }, tt = /\{\{\s*([\w.-]+)\s*\}\}/g, I = (e) => {
79
+ }, ut = /\{\{\s*([\w.-]+)\s*\}\}/g, L = (e) => {
78
80
  let t = [];
79
- for (let n of e.matchAll(tt)) t.push(n[1]);
81
+ for (let n of e.matchAll(ut)) t.push(n[1]);
80
82
  return t;
81
- }, L = (e, t) => e.replace(tt, (e, n) => {
83
+ }, R = (e, t) => e.replace(ut, (e, n) => {
82
84
  let r = t[n];
83
85
  return r == null ? "" : typeof r == "string" ? r : JSON.stringify(r);
84
- }), nt = (e, t) => {
86
+ }), dt = (e, t) => {
85
87
  let n = /* @__PURE__ */ new Set();
86
- for (let r of I(e)) t[r] == null && !n.has(r) && n.add(r);
88
+ for (let r of L(e)) t[r] == null && !n.has(r) && n.add(r);
87
89
  return [...n];
88
- }, R = (e) => {
90
+ }, z = (e) => {
89
91
  let t = [], n;
90
92
  if (e.forEach((e, r) => {
91
93
  let i = e.group;
@@ -114,87 +116,127 @@ var M = Ae("_voltro_ai_flows", {
114
116
  });
115
117
  }
116
118
  return t;
117
- }, rt = (e) => {
119
+ }, ft = (e) => {
118
120
  let t = /* @__PURE__ */ new Map();
119
121
  for (let n of e) n.group !== void 0 && t.set(n.group, (t.get(n.group) ?? 0) + 1);
120
122
  return [...t.entries()].filter(([, e]) => e > 1).map(([e]) => e).sort();
121
- }, z = /* @__PURE__ */ new Map(), it = (e) => {
122
- z.set(e.name, e);
123
- }, at = (e) => z.get(e), ot = () => [...z.values()], st = () => z.clear(), B = (e) => typeof e == "object" && e && !Array.isArray(e) ? e : void 0, V = (e) => Array.isArray(e) ? e : void 0, ct = (e) => {
124
- switch (e) {
125
- case "string": return S.String;
126
- case "number": return S.Number;
127
- case "integer": return S.Int;
128
- case "boolean": return S.Boolean;
129
- case "null": return S.Null;
130
- default: return S.Unknown;
123
+ }, B = /* @__PURE__ */ new Map(), pt = (e) => {
124
+ B.set(e.name, e);
125
+ }, mt = (e) => B.get(e), ht = () => [...B.values()], gt = () => B.clear(), V = w.suspend(() => w.Union(w.Null, w.Boolean, w.Finite, w.String, w.Array(V).pipe(w.mutable), w.Record({
126
+ key: w.String,
127
+ value: V
128
+ }))), H = w.Record({
129
+ key: w.String,
130
+ value: w.Record({
131
+ key: w.String,
132
+ value: V
133
+ })
134
+ }), _t = w.Struct({
135
+ maxTokens: w.optionalWith(w.Int.pipe(w.positive(), w.lessThanOrEqualTo(2 ** 53 - 1)), { exact: !0 }),
136
+ temperature: w.optionalWith(w.Finite.pipe(w.nonNegative()), { exact: !0 }),
137
+ providerOptions: w.optionalWith(H, { exact: !0 })
138
+ }), vt = (e) => C.try({
139
+ try: () => w.decodeUnknownSync(_t, { onExcessProperty: "error" })(e === void 0 ? {} : e),
140
+ catch: () => "invalid text params: expected maxTokens (positive safe integer), temperature (finite nonnegative number), and/or providerOptions (provider-keyed JSON object); other fields are not supported"
141
+ }), yt = w.String.pipe(w.filter((e) => {
142
+ try {
143
+ let t = new URL(e);
144
+ return (t.protocol === "https:" || t.protocol === "http:") && t.username === "" && t.password === "";
145
+ } catch {
146
+ return !1;
131
147
  }
132
- }, H = (e, t) => {
133
- let n = typeof t.description == "string" ? t.description : void 0, r = typeof t.title == "string" ? t.title : void 0;
134
- return n === void 0 && r === void 0 ? e : e.annotations({
135
- ...n === void 0 ? {} : { description: n },
136
- ...r === void 0 ? {} : { title: r }
148
+ })), U = w.Record({
149
+ key: w.String,
150
+ value: yt
151
+ }), bt = (e, t, n = {}) => C.try({
152
+ try: () => {
153
+ let r = w.decodeUnknownSync(ve, { onExcessProperty: "error" })(e === void 0 ? {} : e), i = Object.fromEntries(Object.entries(r).map(([e, r]) => [e, r.from === "upload" ? r.url : r.artifact === void 0 ? Object.hasOwn(t, r.ref) ? t[r.ref] : void 0 : Object.hasOwn(n, r.ref) ? n[r.ref]?.[r.artifact]?.url : void 0]));
154
+ return w.decodeUnknownSync(U)(i);
155
+ },
156
+ catch: () => "invalid or unresolved media input: each slot must resolve to an absolute HTTP(S) URL without embedded credentials"
157
+ }), xt = (e, t) => C.try({
158
+ try: () => {
159
+ let n = w.decodeUnknownSync(U)(t === void 0 ? {} : t), r = e === "image" ? ["referenceImageUrl", "maskImageUrl"] : e === "video" ? [
160
+ "referenceImageUrl",
161
+ "firstFrameImageUrl",
162
+ "lastFrameImageUrl",
163
+ "referenceVideoUrl"
164
+ ] : [];
165
+ if (Object.keys(n).some((e) => !r.includes(e))) throw Error("unsupported slot");
166
+ if (e === "image" && n.maskImageUrl !== void 0 && n.referenceImageUrl === void 0) throw Error("mask requires reference");
167
+ return n;
168
+ },
169
+ catch: () => `invalid or unsupported media input for ${e}; check the built-in adapter's slot contract`
170
+ }), St = w.Struct({
171
+ artifacts: p,
172
+ costMicroUsd: w.optional(w.Finite.pipe(w.nonNegative())),
173
+ requestId: w.optional(w.NonEmptyString)
174
+ }), Ct = (e) => C.try({
175
+ try: () => w.decodeUnknownSync(St, { onExcessProperty: "error" })(e),
176
+ catch: () => "invalid media result: expected artifacts with URL, mediaType and role, exactly one primary artifact, and optional storage references"
177
+ }), W = (e) => e, wt = w.Struct({
178
+ value: w.optional(w.Unknown),
179
+ text: w.optional(w.String),
180
+ url: w.optional(w.String),
181
+ artifacts: w.optional(p),
182
+ costMicroUsd: w.optional(w.Number),
183
+ requestId: w.optional(w.String),
184
+ error: w.optional(w.String)
185
+ }), Tt = (e) => Ct(e).pipe(C.map((e) => {
186
+ let t = e.artifacts.find((e) => e.role === "primary");
187
+ return {
188
+ value: t.url,
189
+ url: t.url,
190
+ artifacts: e.artifacts,
191
+ ...e.requestId === void 0 ? {} : { requestId: e.requestId },
192
+ ...e.costMicroUsd === void 0 ? {} : { costMicroUsd: e.costMicroUsd }
193
+ };
194
+ }), C.catchAll((e) => C.succeed({ error: e }))), G = () => (/* @__PURE__ */ new Date()).toISOString(), Et = (e) => Math.round(e * 1e6), Dt = (e) => ({
195
+ name: "gateway",
196
+ model: e
197
+ }), K = (e, t) => e.resolveModel?.(t) ?? Dt(t), Ot = (e, t, n, r) => C.gen(function* () {
198
+ return t.maxSteps !== void 0 && (!Number.isSafeInteger(t.maxSteps) || t.maxSteps < 1) ? yield* C.fail(new x({
199
+ capability: "resolveAgent",
200
+ message: "agent maxSteps must be a positive safe integer"
201
+ })) : yield* Je({
202
+ ...r,
203
+ system: t.system,
204
+ prompt: n,
205
+ provider: K(e, t.model),
206
+ ...t.tools === void 0 ? {} : { tools: t.tools },
207
+ ...t.maxSteps === void 0 ? {} : { maxSteps: t.maxSteps }
137
208
  });
138
- }, lt = (e) => e.length === 0 ? S.Unknown : e.length === 1 ? e[0] : S.Union(...e), ut = () => S.Record({
139
- key: S.String,
140
- value: S.Unknown
141
- }), U = (e) => {
142
- let t = B(e);
143
- if (t === void 0) return S.Unknown;
144
- if ("const" in t) return H(S.Literal(t.const), t);
145
- let n = V(t.enum);
146
- if (n !== void 0 && n.length > 0) return H(S.Literal(...n), t);
147
- let r = V(t.anyOf) ?? V(t.oneOf);
148
- if (r !== void 0) return H(lt(r.map(U)), t);
149
- let i = t.type, a = typeof i == "string" ? [i] : V(i)?.filter((e) => typeof e == "string") ?? [], o = t.nullable === !0 || a.includes("null"), s = a.find((e) => e !== "null"), c = s === "object" || s === void 0 && t.properties !== void 0 ? dt(t) : s === "array" || s === void 0 && t.items !== void 0 ? S.Array(U(t.items)) : s === void 0 ? S.Unknown : ct(s);
150
- return H(o ? S.NullOr(c) : c, t);
151
- }, dt = (e) => {
152
- let t = B(e.properties);
153
- if (t === void 0) return ut();
154
- let n = new Set((V(e.required) ?? []).filter((e) => typeof e == "string")), r = {};
155
- for (let [e, i] of Object.entries(t)) {
156
- let t = U(i);
157
- r[e] = n.has(e) ? t : S.optional(t);
158
- }
159
- return S.Struct(r);
160
- }, ft = (e) => {
161
- let t = B(e);
162
- return t === void 0 || Object.keys(t).length === 0 ? ut() : U(t);
163
- }, W = (e) => e, pt = S.Struct({
164
- value: S.optional(S.Unknown),
165
- text: S.optional(S.String),
166
- url: S.optional(S.String),
167
- costMicroUsd: S.optional(S.Number),
168
- requestId: S.optional(S.String),
169
- error: S.optional(S.String)
170
- }), G = () => (/* @__PURE__ */ new Date()).toISOString(), mt = (e) => Math.round(e * 1e6), K = (e, t) => e.resolveModel?.(t) ?? K(e, t), q = (e, t, n) => {
171
- let r = Ie(t);
172
- return typeof r == "number" ? mt(r) : Fe(e, { model: n ?? "unknown" }).costMicroUsd ?? 0;
173
- }, J = (e, t, n) => x.promise(() => e.store.update(N.tableName, t, n).then(() => void 0)).pipe(x.catchAllCause(() => x.void)), ht = (e, t) => x.promise(async () => (await e.store.query(E(N).where(C("id", t)).descriptor))[0]?.status === "cancelled").pipe(x.catchAllCause(() => x.succeed(!1))), Y = (e, t) => x.gen(function* () {
174
- let n = at(t);
209
+ }), q = (e, t, n) => {
210
+ let r = He(t);
211
+ return typeof r == "number" ? Et(r) : Ve(e, { model: n ?? "unknown" }).costMicroUsd ?? 0;
212
+ }, J = (e, t, n) => C.promise(() => e.store.update(P.tableName, t, n).then(() => void 0)).pipe(C.catchAllCause(() => C.void)), kt = (e, t) => C.promise(async () => (await e.store.query(O(P).where(T("id", t)).descriptor))[0]?.status === "cancelled").pipe(C.catchAllCause(() => C.succeed(!1))), Y = (e, t) => C.gen(function* () {
213
+ let n = mt(t);
175
214
  if (n) return n;
176
- let i = (yield* x.promise(() => e.store.query(E(M).where(C("id", t)).descriptor)))[0];
177
- return i ? r({
178
- name: i.name ?? t,
179
- mode: i.mode,
180
- steps: i.steps ?? [],
181
- maxSteps: i.maxSteps ?? null,
182
- brief: i.inputSchema ?? [],
183
- orchestratorModel: i.orchestratorModel ?? null,
184
- orchestratorInstructions: i.orchestratorInstructions ?? null,
185
- chain: i.chainTo ?? null,
186
- cadence: i.cadence ?? null,
187
- humanTimeoutMs: i.humanTimeoutMs ?? null
188
- }) : yield* x.fail(new ye({
215
+ let r = (yield* C.promise(() => e.store.query(O(N).where(T("id", t)).descriptor)))[0];
216
+ return r ? _({
217
+ name: r.name ?? t,
218
+ mode: r.mode,
219
+ steps: r.steps ?? [],
220
+ maxSteps: r.maxSteps ?? null,
221
+ brief: r.inputSchema ?? [],
222
+ orchestratorModel: r.orchestratorModel ?? null,
223
+ orchestratorInstructions: r.orchestratorInstructions ?? null,
224
+ chain: r.chainTo ?? null,
225
+ cadence: r.cadence ?? null,
226
+ humanTimeoutMs: r.humanTimeoutMs ?? null
227
+ }) : yield* C.fail(new Ce({
189
228
  flowRef: t,
190
229
  message: `no flow registered or stored for "${t}"`
191
230
  }));
192
- }), gt = (e, t, n, r, i) => x.gen(function* () {
193
- let e = L(n.prompt ?? "", r), a = nt(n.prompt ?? "", r);
194
- if (a.length > 0) return { error: new _e({
231
+ }), At = (e, t, n, r, i, a) => C.gen(function* () {
232
+ let e = R(n.prompt ?? "", r), o = yield* vt(n.type === "agent" || n.type === "structured" || n.type === "generate" && (n.modality ?? "text") === "text" ? n.params : void 0).pipe(C.either);
233
+ if (o._tag === "Left") return { error: `step "${n.id}": ${o.left}` };
234
+ if (n.mediaInputs !== void 0 && (n.type !== "generate" || (n.modality ?? "text") === "text")) return { error: `step "${n.id}": media inputs require an image, video or audio generation step` };
235
+ let s = dt(n.prompt ?? "", r);
236
+ if (s.length > 0) return { error: new xe({
195
237
  stepId: n.id,
196
- unresolvedRef: a[0],
197
- message: `step "${n.id}" references unresolved {{${a[0]}}}`
238
+ unresolvedRef: s[0],
239
+ message: `step "${n.id}" references unresolved {{${s[0]}}}`
198
240
  }).message };
199
241
  switch (n.type) {
200
242
  case "note": return {
@@ -204,44 +246,42 @@ var M = Ae("_voltro_ai_flows", {
204
246
  };
205
247
  case "agent": {
206
248
  if (!n.agentRef) return { error: "agent step missing agentRef" };
207
- if (!t.resolveAgent) return { error: new y({
249
+ if (!t.resolveAgent) return { error: new x({
208
250
  capability: "resolveAgent",
209
251
  message: "no agent resolver configured"
210
252
  }).message };
211
- let r = yield* W(t.resolveAgent(n.agentRef)).pipe(x.map((e) => ({
253
+ let r = yield* W(t.resolveAgent(n.agentRef, i)).pipe(C.map((e) => ({
212
254
  ok: !0,
213
255
  a: e
214
- })), x.catchAll((e) => x.succeed({
256
+ })), C.catchAll((e) => C.succeed({
215
257
  ok: !1,
216
258
  e
217
259
  })));
218
260
  if (!r.ok) return { error: r.e.message };
219
- let i = yield* j({
220
- system: r.a.system,
221
- prompt: e,
222
- provider: K(t, r.a.model)
223
- }).pipe(x.map((e) => ({
261
+ let a = yield* Ot(t, r.a, e, o.right).pipe(C.map((e) => ({
224
262
  ok: !0,
225
263
  r: e
226
- })), x.catchAll((e) => x.succeed({
264
+ })), C.catchAll((e) => C.succeed({
227
265
  ok: !1,
228
266
  e
229
267
  })));
230
- return i.ok ? {
231
- value: i.r.text,
232
- text: i.r.text,
233
- costMicroUsd: q(i.r.usage, i.r.providerMetadata, r.a.model)
234
- } : { error: String(i.e.message ?? i.e) };
268
+ return a.ok ? {
269
+ value: a.r.text,
270
+ text: a.r.text,
271
+ costMicroUsd: q(a.r.usage, a.r.providerMetadata, r.a.model)
272
+ } : { error: String(a.e.message ?? a.e) };
235
273
  }
236
274
  case "structured": {
237
- let r = n.model ?? t.defaultModels?.text, i = yield* Re({
275
+ if (n.schema === void 0) return { error: `step "${n.id}": structured step requires a JSON Schema` };
276
+ let r = n.model ?? t.defaultModels?.text, i = yield* Ge({
277
+ ...o.right,
238
278
  prompt: e,
239
- schema: ft(n.schema),
279
+ jsonSchema: n.schema,
240
280
  ...r ? { provider: K(t, r) } : {}
241
- }).pipe(x.map((e) => ({
281
+ }).pipe(C.map((e) => ({
242
282
  ok: !0,
243
283
  r: e
244
- })), x.catchAll((e) => x.succeed({
284
+ })), C.catchAll((e) => C.succeed({
245
285
  ok: !1,
246
286
  e
247
287
  })));
@@ -252,15 +292,16 @@ var M = Ae("_voltro_ai_flows", {
252
292
  } : { error: String(i.e.message ?? i.e) };
253
293
  }
254
294
  case "generate": {
255
- let r = n.modality ?? "text";
256
- if (r === "text") {
257
- let r = n.model ?? t.defaultModels?.text, i = yield* j({
295
+ let s = n.modality ?? "text";
296
+ if (s === "text") {
297
+ let r = n.model ?? t.defaultModels?.text, i = yield* Je({
298
+ ...o.right,
258
299
  prompt: e,
259
300
  ...r ? { provider: K(t, r) } : {}
260
- }).pipe(x.map((e) => ({
301
+ }).pipe(C.map((e) => ({
261
302
  ok: !0,
262
303
  r: e
263
- })), x.catchAll((e) => x.succeed({
304
+ })), C.catchAll((e) => C.succeed({
264
305
  ok: !1,
265
306
  e
266
307
  })));
@@ -270,285 +311,287 @@ var M = Ae("_voltro_ai_flows", {
270
311
  costMicroUsd: q(i.r.usage, i.r.providerMetadata, r)
271
312
  } : { error: String(i.e.message ?? i.e) };
272
313
  }
273
- if (!t.generateMedia) return { error: new y({
274
- capability: `media:${r}`,
275
- message: `no media generator configured for ${r}`
314
+ if (!t.generateMedia) return { error: new x({
315
+ capability: `media:${s}`,
316
+ message: `no media generator configured for ${s}`
276
317
  }).message };
277
- let a = n.model ?? t.defaultModels?.[r], o = yield* W(t.generateMedia({
278
- modality: r,
279
- ...a ? { model: a } : {},
318
+ let c = yield* bt(n.mediaInputs, r, a).pipe(C.either);
319
+ if (c._tag === "Left") return { error: `step "${n.id}": ${c.left}` };
320
+ let l = n.model ?? t.defaultModels?.[s], u = yield* W(t.generateMedia({
321
+ modality: s,
322
+ ...l ? { model: l } : {},
280
323
  prompt: e,
281
324
  ...n.params ? { params: n.params } : {},
325
+ ...n.mediaInputs === void 0 ? {} : { inputs: c.right },
282
326
  run: i
283
- })).pipe(x.map((e) => ({
327
+ })).pipe(C.map((e) => ({
284
328
  ok: !0,
285
329
  m: e
286
- })), x.catchAll((e) => x.succeed({
330
+ })), C.catchAll((e) => C.succeed({
287
331
  ok: !1,
288
332
  e
289
333
  })));
290
- return o.ok ? {
291
- value: o.m.url,
292
- url: o.m.url,
293
- ...o.m.requestId ? { requestId: o.m.requestId } : {},
294
- costMicroUsd: o.m.costMicroUsd ?? 0
295
- } : { error: o.e.message };
334
+ return u.ok ? yield* Tt(u.m) : { error: u.e.message };
296
335
  }
297
- case "human": return { error: new y({
336
+ case "human": return { error: new x({
298
337
  capability: "human",
299
338
  message: "human step reached the step interpreter — it should have been parked by the deterministic executor (routing bug)"
300
339
  }).message };
301
340
  default: return { error: `unknown step type: ${String(n.type)}` };
302
341
  }
303
- }), _t = (t, n, r, i, a, o) => x.gen(function* () {
304
- let s = { ...a }, c = i.steps.map((e, t) => ({
342
+ }), jt = (e, t, n, r, o, s) => C.gen(function* () {
343
+ let c = Object.assign(Object.create(null), o), l = Object.create(null), u = r.steps.map((e, t) => ({
305
344
  id: t,
306
345
  title: e.title ?? `Step ${t + 1}`,
307
346
  type: e.type,
308
347
  status: "pending",
309
348
  ...e.description ? { description: e.description } : {}
310
- })), l = 0;
311
- yield* J(t, r, {
349
+ })), d = 0;
350
+ yield* J(e, n, {
312
351
  status: "running",
313
- steps: c,
314
- totalSteps: i.steps.length,
352
+ steps: u,
353
+ totalSteps: r.steps.length,
315
354
  currentStep: 0,
316
355
  startedAt: G()
317
356
  });
318
- for (let a of R(i.steps)) {
319
- if (yield* ht(t, r)) return {
320
- runId: r,
357
+ for (let o of z(r.steps)) {
358
+ if (yield* kt(e, n)) return {
359
+ runId: n,
321
360
  status: "cancelled"
322
361
  };
323
- if (a.steps.length > 1) {
324
- let i = [];
325
- for (let { index: t, step: n } of a.steps) {
326
- if (n.when !== void 0 && !g(n.when, s)) {
327
- c[t] = {
328
- ...c[t],
362
+ if (o.steps.length > 1) {
363
+ let r = [];
364
+ for (let { index: e, step: t } of o.steps) {
365
+ if (t.when !== void 0 && !a(t.when, c)) {
366
+ u[e] = {
367
+ ...u[e],
329
368
  status: "skipped",
330
369
  completedAt: G(),
331
- skipReason: e(n.when)
370
+ skipReason: i(t.when)
332
371
  };
333
372
  continue;
334
373
  }
335
- i.push({
336
- index: t,
337
- step: n
338
- }), c[t] = {
339
- ...c[t],
374
+ r.push({
375
+ index: e,
376
+ step: t
377
+ }), u[e] = {
378
+ ...u[e],
340
379
  status: "running",
341
380
  startedAt: G()
342
381
  };
343
382
  }
344
- yield* J(t, r, {
345
- steps: c,
346
- currentStep: a.steps[0].index
383
+ yield* J(e, n, {
384
+ steps: u,
385
+ currentStep: o.steps[0].index
347
386
  });
348
- let u = yield* x.all(i.map(({ index: e, step: i }) => k({
349
- name: `flow-${e}-${i.id}`,
350
- input: { index: e },
351
- success: pt,
352
- execute: gt(t, n, i, s, {
353
- runId: r,
354
- tenantId: o.tenantId
355
- })
356
- }).pipe(x.map((t) => ({
357
- index: e,
387
+ let f = yield* C.all(r.map(({ index: r, step: i }) => j({
388
+ name: `flow-${r}-${i.id}`,
389
+ input: { index: r },
390
+ success: wt,
391
+ execute: At(e, t, i, c, {
392
+ runId: n,
393
+ tenantId: s.tenantId
394
+ }, l)
395
+ }).pipe(C.map((e) => ({
396
+ index: r,
358
397
  step: i,
359
- result: t
360
- })))), { concurrency: "unbounded" }), d = u.find((e) => e.result.error);
361
- for (let { index: e, step: t, result: n } of u) {
398
+ result: e
399
+ })))), { concurrency: "unbounded" }), p = f.find((e) => e.result.error);
400
+ for (let { index: e, step: t, result: n } of f) {
362
401
  if (n.error) {
363
- c[e] = {
364
- ...c[e],
402
+ u[e] = {
403
+ ...u[e],
365
404
  status: "failed",
366
405
  completedAt: G(),
367
406
  errorMessage: n.error
368
407
  };
369
408
  continue;
370
409
  }
371
- t.outputKey && n.value !== void 0 && (s[t.outputKey] = n.value), l += n.costMicroUsd ?? 0, c[e] = {
372
- ...c[e],
410
+ t.outputKey && n.value !== void 0 && (c[t.outputKey] = n.value), t.outputKey && n.artifacts !== void 0 && (l[t.outputKey] = n.artifacts), d += n.costMicroUsd ?? 0, u[e] = {
411
+ ...u[e],
373
412
  status: "succeeded",
374
413
  completedAt: G(),
375
414
  ...n.text ? { output: { text: n.text } } : {},
376
415
  ...n.url ? { url: n.url } : {},
416
+ ...n.artifacts === void 0 ? {} : { artifacts: n.artifacts },
377
417
  ...n.requestId ? { requestId: n.requestId } : {},
378
418
  ...n.costMicroUsd ? { costMicroUsd: n.costMicroUsd } : {}
379
419
  };
380
420
  }
381
- if (d !== void 0) return yield* J(t, r, {
382
- steps: c,
421
+ if (p !== void 0) return yield* J(e, n, {
422
+ steps: u,
383
423
  status: "failed",
384
- errorMessage: d.result.error,
424
+ errorMessage: p.result.error,
385
425
  completedAt: G(),
386
- costMicroUsd: l
426
+ costMicroUsd: d
387
427
  }), {
388
- runId: r,
428
+ runId: n,
389
429
  status: "failed"
390
430
  };
391
- yield* J(t, r, {
392
- steps: c,
393
- currentStep: a.steps[a.steps.length - 1].index + 1,
394
- costMicroUsd: l
431
+ yield* J(e, n, {
432
+ steps: u,
433
+ currentStep: o.steps[o.steps.length - 1].index + 1,
434
+ costMicroUsd: d
395
435
  });
396
436
  continue;
397
437
  }
398
- let { index: u, step: f } = a.steps[0];
399
- if (f.when !== void 0 && !g(f.when, s)) {
400
- c[u] = {
401
- ...c[u],
438
+ let { index: f, step: p } = o.steps[0];
439
+ if (p.when !== void 0 && !a(p.when, c)) {
440
+ u[f] = {
441
+ ...u[f],
402
442
  status: "skipped",
403
443
  completedAt: G(),
404
- skipReason: e(f.when)
405
- }, yield* J(t, r, {
406
- steps: c,
407
- currentStep: u + 1
444
+ skipReason: i(p.when)
445
+ }, yield* J(e, n, {
446
+ steps: u,
447
+ currentStep: f + 1
408
448
  });
409
449
  continue;
410
450
  }
411
- if (f.type === "human") {
412
- let e = {
413
- mode: f.reviewMode ?? "approve",
414
- ...f.options ? { options: f.options } : {},
415
- prompt: L(f.prompt ?? "", s)
451
+ if (p.type === "human") {
452
+ let i = {
453
+ mode: p.reviewMode ?? "approve",
454
+ ...p.options ? { options: p.options } : {},
455
+ prompt: R(p.prompt ?? "", c)
416
456
  };
417
- c[u] = {
418
- ...c[u],
457
+ u[f] = {
458
+ ...u[f],
419
459
  status: "waiting",
420
460
  startedAt: G(),
421
- review: e
422
- }, yield* J(t, r, {
423
- steps: c,
461
+ review: i
462
+ }, yield* J(e, n, {
463
+ steps: u,
424
464
  status: "waiting",
425
- currentStep: u
426
- }), n.onEvent && (yield* W(n.onEvent({
465
+ currentStep: f
466
+ }), t.onEvent && (yield* W(t.onEvent({
427
467
  kind: "review-needed",
428
- runId: r,
429
- flowName: i.name,
430
- ownerId: o.ownerId,
431
- source: o.source
432
- })).pipe(x.catchAllCause(() => x.void)));
433
- let a = $e({
434
- step: f,
435
- flow: i,
436
- deps: n
437
- }), p = yield* Pe(t, {
438
- name: v(u),
439
- schema: d,
468
+ runId: n,
469
+ flowName: r.name,
470
+ ownerId: s.ownerId,
471
+ source: s.source
472
+ })).pipe(C.catchAllCause(() => C.void)));
473
+ let a = ct({
474
+ step: p,
475
+ flow: r,
476
+ deps: t
477
+ }), o = yield* Be(e, {
478
+ name: b(f),
479
+ schema: g,
440
480
  timeoutMs: a
441
- }).pipe(x.map((e) => ({
481
+ }).pipe(C.map((e) => ({
442
482
  ok: !0,
443
483
  a: e
444
- })), x.catchAllCause((e) => Ce.isInterruptedOnly(e) ? x.failCause(e) : x.succeed({
484
+ })), C.catchAllCause((e) => Oe.isInterruptedOnly(e) ? C.failCause(e) : C.succeed({
445
485
  ok: !1,
446
486
  cause: e
447
487
  })));
448
- if (!p.ok) {
449
- let e = Number.isFinite(a) ? `human review timed out after ${a}ms` : "human review failed";
450
- return c[u] = {
451
- ...c[u],
488
+ if (!o.ok) {
489
+ let t = Number.isFinite(a) ? `human review timed out after ${a}ms` : "human review failed";
490
+ return u[f] = {
491
+ ...u[f],
452
492
  status: "failed",
453
493
  completedAt: G(),
454
- errorMessage: e
455
- }, yield* J(t, r, {
456
- steps: c,
494
+ errorMessage: t
495
+ }, yield* J(e, n, {
496
+ steps: u,
457
497
  status: "failed",
458
- errorMessage: e,
498
+ errorMessage: t,
459
499
  completedAt: G(),
460
- costMicroUsd: l
500
+ costMicroUsd: d
461
501
  }), {
462
- runId: r,
502
+ runId: n,
463
503
  status: "failed"
464
504
  };
465
505
  }
466
- let m = p.a;
467
- if (m.decision === "reject") return c[u] = {
468
- ...c[u],
506
+ let l = o.a;
507
+ if (l.decision === "reject") return u[f] = {
508
+ ...u[f],
469
509
  status: "failed",
470
510
  completedAt: G(),
471
511
  errorMessage: "rejected by reviewer"
472
- }, yield* J(t, r, {
473
- steps: c,
512
+ }, yield* J(e, n, {
513
+ steps: u,
474
514
  status: "cancelled",
515
+ humanResponse: l,
475
516
  completedAt: G(),
476
- costMicroUsd: l
517
+ costMicroUsd: d
477
518
  }), {
478
- runId: r,
519
+ runId: n,
479
520
  status: "cancelled"
480
521
  };
481
- f.outputKey && (s[f.outputKey] = m.value ?? m.text ?? m.decision ?? !0), c[u] = {
482
- ...c[u],
522
+ p.outputKey && (c[p.outputKey] = l.value ?? l.text ?? l.decision ?? !0), u[f] = {
523
+ ...u[f],
483
524
  status: "succeeded",
484
525
  completedAt: G(),
485
- output: { text: String(m.text ?? m.value ?? m.decision ?? "approved") }
486
- }, yield* J(t, r, {
487
- steps: c,
526
+ output: { text: String(l.text ?? l.value ?? l.decision ?? "approved") }
527
+ }, yield* J(e, n, {
528
+ steps: u,
488
529
  status: "running",
489
- currentStep: u + 1
530
+ humanResponse: l,
531
+ currentStep: f + 1
490
532
  });
491
533
  continue;
492
534
  }
493
- c[u] = {
494
- ...c[u],
535
+ u[f] = {
536
+ ...u[f],
495
537
  status: "running",
496
538
  startedAt: G()
497
- }, yield* J(t, r, {
498
- steps: c,
499
- currentStep: u
539
+ }, yield* J(e, n, {
540
+ steps: u,
541
+ currentStep: f
500
542
  });
501
- let p = yield* k({
502
- name: `flow-${u}-${f.id}`,
503
- input: { index: u },
504
- success: pt,
505
- execute: gt(t, n, f, s, {
506
- runId: r,
507
- tenantId: o.tenantId
508
- })
543
+ let m = yield* j({
544
+ name: `flow-${f}-${p.id}`,
545
+ input: { index: f },
546
+ success: wt,
547
+ execute: At(e, t, p, c, {
548
+ runId: n,
549
+ tenantId: s.tenantId
550
+ }, l)
509
551
  });
510
- if (p.error) return c[u] = {
511
- ...c[u],
552
+ if (m.error) return u[f] = {
553
+ ...u[f],
512
554
  status: "failed",
513
555
  completedAt: G(),
514
- errorMessage: p.error
515
- }, yield* J(t, r, {
516
- steps: c,
556
+ errorMessage: m.error
557
+ }, yield* J(e, n, {
558
+ steps: u,
517
559
  status: "failed",
518
- errorMessage: p.error,
560
+ errorMessage: m.error,
519
561
  completedAt: G(),
520
- costMicroUsd: l
562
+ costMicroUsd: d
521
563
  }), {
522
- runId: r,
564
+ runId: n,
523
565
  status: "failed"
524
566
  };
525
- f.outputKey && p.value !== void 0 && (s[f.outputKey] = p.value), l += p.costMicroUsd ?? 0, c[u] = {
526
- ...c[u],
567
+ p.outputKey && m.value !== void 0 && (c[p.outputKey] = m.value), p.outputKey && m.artifacts !== void 0 && (l[p.outputKey] = m.artifacts), d += m.costMicroUsd ?? 0, u[f] = {
568
+ ...u[f],
527
569
  status: "succeeded",
528
570
  completedAt: G(),
529
- ...p.text ? { output: { text: p.text } } : {},
530
- ...p.url ? { url: p.url } : {},
531
- ...p.requestId ? { requestId: p.requestId } : {},
532
- ...p.costMicroUsd ? { costMicroUsd: p.costMicroUsd } : {}
533
- }, yield* J(t, r, {
534
- steps: c,
535
- currentStep: u + 1,
536
- costMicroUsd: l
571
+ ...m.text ? { output: { text: m.text } } : {},
572
+ ...m.url ? { url: m.url } : {},
573
+ ...m.artifacts === void 0 ? {} : { artifacts: m.artifacts },
574
+ ...m.requestId ? { requestId: m.requestId } : {},
575
+ ...m.costMicroUsd ? { costMicroUsd: m.costMicroUsd } : {}
576
+ }, yield* J(e, n, {
577
+ steps: u,
578
+ currentStep: f + 1,
579
+ costMicroUsd: d
537
580
  });
538
581
  }
539
- let u = {};
540
- for (let e of i.steps) e.outputKey && s[e.outputKey] !== void 0 && (u[e.outputKey] = s[e.outputKey]);
541
- return yield* J(t, r, {
582
+ let f = Object.create(null);
583
+ for (let e of r.steps) e.outputKey && c[e.outputKey] !== void 0 && (f[e.outputKey] = c[e.outputKey]);
584
+ return yield* J(e, n, {
542
585
  status: "succeeded",
543
- output: u,
586
+ output: f,
544
587
  completedAt: G(),
545
- costMicroUsd: l
588
+ costMicroUsd: d
546
589
  }), {
547
- runId: r,
590
+ runId: n,
548
591
  status: "succeeded",
549
- output: u
592
+ output: f
550
593
  };
551
- }), vt = (e, t, n, r, i, a, o) => x.gen(function* () {
594
+ }), Mt = (e, t, n, r, i, a, o) => C.gen(function* () {
552
595
  let s = n.chain;
553
596
  if (!s) return;
554
597
  let c = [...a.chainPath ?? [], a.flowRef];
@@ -557,7 +600,7 @@ var M = Ae("_voltro_ai_flows", {
557
600
  yield* J(e, t, { chainRefusal: `chain to "${s.flowRef}" refused — it is already in this run's chain (${c.join(" → ")}), which would loop` });
558
601
  return;
559
602
  }
560
- let l = et(o);
603
+ let l = lt(o);
561
604
  if (c.length >= l) {
562
605
  yield* J(e, t, { chainRefusal: `chain to "${s.flowRef}" refused — depth ${c.length} reached the limit of ${l} (${c.join(" → ")})` });
563
606
  return;
@@ -578,9 +621,9 @@ var M = Ae("_voltro_ai_flows", {
578
621
  let f = e.workflows;
579
622
  if (!f) return;
580
623
  let p = `${t}--chain`, m = `${a.requestId}--chain`;
581
- yield* x.promise(async () => {
624
+ yield* C.promise(async () => {
582
625
  try {
583
- await e.store.insert(N.tableName, {
626
+ await e.store.insert(P.tableName, {
584
627
  id: p,
585
628
  flowRef: s.flowRef,
586
629
  flowName: s.flowRef,
@@ -598,276 +641,322 @@ var M = Ae("_voltro_ai_flows", {
598
641
  requestId: m,
599
642
  chainPath: c
600
643
  });
601
- }).pipe(x.catchAllCause(() => x.void));
602
- }), yt = (e) => e.steps.length === 0 ? "" : "Suggested plan (you MAY reorder, insert, or skip steps):\n" + e.steps.map((e, t) => `${t + 1}. [${e.type}${e.modality ? `/${e.modality}` : ""}] ${e.title ?? e.id}${e.prompt ? `: ${e.prompt}` : ""}`).join("\n"), bt = (e) => {
644
+ }).pipe(C.catchAllCause(() => C.void));
645
+ }), Nt = (e) => e.steps.length === 0 ? "" : "Suggested plan (you MAY reorder, insert, or skip steps):\n" + e.steps.map((e, t) => `${t + 1}. [${e.type}${e.modality ? `/${e.modality}` : ""}] ${e.title ?? e.id}${e.prompt ? `: ${e.prompt}` : ""}`).join("\n"), Pt = (e) => {
603
646
  let t = Object.entries(e);
604
647
  return t.length === 0 ? "Execute the flow." : "Brief for this run:\n" + t.map(([e, t]) => `- ${e}: ${typeof t == "string" ? t : JSON.stringify(t)}`).join("\n");
605
- }, xt = (e) => [
648
+ }, Ft = (e) => [
606
649
  e.orchestrator?.instructions ?? "You are an orchestrator that uses the available tools to produce a bundled result.",
607
- yt(e),
650
+ Nt(e),
608
651
  "When finished, emit a JSON object mapping each deliverable name (outputKey) to its value."
609
- ].filter(Boolean).join("\n\n"), St = S.Struct({
610
- object: S.Record({
611
- key: S.String,
612
- value: S.Unknown
652
+ ].filter(Boolean).join("\n\n"), It = w.Struct({
653
+ object: w.Record({
654
+ key: w.String,
655
+ value: w.Unknown
613
656
  }),
614
- planCostMicroUsd: S.Number,
615
- toolCostMicroUsd: S.Number,
616
- steps: S.Array(pe),
617
- error: S.optional(S.String)
618
- }), Ct = (e, t, n, r, i, a, o) => x.gen(function* () {
657
+ planCostMicroUsd: w.Number,
658
+ toolCostMicroUsd: w.Number,
659
+ steps: w.Array(r),
660
+ error: w.optional(w.String)
661
+ }), Lt = (e, t, n, r, i, a, o, s) => C.gen(function* () {
619
662
  yield* J(e, n, {
620
663
  status: "running",
621
664
  startedAt: G(),
622
665
  totalSteps: r.steps.length
623
666
  });
624
- let s = yield* k({
667
+ let c = yield* j({
625
668
  name: "flow-agentic",
626
669
  input: { flowRef: r.name },
627
- success: St,
628
- execute: x.gen(function* () {
629
- let s = [], c = 0, l = (e) => {
630
- let t = s.length;
631
- return s.push({
670
+ success: It,
671
+ execute: C.gen(function* () {
672
+ let c = [], l = 0, u = (e) => {
673
+ let t = c.length;
674
+ return c.push({
632
675
  id: t,
633
676
  status: "running",
634
677
  startedAt: G(),
635
678
  ...e
636
679
  }), t;
637
- }, u = (e, t) => {
638
- s[e] = {
639
- ...s[e],
680
+ }, d = (e, t) => {
681
+ c[e] = {
682
+ ...c[e],
640
683
  completedAt: G(),
641
684
  ...t
642
685
  };
643
- }, d = () => J(e, n, {
644
- steps: s,
645
- currentStep: s.length,
646
- costMicroUsd: c
647
- }), f = A({
648
- name: "run_agent",
649
- description: "Delegate a text task to an allowed sub-agent. Returns the agent's text.",
650
- input: S.Struct({
651
- agentRef: S.String,
652
- prompt: S.String
653
- }),
654
- execute: ({ agentRef: e, prompt: n }) => x.gen(function* () {
655
- let r = l({
656
- title: `agent:${e}`,
657
- type: "agent"
658
- });
659
- if (yield* d(), !t.resolveAgent) return u(r, {
660
- status: "failed",
661
- errorMessage: "no agent resolver configured"
662
- }), yield* d(), "ERROR: no agent resolver configured";
663
- let i = yield* W(t.resolveAgent(e)).pipe(x.map((e) => ({
664
- ok: !0,
665
- a: e
666
- })), x.catchAll((e) => x.succeed({
667
- ok: !1,
668
- e
669
- })));
670
- if (!i.ok) return u(r, {
671
- status: "failed",
672
- errorMessage: i.e.message
673
- }), yield* d(), `ERROR: ${i.e.message}`;
674
- let a = yield* j({
675
- system: i.a.system,
676
- prompt: n,
677
- provider: K(t, i.a.model)
678
- }).pipe(x.map((e) => ({
679
- ok: !0,
680
- r: e
681
- })), x.catchAll((e) => x.succeed({
682
- ok: !1,
683
- e
684
- })));
685
- if (!a.ok) {
686
- let e = String(a.e.message ?? a.e);
687
- return u(r, {
686
+ }, f = () => J(e, n, {
687
+ steps: c,
688
+ currentStep: c.length,
689
+ costMicroUsd: l
690
+ }), p = {
691
+ run_agent: M({
692
+ name: "run_agent",
693
+ description: "Delegate a text task to an allowed sub-agent. Returns the agent's text.",
694
+ input: w.Struct({
695
+ agentRef: w.String,
696
+ prompt: w.String
697
+ }),
698
+ execute: ({ agentRef: e, prompt: r }) => C.gen(function* () {
699
+ let i = u({
700
+ title: `agent:${e}`,
701
+ type: "agent"
702
+ });
703
+ if (yield* f(), !t.resolveAgent) return d(i, {
688
704
  status: "failed",
689
- errorMessage: e
690
- }), yield* d(), `ERROR: ${e}`;
691
- }
692
- let o = q(a.r.usage, a.r.providerMetadata, i.a.model);
693
- return c += o, u(r, {
694
- status: "succeeded",
695
- output: { text: a.r.text },
696
- costMicroUsd: o
697
- }), yield* d(), a.r.text;
698
- })
699
- }), p = A({
700
- name: "generate_media",
701
- description: "Generate an image, video, or audio artifact. Returns the hosted URL.",
702
- input: S.Struct({
703
- modality: S.Literal("image", "video", "audio"),
704
- prompt: S.String,
705
- model: S.optional(S.String)
706
- }),
707
- execute: ({ modality: e, prompt: r, model: i }) => x.gen(function* () {
708
- let a = l({
709
- title: `media:${e}`,
710
- type: "generate"
711
- });
712
- if (yield* d(), !t.generateMedia) return u(a, {
713
- status: "failed",
714
- errorMessage: `no media generator for ${e}`
715
- }), yield* d(), `ERROR: no media generator configured for ${e}`;
716
- let s = yield* W(t.generateMedia({
717
- modality: e,
718
- prompt: r,
719
- ...i ? { model: i } : {},
720
- run: {
705
+ errorMessage: "no agent resolver configured"
706
+ }), yield* f(), "ERROR: no agent resolver configured";
707
+ let a = yield* W(t.resolveAgent(e, {
721
708
  runId: n,
722
709
  tenantId: o
710
+ })).pipe(C.map((e) => ({
711
+ ok: !0,
712
+ a: e
713
+ })), C.catchAll((e) => C.succeed({
714
+ ok: !1,
715
+ e
716
+ })));
717
+ if (!a.ok) return d(i, {
718
+ status: "failed",
719
+ errorMessage: a.e.message
720
+ }), yield* f(), `ERROR: ${a.e.message}`;
721
+ let s = yield* Ot(t, a.a, r, {}).pipe(C.map((e) => ({
722
+ ok: !0,
723
+ r: e
724
+ })), C.catchAll((e) => C.succeed({
725
+ ok: !1,
726
+ e
727
+ })));
728
+ if (!s.ok) {
729
+ let e = String(s.e.message ?? s.e);
730
+ return d(i, {
731
+ status: "failed",
732
+ errorMessage: e
733
+ }), yield* f(), `ERROR: ${e}`;
723
734
  }
724
- })).pipe(x.map((e) => ({
725
- ok: !0,
726
- r: e
727
- })), x.catchAll((e) => x.succeed({
728
- ok: !1,
729
- e
730
- })));
731
- return s.ok ? (c += s.r.costMicroUsd ?? 0, u(a, {
732
- status: "succeeded",
733
- url: s.r.url,
734
- ...s.r.requestId ? { requestId: s.r.requestId } : {},
735
- costMicroUsd: s.r.costMicroUsd ?? 0
736
- }), yield* d(), s.r.url) : (u(a, {
737
- status: "failed",
738
- errorMessage: s.e.message
739
- }), yield* d(), `ERROR: ${s.e.message}`);
740
- })
741
- }), m = A({
742
- name: "pick_structured",
743
- description: "Produce a JSON object for a task. Returns the object.",
744
- input: S.Struct({
745
- prompt: S.String,
746
- model: S.optional(S.String)
735
+ let c = q(s.r.usage, s.r.providerMetadata, a.a.model);
736
+ return l += c, d(i, {
737
+ status: "succeeded",
738
+ output: { text: s.r.text },
739
+ costMicroUsd: c
740
+ }), yield* f(), s.r.text;
741
+ })
747
742
  }),
748
- execute: ({ prompt: e, model: n }) => x.gen(function* () {
749
- let r = l({
750
- title: "structured",
751
- type: "structured"
752
- });
753
- yield* d();
754
- let i = yield* Re({
755
- prompt: e,
756
- schema: S.Record({
757
- key: S.String,
758
- value: S.Unknown
759
- }),
760
- ...n ? { provider: K(t, n) } : {}
761
- }).pipe(x.map((e) => ({
762
- ok: !0,
763
- r: e
764
- })), x.catchAll((e) => x.succeed({
765
- ok: !1,
766
- e
767
- })));
768
- if (!i.ok) {
769
- let e = String(i.e.message ?? i.e);
770
- return u(r, {
743
+ generate_media: M({
744
+ name: "generate_media",
745
+ description: "Generate image, video, or audio artifacts. Returns every artifact with its URL, role, media type and optional storage reference.",
746
+ input: w.Struct({
747
+ modality: w.Literal("image", "video", "audio"),
748
+ prompt: w.String,
749
+ model: w.optional(w.String),
750
+ inputs: w.optional(U),
751
+ params: w.optional(w.Record({
752
+ key: w.String,
753
+ value: w.Unknown
754
+ }))
755
+ }),
756
+ execute: ({ modality: e, prompt: r, model: i, inputs: a, params: s }) => C.gen(function* () {
757
+ let c = u({
758
+ title: `media:${e}`,
759
+ type: "generate"
760
+ });
761
+ if (yield* f(), !t.generateMedia) return d(c, {
762
+ status: "failed",
763
+ errorMessage: `no media generator for ${e}`
764
+ }), yield* f(), `ERROR: no media generator configured for ${e}`;
765
+ let p = yield* W(t.generateMedia({
766
+ modality: e,
767
+ prompt: r,
768
+ ...i ? { model: i } : {},
769
+ ...a === void 0 ? {} : { inputs: a },
770
+ ...s === void 0 ? {} : { params: s },
771
+ run: {
772
+ runId: n,
773
+ tenantId: o
774
+ }
775
+ })).pipe(C.map((e) => ({
776
+ ok: !0,
777
+ r: e
778
+ })), C.catchAll((e) => C.succeed({
779
+ ok: !1,
780
+ e
781
+ })));
782
+ if (!p.ok) return d(c, {
771
783
  status: "failed",
772
- errorMessage: e
773
- }), yield* d(), { error: e };
774
- }
775
- let a = q(i.r.usage, i.r.providerMetadata, n);
776
- return c += a, u(r, {
777
- status: "succeeded",
778
- output: { text: JSON.stringify(i.r.object) },
779
- costMicroUsd: a
780
- }), yield* d(), i.r.object;
784
+ errorMessage: p.e.message
785
+ }), yield* f(), `ERROR: ${p.e.message}`;
786
+ let m = yield* Tt(p.r);
787
+ return m.error ? (d(c, {
788
+ status: "failed",
789
+ errorMessage: m.error
790
+ }), yield* f(), { error: m.error }) : (l += m.costMicroUsd ?? 0, d(c, {
791
+ status: "succeeded",
792
+ url: m.url,
793
+ artifacts: m.artifacts,
794
+ ...m.requestId ? { requestId: m.requestId } : {},
795
+ costMicroUsd: m.costMicroUsd ?? 0
796
+ }), yield* f(), { artifacts: m.artifacts });
797
+ })
798
+ }),
799
+ pick_structured: M({
800
+ name: "pick_structured",
801
+ description: "Produce a JSON object for a task. Returns the object.",
802
+ input: w.Struct({
803
+ prompt: w.String,
804
+ model: w.optional(w.String)
805
+ }),
806
+ execute: ({ prompt: e, model: n }) => C.gen(function* () {
807
+ let r = u({
808
+ title: "structured",
809
+ type: "structured"
810
+ });
811
+ yield* f();
812
+ let i = yield* We({
813
+ prompt: e,
814
+ schema: w.Record({
815
+ key: w.String,
816
+ value: w.Unknown
817
+ }),
818
+ ...n ? { provider: K(t, n) } : {}
819
+ }).pipe(C.map((e) => ({
820
+ ok: !0,
821
+ r: e
822
+ })), C.catchAll((e) => C.succeed({
823
+ ok: !1,
824
+ e
825
+ })));
826
+ if (!i.ok) {
827
+ let e = String(i.e.message ?? i.e);
828
+ return d(r, {
829
+ status: "failed",
830
+ errorMessage: e
831
+ }), yield* f(), { error: e };
832
+ }
833
+ let a = q(i.r.usage, i.r.providerMetadata, n);
834
+ return l += a, d(r, {
835
+ status: "succeeded",
836
+ output: { text: JSON.stringify(i.r.object) },
837
+ costMicroUsd: a
838
+ }), yield* f(), i.r.object;
839
+ })
781
840
  })
782
- }), h = t.memoryPrefix ? yield* W(t.memoryPrefix(a)).pipe(x.catchAll(() => x.succeed(""))) : "", ee = h ? `${h}\n\n${xt(r)}` : xt(r), g = yield* ze({
783
- system: ee,
784
- prompt: bt(i),
785
- schema: S.Record({
786
- key: S.String,
787
- value: S.Unknown
841
+ }, m = yield* (t.resolveTools ? W(t.resolveTools(s, {
842
+ runId: n,
843
+ tenantId: o
844
+ })) : C.succeed({})).pipe(C.either);
845
+ if (m._tag === "Left") return {
846
+ object: {},
847
+ planCostMicroUsd: 0,
848
+ toolCostMicroUsd: 0,
849
+ steps: c,
850
+ error: "flow tool resolution failed"
851
+ };
852
+ if (Object.keys(m.right).some((e) => Object.hasOwn(p, e))) return {
853
+ object: {},
854
+ planCostMicroUsd: 0,
855
+ toolCostMicroUsd: 0,
856
+ steps: c,
857
+ error: "flow tools cannot replace reserved planner tools"
858
+ };
859
+ let ee = t.memoryPrefix ? yield* W(t.memoryPrefix(a)).pipe(C.catchAll(() => C.succeed(""))) : "", h = ee ? `${ee}\n\n${Ft(r)}` : Ft(r), g = yield* Ke({
860
+ system: h,
861
+ prompt: Pt(i),
862
+ schema: w.Record({
863
+ key: w.String,
864
+ value: w.Unknown
788
865
  }),
789
866
  tools: {
790
- run_agent: f,
791
- generate_media: p,
792
- pick_structured: m
867
+ ...m.right,
868
+ ...p
793
869
  },
794
870
  maxSteps: r.maxSteps,
795
871
  ...r.orchestrator?.model ? { provider: K(t, r.orchestrator.model) } : {}
796
- }).pipe(x.map((e) => ({
872
+ }).pipe(C.map((e) => ({
797
873
  ok: !0,
798
874
  r: e
799
- })), x.catchAll((e) => x.succeed({
875
+ })), C.catchAll((e) => C.succeed({
800
876
  ok: !1,
801
877
  e
802
878
  })));
803
879
  return g.ok ? {
804
880
  object: g.r.object,
805
881
  planCostMicroUsd: q(g.r.usage, g.r.providerMetadata, r.orchestrator?.model),
806
- toolCostMicroUsd: c,
807
- steps: s
882
+ toolCostMicroUsd: l,
883
+ steps: c
808
884
  } : {
809
885
  object: {},
810
886
  planCostMicroUsd: 0,
811
- toolCostMicroUsd: c,
812
- steps: s,
887
+ toolCostMicroUsd: l,
888
+ steps: c,
813
889
  error: String(g.e.message ?? g.e)
814
890
  };
815
891
  })
816
- }), c = s.planCostMicroUsd + s.toolCostMicroUsd;
817
- return s.error ? (yield* J(e, n, {
892
+ }), l = c.planCostMicroUsd + c.toolCostMicroUsd;
893
+ return c.error ? (yield* J(e, n, {
818
894
  status: "failed",
819
- steps: s.steps,
820
- errorMessage: s.error,
895
+ steps: c.steps,
896
+ errorMessage: c.error,
821
897
  completedAt: G(),
822
- costMicroUsd: c
898
+ costMicroUsd: l
823
899
  }), {
824
900
  runId: n,
825
901
  status: "failed"
826
902
  }) : (yield* J(e, n, {
827
903
  status: "succeeded",
828
- steps: s.steps,
829
- output: s.object,
904
+ steps: c.steps,
905
+ output: c.object,
830
906
  completedAt: G(),
831
- costMicroUsd: c
907
+ costMicroUsd: l
832
908
  }), {
833
909
  runId: n,
834
910
  status: "succeeded",
835
- output: s.object
911
+ output: c.object
836
912
  });
837
- }), wt = (e, t = {}) => (n, r) => x.gen(function* () {
838
- let { runId: r, flowRef: i, input: a } = n, o = yield* k({
913
+ }), Rt = (e, t = {}) => (n, r) => C.gen(function* () {
914
+ let { runId: r, flowRef: i, input: a } = n, o = yield* C.tryPromise(() => e.store.query(O(P).where(T("id", r)).descriptor)).pipe(C.flatMap(w.decodeUnknown(w.Tuple(w.Struct({
915
+ id: w.Literal(r),
916
+ tenantId: w.NullOr(w.NonEmptyString),
917
+ ownerId: w.optional(w.NullOr(w.String))
918
+ })))), C.either);
919
+ if (o._tag === "Left") return yield* J(e, r, {
920
+ status: "failed",
921
+ errorMessage: "flow run context unavailable: expected one matching run row with an explicit tenantId (string or null)",
922
+ completedAt: G()
923
+ }), {
924
+ runId: r,
925
+ status: "failed"
926
+ };
927
+ let { tenantId: s, ownerId: c = null } = o.right[0], l = yield* j({
839
928
  name: "flow-0-resolve",
840
929
  input: { flowRef: i },
841
- success: S.Struct({
842
- ir: S.Unknown,
843
- error: S.optional(S.String)
930
+ success: w.Struct({
931
+ ir: w.Unknown,
932
+ error: w.optional(w.String)
844
933
  }),
845
- execute: Y(e, i).pipe(x.map((e) => ({ ir: e })), x.catchAll((e) => x.succeed({
934
+ execute: Y(e, i).pipe(C.map((e) => ({ ir: e })), C.catchAll((e) => C.succeed({
846
935
  ir: void 0,
847
936
  error: e.message
848
937
  })))
849
938
  });
850
- if (o.error || !o.ir) return yield* J(e, r, {
939
+ if (l.error || !l.ir) return yield* J(e, r, {
851
940
  status: "failed",
852
- errorMessage: o.error ?? "flow not found",
941
+ errorMessage: l.error ?? "flow not found",
853
942
  completedAt: G()
854
943
  }), {
855
944
  runId: r,
856
945
  status: "failed"
857
946
  };
858
- let s = o.ir, c = (yield* x.promise(() => e.store.query(E(N).where(C("id", r)).descriptor)).pipe(x.catchAllCause(() => x.succeed([]))))[0], l = c?.ownerId ?? null, u = c?.tenantId ?? null, d = s.mode === "agentic" ? yield* Ct(e, t, r, s, a, l, u) : yield* _t(e, t, r, s, a, {
859
- ownerId: l,
860
- tenantId: u,
947
+ let u = l.ir, d = u.mode === "agentic" ? yield* Lt(e, t, r, u, a, c, s, i) : yield* jt(e, t, r, u, a, {
948
+ ownerId: c,
949
+ tenantId: s,
861
950
  source: n.source
862
951
  });
863
- return d.status === "succeeded" && s.chain && (yield* vt(e, r, s, a, d.output ?? {}, n, t)), t.onEvent && (d.status === "succeeded" || d.status === "failed") && (yield* W(t.onEvent({
952
+ return d.status === "succeeded" && u.chain && (yield* Mt(e, r, u, a, d.output ?? {}, n, t)), t.onEvent && (d.status === "succeeded" || d.status === "failed") && (yield* W(t.onEvent({
864
953
  kind: d.status,
865
954
  runId: r,
866
- flowName: s.name,
867
- ownerId: l,
955
+ flowName: u.name,
956
+ ownerId: c,
868
957
  source: n.source
869
- })).pipe(x.catchAllCause(() => x.void))), d;
870
- }), Tt = {
958
+ })).pipe(C.catchAllCause(() => C.void))), d;
959
+ }), zt = {
871
960
  text: (e) => ({
872
961
  type: "generate",
873
962
  modality: "text",
@@ -894,31 +983,32 @@ var M = Ae("_voltro_ai_flows", {
894
983
  type: "human",
895
984
  ...e
896
985
  })
897
- }, Et = (e) => e.map((e, t) => "id" in e && e.id ? e : {
986
+ }, Bt = (e) => e.map((e, t) => "id" in e && e.id ? e : {
898
987
  id: `step-${t}`,
899
988
  ...e
900
- }), Dt = (e) => {
901
- let t = [], r = R(e.steps);
902
- for (let e of rt(r)) t.push(`group "${e}" is not contiguous — only CONSECUTIVE steps sharing a group run concurrently, so this would execute as two separate fan-outs`);
903
- let i = new Set(e.brief.map((e) => e.key));
904
- for (let e of r) {
989
+ }), Vt = (e) => {
990
+ let t = [], n = z(e.steps);
991
+ for (let e of ft(n)) t.push(`group "${e}" is not contiguous — only CONSECUTIVE steps sharing a group run concurrently, so this would execute as two separate fan-outs`);
992
+ let r = new Set(e.brief.map((e) => e.key));
993
+ for (let e of n) {
905
994
  for (let { step: n } of e.steps) {
906
995
  n.type === "human" && n.group !== void 0 && t.push(`step "${n.id}" is a human review inside group "${n.group}" — a review SUSPENDS the whole run, which one branch of a fan-out cannot do`);
907
- for (let r of I(n.prompt ?? "")) i.has(r) || t.push(e.steps.length > 1 ? `step "${n.id}" references {{${r}}} which is produced inside its OWN group "${n.group}" or does not exist — grouped steps run concurrently, so they cannot read each other` : `step "${n.id}" references {{${r}}} which is not a brief field or a prior step outputKey`);
908
- n.when !== void 0 && !i.has(n.when.ref) && t.push(`step "${n.id}" has a when-condition on {{${n.when.ref}}} which is not a brief field or a prior step outputKey — it would never run`);
996
+ for (let i of L(n.prompt ?? "")) r.has(i) || t.push(e.steps.length > 1 ? `step "${n.id}" references {{${i}}} which is produced inside its OWN group "${n.group}" or does not exist — grouped steps run concurrently, so they cannot read each other` : `step "${n.id}" references {{${i}}} which is not a brief field or a prior step outputKey`);
997
+ for (let [e, i] of Object.entries(n.mediaInputs ?? {})) i.from === "step" && !r.has(i.ref) && t.push(`step "${n.id}" media input "${e}" references "${i.ref}" which is not a brief field or an earlier segment's outputKey`);
998
+ n.when !== void 0 && !r.has(n.when.ref) && t.push(`step "${n.id}" has a when-condition on {{${n.when.ref}}} which is not a brief field or a prior step outputKey — it would never run`);
909
999
  }
910
- for (let { step: t } of e.steps) t.outputKey && i.add(n(t.outputKey));
1000
+ for (let { step: t } of e.steps) t.outputKey && r.add(s(t.outputKey));
911
1001
  }
912
- if (t.length > 0) throw new be({
1002
+ if (t.length > 0) throw new Te({
913
1003
  flowRef: e.name,
914
1004
  message: `flow "${e.name}" has ${t.length} problem(s)`,
915
1005
  issues: t
916
1006
  });
917
- }, Ot = (e) => {
918
- let t = r({
1007
+ }, Ht = (e) => {
1008
+ let t = _({
919
1009
  name: e.name,
920
1010
  mode: e.mode,
921
- steps: Et(e.steps),
1011
+ steps: Bt(e.steps),
922
1012
  maxSteps: e.maxSteps,
923
1013
  brief: e.brief,
924
1014
  orchestratorModel: e.orchestrator?.model,
@@ -927,230 +1017,379 @@ var M = Ae("_voltro_ai_flows", {
927
1017
  cadence: e.cadence,
928
1018
  humanTimeoutMs: e.humanTimeoutMs
929
1019
  });
930
- return Dt(t), it(t), t;
931
- }, X = (e) => String(e).padStart(2, "0"), kt = (e, t) => `cron-${e}-${t.getFullYear()}${X(t.getMonth() + 1)}${X(t.getDate())}-${X(t.getHours())}${X(t.getMinutes())}`, At = async (e) => {
1020
+ return Vt(t), pt(t), t;
1021
+ }, X = async (e, t, n) => {
1022
+ let r = w.decodeUnknownSync(ke.pipe(w.filter((e) => e.workflowName === "flow.run" && e.id.length > 0)))(n);
1023
+ if (await e.store.update(P.tableName, t, { workflowStart: r }) === null) throw Error("flow start receipt could not be recorded; workflow submission may have succeeded");
1024
+ return r;
1025
+ }, Ut = (e, t, n) => {
1026
+ if (!Number.isFinite(t.getTime())) throw Error("cadence timestamp must be valid");
1027
+ return `cron-${Xe("sha256").update(JSON.stringify([
1028
+ n,
1029
+ e,
1030
+ Math.floor(t.getTime() / 6e4)
1031
+ ])).digest("hex")}`;
1032
+ }, Wt = async (e) => {
932
1033
  let t = [];
933
- for (let e of ot()) e.cadence && (e.cadence.repeats?.length ?? 0) > 0 && t.push({
934
- flowRef: e.name,
935
- cadence: e.cadence,
936
- defaultInput: e.cadence.defaultInput ?? {}
1034
+ for (let n of ht()) n.cadence && (n.cadence.repeats?.length ?? 0) > 0 && t.push({
1035
+ tenantId: e.request.subject.tenantId,
1036
+ flowRef: n.name,
1037
+ cadence: n.cadence,
1038
+ defaultInput: n.cadence.defaultInput ?? {}
937
1039
  });
938
1040
  let n = await e.store.select("_voltro_ai_flows").where("isEnabled", !0).all();
939
- for (let e of n) e.id && e.cadence && (e.cadence.repeats?.length ?? 0) > 0 && t.push({
940
- flowRef: e.id,
941
- cadence: e.cadence,
942
- defaultInput: e.cadence.defaultInput ?? {}
1041
+ for (let r of n) r.id && r.cadence && (r.cadence.repeats?.length ?? 0) > 0 && t.push({
1042
+ tenantId: r.tenantId ?? e.request.subject.tenantId,
1043
+ flowRef: r.id,
1044
+ cadence: r.cadence,
1045
+ defaultInput: r.cadence.defaultInput ?? {}
943
1046
  });
944
1047
  return t;
945
- }, jt = async (e, t = /* @__PURE__ */ new Date()) => {
946
- let n = e.workflows, r = [], i = 0, a = await At(e).catch(() => []);
947
- for (let o of a) {
948
- if (!Se(o.cadence, t) || (i += 1, !n)) continue;
949
- let a = kt(o.flowRef, t), s = `run-${a}`;
1048
+ }, Gt = async (e, t = /* @__PURE__ */ new Date()) => {
1049
+ let n = [], r = 0, i = await Wt(e), a = [];
1050
+ for (let o of i) {
1051
+ if (!De(o.cadence, t)) continue;
1052
+ r += 1;
1053
+ let i = Ut(o.flowRef, t, o.tenantId), s = `run-${i}`;
950
1054
  try {
951
- try {
952
- await e.store.insert("_voltro_ai_flow_runs", {
1055
+ if (!e.workflows) throw Error("workflow runtime unavailable; no cadence start was submitted");
1056
+ (await e.transaction(async (e) => {
1057
+ let t = e.workflows;
1058
+ if (!t) throw Error("workflow runtime unavailable in transaction; no cadence start was submitted");
1059
+ await e.store.insertIgnoreWithOutcome("_voltro_ai_flow_runs", {
953
1060
  id: s,
954
1061
  flowRef: o.flowRef,
955
1062
  flowName: o.flowRef,
956
1063
  status: "pending",
957
1064
  source: "cron",
958
- requestId: a,
1065
+ requestId: i,
959
1066
  input: o.defaultInput
1067
+ }, { conflictColumns: ["id"] });
1068
+ let n = await e.store.select("_voltro_ai_flow_runs").where("id", s).first();
1069
+ if (!n) throw Error("cadence run is not readable after persistence");
1070
+ let r = w.decodeUnknownSync(y.payloadSchema.pipe(w.filter((e) => e.runId === s && e.flowRef === o.flowRef && e.requestId === i && e.source === "cron")))({
1071
+ ...n,
1072
+ runId: n.id
960
1073
  });
961
- } catch {}
962
- await n.start("flow.run", {
963
- runId: s,
964
- flowRef: o.flowRef,
965
- input: o.defaultInput,
966
- source: "cron",
967
- requestId: a
968
- }), r.push(a);
969
- } catch {}
1074
+ return X(e, s, await t.start("flow.run", r));
1075
+ }, o.tenantId === null ? void 0 : { tenantId: o.tenantId })).status === "running" && n.push(i);
1076
+ } catch (e) {
1077
+ a.push(e);
1078
+ }
970
1079
  }
1080
+ if (a.length > 0) throw AggregateError(a, `${a.length} cadence submission(s) failed`);
971
1081
  return {
972
- matched: i,
973
- started: r
1082
+ matched: r,
1083
+ started: n
974
1084
  };
975
- }, Mt = (e) => ({
1085
+ }, Z = (e) => w.optionalWith(e, { exact: !0 }), Kt = w.Int.pipe(w.positive(), w.lessThanOrEqualTo(2 ** 53 - 1)), qt = w.Int.pipe(w.between(-(2 ** 53 - 1), 2 ** 53 - 1)), Jt = w.TemplateLiteral(w.Number, "x", w.Number).pipe(w.pattern(/^[1-9]\d*x[1-9]\d*$/)), Yt = w.TemplateLiteral(w.Number, ":", w.Number).pipe(w.pattern(/^[1-9]\d*:[1-9]\d*$/)), Xt = w.Struct({
1086
+ n: Z(Kt),
1087
+ seed: Z(qt),
1088
+ size: Z(Jt),
1089
+ aspectRatio: Z(Yt),
1090
+ providerOptions: Z(H)
1091
+ }), Zt = w.Struct({
1092
+ voice: Z(w.NonEmptyString),
1093
+ outputFormat: Z(w.NonEmptyString),
1094
+ instructions: Z(w.String),
1095
+ speed: Z(w.Finite.pipe(w.positive())),
1096
+ language: Z(w.NonEmptyString),
1097
+ providerOptions: Z(H)
1098
+ }), Qt = w.Struct({
1099
+ aspectRatio: Z(Yt),
1100
+ durationSeconds: Z(w.Finite.pipe(w.positive())),
1101
+ resolution: Z(Jt),
1102
+ fps: Z(w.Finite.pipe(w.positive())),
1103
+ seed: Z(qt),
1104
+ generateAudio: Z(w.Boolean),
1105
+ maxInlineBytes: Z(Kt),
1106
+ providerOptions: Z(H)
1107
+ }), Q = (e, t, n) => C.try({
1108
+ try: () => w.decodeUnknownSync(e, { onExcessProperty: "error" })(t === void 0 ? {} : t),
1109
+ catch: () => `invalid ${n} media params: check the built-in adapter's supported options and value ranges`
1110
+ }), $t = (e) => Q(Xt, e, "image"), en = (e) => Q(Zt, e, "audio"), tn = (e) => Q(Qt, e, "video"), nn = (e) => ({
976
1111
  name: "gateway",
977
1112
  model: e
978
- }), Nt = (e) => Math.round(e * 1e6), Z = (e, t, n) => {
979
- let r = Ie(t);
980
- return typeof r == "number" ? Nt(r) : e ? Fe(e, { model: n ?? "unknown" }).costMicroUsd ?? 0 : 0;
981
- }, Pt = (e, t) => (n) => {
982
- let r = n.model, i = (e) => t?.resolveModel?.(e) ?? Mt(e);
983
- return x.gen(function* () {
1113
+ }), rn = (e) => Math.round(e * 1e6), $ = (e, t, n) => {
1114
+ let r = He(t);
1115
+ return typeof r == "number" ? rn(r) : e ? Ve(e, { model: n ?? "unknown" }).costMicroUsd ?? 0 : 0;
1116
+ }, an = (e, t) => (n) => {
1117
+ let r = n.model, i = (e) => t?.resolveModel?.(e) ?? nn(e);
1118
+ return C.gen(function* () {
1119
+ let t = yield* xt(n.modality, n.inputs).pipe(C.mapError((e) => new x({
1120
+ capability: `media:${n.modality}`,
1121
+ message: e
1122
+ })));
984
1123
  if (n.modality === "image") {
985
- let t = yield* Le({
1124
+ let a = yield* $t(n.params).pipe(C.mapError((e) => new x({
1125
+ capability: "media:image",
1126
+ message: e
1127
+ }))), o = t.referenceImageUrl, s = t.maskImageUrl, c = yield* Ue({
1128
+ ...a,
986
1129
  prompt: n.prompt,
1130
+ ...o === void 0 ? {} : { inputs: {
1131
+ images: [o],
1132
+ ...s === void 0 ? {} : { mask: s }
1133
+ } },
987
1134
  ...r ? { provider: i(r) } : {}
988
- }), a = t.images[0];
989
- if (!a) return yield* x.fail(new y({
1135
+ });
1136
+ if (c.images.length === 0) return yield* C.fail(new x({
990
1137
  capability: "media:image",
991
1138
  message: "no image produced"
992
1139
  }));
993
- let o = yield* x.promise(() => e.put({
994
- data: a.data,
995
- mediaType: a.mediaType,
996
- run: n.run
997
- }));
1140
+ let l = [];
1141
+ for (let [t, r] of c.images.entries()) {
1142
+ let i = yield* e.put({
1143
+ data: r.data,
1144
+ mediaType: r.mediaType,
1145
+ run: n.run
1146
+ }).pipe(C.mapError(() => new x({
1147
+ capability: "media:image",
1148
+ message: "media persistence failed"
1149
+ })));
1150
+ l.push({
1151
+ url: i.url,
1152
+ mediaType: r.mediaType,
1153
+ role: t === 0 ? "primary" : "variant",
1154
+ ...i.refId === void 0 ? {} : { storageRefId: i.refId },
1155
+ ...r.providerMetadata === void 0 ? {} : { providerMetadata: r.providerMetadata }
1156
+ });
1157
+ }
998
1158
  return {
999
- url: o.url,
1000
- ...o.refId ? { requestId: o.refId } : {},
1001
- costMicroUsd: Z(t.usage, t.providerMetadata, r)
1159
+ artifacts: l,
1160
+ costMicroUsd: $(c.usage, c.providerMetadata, r)
1002
1161
  };
1003
1162
  }
1004
1163
  if (n.modality === "audio") {
1005
- let t = yield* Be({
1164
+ let t = yield* en(n.params).pipe(C.mapError((e) => new x({
1165
+ capability: "media:audio",
1166
+ message: e
1167
+ }))), a = yield* qe({
1168
+ ...t,
1006
1169
  text: n.prompt,
1007
1170
  ...r ? { provider: i(r) } : {}
1008
- }), a = yield* x.promise(() => e.put({
1009
- data: t.audio.data,
1010
- mediaType: t.audio.mediaType,
1171
+ }), o = yield* e.put({
1172
+ data: a.audio.data,
1173
+ mediaType: a.audio.mediaType,
1011
1174
  run: n.run
1012
- }));
1175
+ }).pipe(C.mapError(() => new x({
1176
+ capability: "media:audio",
1177
+ message: "media persistence failed"
1178
+ })));
1013
1179
  return {
1014
- url: a.url,
1015
- ...a.refId ? { requestId: a.refId } : {},
1016
- costMicroUsd: Z(t.usage, t.providerMetadata, r)
1180
+ artifacts: [{
1181
+ url: o.url,
1182
+ mediaType: a.audio.mediaType,
1183
+ role: "primary",
1184
+ ...o.refId === void 0 ? {} : { storageRefId: o.refId }
1185
+ }],
1186
+ costMicroUsd: $(a.usage, a.providerMetadata, r)
1017
1187
  };
1018
1188
  }
1019
- let t = yield* Ve({
1189
+ let { maxInlineBytes: a, providerOptions: o, ...s } = yield* tn(n.params).pipe(C.mapError((e) => new x({
1190
+ capability: "media:video",
1191
+ message: e
1192
+ }))), c = yield* Ye({
1020
1193
  prompt: n.prompt,
1194
+ inputs: {
1195
+ ...t.referenceImageUrl === void 0 ? {} : { image: t.referenceImageUrl },
1196
+ ...t.referenceVideoUrl === void 0 ? {} : { references: [t.referenceVideoUrl] },
1197
+ frameImages: [...t.firstFrameImageUrl === void 0 ? [] : [{
1198
+ frameType: "first_frame",
1199
+ image: t.firstFrameImageUrl
1200
+ }], ...t.lastFrameImageUrl === void 0 ? [] : [{
1201
+ frameType: "last_frame",
1202
+ image: t.lastFrameImageUrl
1203
+ }]]
1204
+ },
1021
1205
  ...r ? { provider: i(r) } : {},
1022
- ...n.params ? { params: n.params } : {}
1023
- }), a;
1024
- if (t.video.url) a = e.ingestUrl ? yield* x.promise(() => e.ingestUrl(t.video.url, n.run)) : { url: t.video.url };
1025
- else if (t.video.data) a = yield* x.promise(() => e.put({
1026
- data: t.video.data,
1027
- mediaType: t.video.mediaType,
1206
+ params: s,
1207
+ ...o === void 0 ? {} : { providerOptions: o },
1208
+ ...a === void 0 ? {} : { maxInlineBytes: a }
1209
+ }), l;
1210
+ if (c.video.url) l = e.ingestUrl ? yield* e.ingestUrl(c.video.url, n.run).pipe(C.mapError(() => new x({
1211
+ capability: "media:video",
1212
+ message: "media persistence failed"
1213
+ }))) : { url: c.video.url };
1214
+ else if (c.video.data) l = yield* e.put({
1215
+ data: c.video.data,
1216
+ mediaType: c.video.mediaType,
1028
1217
  run: n.run
1029
- }));
1030
- else return yield* x.fail(new y({
1218
+ }).pipe(C.mapError(() => new x({
1219
+ capability: "media:video",
1220
+ message: "media persistence failed"
1221
+ })));
1222
+ else return yield* C.fail(new x({
1031
1223
  capability: "media:video",
1032
1224
  message: "no video produced"
1033
1225
  }));
1034
1226
  return {
1035
- url: a.url,
1036
- ...a.refId ? { requestId: a.refId } : {},
1037
- costMicroUsd: Z(t.usage, t.providerMetadata, r)
1227
+ artifacts: [{
1228
+ url: l.url,
1229
+ mediaType: c.video.mediaType,
1230
+ role: "primary",
1231
+ ...l.refId === void 0 ? {} : { storageRefId: l.refId }
1232
+ }],
1233
+ costMicroUsd: $(c.usage, c.providerMetadata, r)
1038
1234
  };
1039
- }).pipe(x.catchAll((e) => e instanceof y ? x.fail(e) : x.fail(new y({
1235
+ }).pipe(C.catchAll((e) => e instanceof x ? C.fail(e) : C.fail(new x({
1040
1236
  capability: `media:${n.modality}`,
1041
1237
  message: String(e.message ?? e)
1042
1238
  }))));
1043
- }, Q = () => globalThis.crypto?.randomUUID?.() ?? `req-${Date.now().toString(36)}`, Ft = (e) => e.request?.subject?.id ?? null, $ = (e, t) => x.promise(() => e.store.query(E(N).where(C("id", t)).descriptor)).pipe(x.map((e) => e[0])), It = (e, t) => x.gen(function* () {
1239
+ }, on = () => globalThis.crypto?.randomUUID?.() ?? `req-${Date.now().toString(36)}`, sn = (e) => e.request?.subject?.id ?? null, cn = (e, t) => C.promise(() => e.store.query(O(P).where(T("id", t)).descriptor)).pipe(C.map((e) => e[0])), ln = (e) => C.sync(() => {
1240
+ let t = e.workflows;
1241
+ if (!t) throw Error("workflow runtime unavailable; no flow start was submitted");
1242
+ return t;
1243
+ }), un = (e, t) => C.gen(function* () {
1244
+ yield* ln(e);
1044
1245
  let n = yield* Y(e, t.flowRef), r = t.input ?? {}, i = n.brief.filter((e) => e.required && e.type !== "boolean" && (r[e.key] === void 0 || r[e.key] === null || r[e.key] === "")).map((e) => e.key);
1045
- if (i.length > 0) return yield* x.fail(new ge({
1246
+ if (i.length > 0) return yield* C.fail(new be({
1046
1247
  missing: i,
1047
1248
  message: `missing required brief field(s): ${i.join(", ")}`
1048
1249
  }));
1049
- let a = Q(), o = `run-${a}`, s = t.source ?? "manual";
1050
- yield* x.promise(() => e.store.insert(N.tableName, {
1051
- id: o,
1052
- flowRef: t.flowRef,
1053
- flowName: n.name,
1054
- mode: n.mode,
1055
- status: "pending",
1056
- source: s,
1057
- requestId: a,
1058
- input: r,
1059
- ownerId: Ft(e)
1060
- }));
1061
- let c = e.workflows;
1062
- return c && (yield* x.promise(() => c.start(_, {
1063
- runId: o,
1064
- flowRef: t.flowRef,
1065
- input: r,
1066
- source: s,
1067
- requestId: a
1068
- }))), {
1069
- runId: o,
1070
- requestId: a,
1071
- status: "pending"
1072
- };
1073
- }), Lt = (e, t) => x.gen(function* () {
1074
- let n = yield* $(e, t.runId);
1075
- if (!n) return yield* x.fail(new b({
1076
- runId: t.runId,
1077
- message: "run not found"
1078
- }));
1079
- let r = n.requestId ?? Q(), i = n.flowRef, a = n.input ?? {}, o = n.source ?? "manual";
1080
- yield* x.promise(() => e.store.update(N.tableName, t.runId, {
1081
- status: "pending",
1082
- error: null,
1083
- errorMessage: null
1250
+ let a = on(), o = `run-${a}`, s = t.source ?? "manual";
1251
+ return yield* C.promise(() => e.transaction(async (e) => {
1252
+ let i = e.workflows;
1253
+ if (!i) throw Error("workflow runtime unavailable in transaction; no flow start was submitted");
1254
+ await e.store.insert(P.tableName, {
1255
+ id: o,
1256
+ flowRef: t.flowRef,
1257
+ flowName: n.name,
1258
+ mode: n.mode,
1259
+ status: "pending",
1260
+ source: s,
1261
+ requestId: a,
1262
+ input: r,
1263
+ ownerId: sn(e)
1264
+ });
1265
+ let c = await X(e, o, await i.start(v, {
1266
+ runId: o,
1267
+ flowRef: t.flowRef,
1268
+ input: r,
1269
+ source: s,
1270
+ requestId: a
1271
+ }));
1272
+ return h.make({
1273
+ runId: o,
1274
+ requestId: a,
1275
+ admission: c
1276
+ });
1084
1277
  }));
1085
- let s = e.workflows;
1086
- return s && (yield* x.promise(() => s.start(_, {
1087
- runId: t.runId,
1088
- flowRef: i,
1089
- input: a,
1090
- source: o,
1091
- requestId: r
1092
- }))), {
1093
- runId: t.runId,
1094
- requestId: r,
1095
- status: "pending"
1096
- };
1097
- }), Rt = (e, t) => x.gen(function* () {
1098
- return (yield* $(e, t.runId)) ? (yield* x.promise(() => e.store.update(N.tableName, t.runId, {
1278
+ }), dn = (e, t) => C.gen(function* () {
1279
+ return yield* ln(e), yield* C.tryPromise({
1280
+ try: () => e.transaction(async (e) => {
1281
+ let n = e.workflows;
1282
+ if (!n) throw Error("workflow runtime unavailable in transaction; no flow start was submitted");
1283
+ let r = (await e.store.query(O(P).where(T("id", t.runId)).descriptor))[0];
1284
+ if (!r) throw new S({
1285
+ runId: t.runId,
1286
+ message: "run not found"
1287
+ });
1288
+ let i = r.requestId;
1289
+ if (typeof i != "string" || i.length === 0) throw Error("stored flow run has no valid requestId; retry refused without changing the run");
1290
+ let a = w.decodeUnknownEither(y.payloadSchema.pipe(w.filter((e) => e.runId === t.runId && e.flowRef.length > 0)))({
1291
+ ...r,
1292
+ runId: r.id
1293
+ });
1294
+ if (a._tag === "Left") throw Error("stored workflow payload is incomplete or invalid; retry refused without changing the run");
1295
+ let o = await X(e, t.runId, await n.start(v, a.right));
1296
+ return h.make({
1297
+ runId: t.runId,
1298
+ requestId: i,
1299
+ admission: o
1300
+ });
1301
+ }),
1302
+ catch: (e) => e
1303
+ }).pipe(C.catchAll((e) => e instanceof S ? C.fail(e) : C.die(e)));
1304
+ }), fn = (e, t) => C.gen(function* () {
1305
+ return (yield* cn(e, t.runId)) ? (yield* C.promise(() => e.store.update(P.tableName, t.runId, {
1099
1306
  status: "cancelled",
1100
1307
  cancelledAt: (/* @__PURE__ */ new Date()).toISOString()
1101
1308
  })), {
1102
1309
  runId: t.runId,
1103
1310
  status: "cancelled"
1104
- }) : yield* x.fail(new b({
1311
+ }) : yield* C.fail(new S({
1105
1312
  runId: t.runId,
1106
1313
  message: "run not found"
1107
1314
  }));
1108
- }), zt = (e) => {
1109
- let t = e.steps?.find((e) => e.status === "waiting");
1110
- if (t !== void 0) return t.id;
1111
- let n = e.currentStep;
1112
- return typeof n == "number" ? n : 0;
1113
- }, Bt = (e, t) => x.gen(function* () {
1114
- let n = yield* $(e, t.runId);
1115
- if (!n) return yield* x.fail(new b({
1315
+ }), pn = (e) => {
1316
+ let t = e.steps?.filter((e) => e.status === "waiting"), n = t?.[0];
1317
+ if (t?.length !== 1 || n?.type !== "human" || !Number.isSafeInteger(n.id) || n.id < 0) throw Error("expected exactly one waiting human step with a nonnegative integer index");
1318
+ return n.id;
1319
+ }, mn = (e, t) => C.gen(function* () {
1320
+ let n = (e, n) => new we({
1321
+ runId: t.runId,
1322
+ reason: e,
1323
+ message: n
1324
+ }), r = yield* w.decodeUnknown(le, { onExcessProperty: "error" })(t).pipe(C.mapError(() => n("invalid-response", "review response requires runId, displayed stepIndex and a valid response")));
1325
+ if (r.response.decision === void 0 && r.response.text === void 0 && r.response.value === void 0) return yield* C.fail(n("invalid-response", "review response must contain a decision, text or value"));
1326
+ let i = e.workflows;
1327
+ if (!i) return yield* C.fail(n("runtime-unavailable", "workflow runtime unavailable; review was not sent"));
1328
+ let a = yield* cn(e, t.runId);
1329
+ if (!a) return yield* C.fail(new S({
1116
1330
  runId: t.runId,
1117
1331
  message: "run not found"
1118
1332
  }));
1119
- let r = n.status;
1120
- if (r !== "waiting") return yield* x.fail(new ve({
1333
+ let o = a.status;
1334
+ if (o !== "waiting") return yield* C.fail(new Se({
1121
1335
  runId: t.runId,
1122
- status: r ?? "unknown",
1123
- message: `run is "${r}", not awaiting a response`
1336
+ status: o ?? "unknown",
1337
+ message: `run is "${o}", not awaiting a response`
1124
1338
  }));
1125
- let i = {
1126
- ...t.response,
1339
+ let s = yield* C.try({
1340
+ try: () => pn(a),
1341
+ catch: () => n("invalid-run", "stored run has no unambiguous waiting review")
1342
+ });
1343
+ if (s !== r.stepIndex) return yield* C.fail(new Se({
1344
+ runId: t.runId,
1345
+ status: o,
1346
+ message: "this review is no longer waiting; reload the run before answering"
1347
+ }));
1348
+ let c = yield* w.decodeUnknown(w.Struct({
1349
+ runId: w.Literal(t.runId),
1350
+ flowRef: w.NonEmptyString,
1351
+ requestId: w.NonEmptyString,
1352
+ input: w.Record({
1353
+ key: w.String,
1354
+ value: w.Unknown
1355
+ }),
1356
+ source: w.Literal("manual", "cron")
1357
+ }))({
1358
+ ...a,
1359
+ runId: a.id
1360
+ }).pipe(C.mapError(() => n("invalid-run", "stored workflow payload is incomplete; review was not sent"))), l = yield* y.executionId(c), u = {
1361
+ ...r.response,
1127
1362
  respondedAt: (/* @__PURE__ */ new Date()).toISOString()
1128
- };
1129
- yield* x.promise(() => e.store.update(N.tableName, t.runId, { humanResponse: i }));
1130
- let a = e.workflows, o = n.requestId, s = zt(n);
1131
- return a && o && (yield* x.promise(() => a.signal({
1132
- workflowName: _,
1133
- executionId: `flow-run:${o}`
1134
- }, v(s), i)).pipe(x.catchAllCause(() => x.void))), {
1363
+ }, d = yield* C.tryPromise({
1364
+ try: () => i.signal({
1365
+ workflowName: v,
1366
+ executionId: l
1367
+ }, b(s), u),
1368
+ catch: () => n("delivery-unknown", "review delivery was not confirmed; observe the run before retrying")
1369
+ }), f = yield* w.decodeUnknown(w.Struct({ eventId: w.NonEmptyString }))(d).pipe(C.mapError(() => n("delivery-unknown", "workflow runtime returned no valid review delivery receipt")));
1370
+ return yield* w.decodeUnknown(fe)({
1135
1371
  runId: t.runId,
1136
- stepIndex: s
1137
- };
1138
- }), Vt = (e, t) => x.promise(() => e.store.query(E(M).where(C("id", t.id)).descriptor)).pipe(x.map((e) => e[0])), Ht = (e) => x.promise(() => e.store.query(E(M).descriptor)), Ut = (e, t) => x.promise(() => e.store.insert(M.tableName, {
1139
- id: t.id ?? `flow-${Q()}`,
1372
+ stepIndex: s,
1373
+ executionId: l,
1374
+ eventId: f.eventId,
1375
+ status: "accepted"
1376
+ }).pipe(C.mapError(() => n("delivery-unknown", "workflow runtime returned no valid review delivery receipt")));
1377
+ }), hn = (e, t) => C.promise(() => e.store.query(O(N).where(T("id", t.id)).descriptor)).pipe(C.map((e) => e[0])), gn = (e) => C.promise(() => e.store.query(O(N).descriptor)), _n = (e, t) => C.promise(() => e.store.insert(N.tableName, {
1378
+ id: t.id ?? `flow-${on()}`,
1140
1379
  ...t
1141
- })), Wt = (e, t) => x.promise(() => e.store.update(M.tableName, t.id, t.patch)), Gt = (e, t) => x.promise(() => e.store.delete(M.tableName, t.id)), Kt = "aiFlows", qt = (e = {}) => {
1142
- let t = Te({
1143
- base: Kt,
1380
+ })), vn = (e, t) => C.promise(() => e.store.update(N.tableName, t.id, t.patch)), yn = (e, t) => C.promise(() => e.store.delete(N.tableName, t.id)), bn = "aiFlows", xn = (e = {}) => {
1381
+ let t = je({
1382
+ base: bn,
1144
1383
  alias: e.alias
1145
1384
  });
1146
- Ye(e.humanReviewTimeoutMs === void 0 ? {} : { humanReviewTimeoutMs: e.humanReviewTimeoutMs }), ke({
1385
+ it(e.humanReviewTimeoutMs === void 0 ? {} : { humanReviewTimeoutMs: e.humanReviewTimeoutMs }), Fe({
1147
1386
  source: "plugin",
1148
- table: N.tableName,
1387
+ table: P.tableName,
1149
1388
  timeColumn: "createdAt",
1150
- ttlMs: e.runsTtlMs ?? Ze(process.env.VOLTRO_AI_FLOW_RUNS_TTL_HOURS, 2160),
1151
- envVar: Ke,
1389
+ ttlMs: e.runsTtlMs ?? ot(process.env.VOLTRO_AI_FLOW_RUNS_TTL_HOURS, 2160),
1390
+ envVar: tt,
1152
1391
  label: "ai flow runs",
1153
- where: Oe("status", [
1392
+ where: Pe("status", [
1154
1393
  "succeeded",
1155
1394
  "failed",
1156
1395
  "cancelled"
@@ -1163,23 +1402,42 @@ var M = Ae("_voltro_ai_flows", {
1163
1402
  kind: "json",
1164
1403
  status: e,
1165
1404
  data: { error: t }
1166
- }), o = (e, t) => x.promise(async () => {
1167
- let n = r.current;
1168
- if (!n) return a(503, "store not bound yet");
1169
- let o = await n.query({
1405
+ }), o = (e, t, n) => C.promise(async () => {
1406
+ let o = r.current;
1407
+ if (!o) return a(503, "store not bound yet");
1408
+ let s = await o.query({
1170
1409
  table: e,
1171
- predicate: void 0,
1172
- order: [],
1173
- take: t,
1410
+ predicate: n === void 0 ? void 0 : T("id", n),
1411
+ order: [{
1412
+ column: "createdAt",
1413
+ direction: "desc"
1414
+ }, {
1415
+ column: "id",
1416
+ direction: "desc"
1417
+ }],
1418
+ take: n === void 0 ? t : 1,
1174
1419
  skip: void 0,
1175
- projection: void 0
1420
+ projection: e === "_voltro_ai_flow_runs" && n === void 0 ? [
1421
+ "id",
1422
+ "flowRef",
1423
+ "flowName",
1424
+ "mode",
1425
+ "status",
1426
+ "source",
1427
+ "currentStep",
1428
+ "totalSteps",
1429
+ "costMicroUsd",
1430
+ "startedAt",
1431
+ "completedAt",
1432
+ "createdAt"
1433
+ ] : void 0
1176
1434
  });
1177
1435
  return i({
1178
- count: o.length,
1179
- rows: o,
1436
+ count: s.length,
1437
+ rows: s,
1180
1438
  take: t
1181
1439
  });
1182
- }).pipe(x.catchAllCause(() => x.succeed(a(500, "query failed")))), s = (e, t) => {
1440
+ }).pipe(C.catchAllCause(() => C.succeed(a(500, "query failed")))), s = (e, t) => {
1183
1441
  let r = /[?&]take=(\d+)/.exec(e)?.[1], i = r === void 0 ? t : Number(r);
1184
1442
  return Math.min(n, Math.max(1, Number.isFinite(i) ? i : t));
1185
1443
  }, c = [{
@@ -1190,15 +1448,15 @@ var M = Ae("_voltro_ai_flows", {
1190
1448
  }, {
1191
1449
  method: "GET",
1192
1450
  path: "/runs",
1193
- description: "List recent flow runs (`?take=` up to the configured max).",
1194
- handler: (e) => o("_voltro_ai_flow_runs", s(e.url, Math.min(100, n)))
1451
+ description: "List recent run summaries (`?take=` bounded); `?runId=` reads one run with payloads and steps.",
1452
+ handler: (e) => o("_voltro_ai_flow_runs", s(e.url, Math.min(100, n)), new URL(e.url, "http://inspect.local").searchParams.get("runId") ?? void 0)
1195
1453
  }];
1196
- return we({
1454
+ return Ae({
1197
1455
  name: t,
1198
- baseName: Kt,
1456
+ baseName: bn,
1199
1457
  description: "AI Flows — durable multi-step AI pipelines (deterministic + agentic) with human-in-the-loop, chaining, and cadence. Code-first (defineFlow) or data-driven.",
1200
1458
  permissions: ["store:write", "inspect:read"],
1201
- ...e.tables === !1 ? {} : { extendSchema: { tables: He } },
1459
+ ...e.tables === !1 ? {} : { extendSchema: { tables: Ze } },
1202
1460
  inspectEndpoints: c,
1203
1461
  bindDataStore: (e) => {
1204
1462
  r.current = e;
@@ -1206,4 +1464,4 @@ var M = Ae("_voltro_ai_flows", {
1206
1464
  });
1207
1465
  };
1208
1466
  //#endregion
1209
- export { le as BriefField, ie as ChainPending, a as ConditionOp, Ke as FLOW_RUNS_TTL_ENV, Ge as FLOW_RUNS_TTL_HOURS_DEFAULT, _ as FLOW_RUN_WORKFLOW, se as FlowCadence, ee as FlowChain, l as FlowMode, ae as FlowStatus, ce as FlowStep, he as HUMAN_RESPONSE_SIGNAL_PREFIX, We as HUMAN_REVIEW_TIMEOUT_ENV, Ue as HUMAN_REVIEW_TIMEOUT_HOURS_DEFAULT, d as HumanResponse, ne as Json, qe as MAX_CHAIN_DEPTH_DEFAULT, Je as MAX_CHAIN_DEPTH_ENV, ue as MAX_STEPS_DEFAULT, f as MAX_STEPS_MAX, p as MAX_STEPS_MIN, oe as MediaInputSlot, re as MediaInputs, h as Modality, m as ReviewMode, c as ReviewOption, de as RunReview, me as RunSource, u as RunStatus, pe as RunStep, o as RunStepStatus, te as StepCondition, t as StepType, fe as Visibility, N as aiFlowRunsTable, qt as aiFlowsPlugin, M as aiFlowsTable, He as aiFlowsTables, wt as buildFlowRunExecute, Se as cadenceMatches, Rt as cancelFlow, s as clampMaxSteps, st as clearRegistry, I as collectRefs, Ut as createFlow, kt as cronRequestId, Ot as defineFlow, Gt as deleteFlow, e as describeCondition, g as evaluateCondition, R as flowSegments, Tt as flowStep, F as getAiFlowsDefaults, Vt as getFlow, at as getRegisteredFlow, v as humanResponseSignalName, L as interpolate, i as isTruthy, ft as jsonSchemaToEffectSchema, It as launchFlow, Ht as listFlows, ot as listRegisteredFlows, Pt as makeMediaGenerator, xe as nextRuns, rt as nonContiguousGroups, r as normalizeFlow, it as registerFlow, Xe as resetAiFlowsDefaults, $e as resolveHumanReviewTimeoutMs, Y as resolveIr, et as resolveMaxChainDepth, Bt as respondToFlow, Lt as retryFlow, jt as runCadenceTick, n as sanitizeOutputKey, Ye as setAiFlowsDefaults, nt as unresolvedRefs, Wt as updateFlow, Dt as validateFlow, zt as waitingStepIndex };
1467
+ export { pe as BriefField, ce as ChainPending, c as ConditionOp, tt as FLOW_RUNS_TTL_ENV, et as FLOW_RUNS_TTL_HOURS_DEFAULT, v as FLOW_RUN_WORKFLOW, de as FlowCadence, ie as FlowChain, m as FlowMode, le as FlowReviewInput, fe as FlowReviewReceipt, h as FlowStartReceipt, oe as FlowStatus, me as FlowStep, ye as HUMAN_RESPONSE_SIGNAL_PREFIX, $e as HUMAN_REVIEW_TIMEOUT_ENV, Qe as HUMAN_REVIEW_TIMEOUT_HOURS_DEFAULT, g as HumanResponse, te as Json, nt as MAX_CHAIN_DEPTH_DEFAULT, rt as MAX_CHAIN_DEPTH_ENV, ue as MAX_STEPS_DEFAULT, se as MAX_STEPS_MAX, re as MAX_STEPS_MIN, ne as MediaArtifact, p as MediaArtifacts, he as MediaInputSlot, ve as MediaInputs, ee as Modality, _e as ReviewMode, d as ReviewOption, t as RunReview, ge as RunSource, f as RunStatus, r as RunStep, n as RunStepStatus, u as StepCondition, l as StepType, ae as Visibility, P as aiFlowRunsTable, xn as aiFlowsPlugin, N as aiFlowsTable, Ze as aiFlowsTables, Rt as buildFlowRunExecute, De as cadenceMatches, fn as cancelFlow, e as clampMaxSteps, gt as clearRegistry, L as collectRefs, _n as createFlow, Ut as cronRequestId, Ht as defineFlow, yn as deleteFlow, i as describeCondition, a as evaluateCondition, z as flowSegments, zt as flowStep, I as getAiFlowsDefaults, hn as getFlow, mt as getRegisteredFlow, b as humanResponseSignalName, R as interpolate, o as isTruthy, un as launchFlow, gn as listFlows, ht as listRegisteredFlows, an as makeMediaGenerator, Ee as nextRuns, ft as nonContiguousGroups, _ as normalizeFlow, pt as registerFlow, at as resetAiFlowsDefaults, ct as resolveHumanReviewTimeoutMs, Y as resolveIr, lt as resolveMaxChainDepth, mn as respondToFlow, dn as retryFlow, Gt as runCadenceTick, s as sanitizeOutputKey, it as setAiFlowsDefaults, dt as unresolvedRefs, vn as updateFlow, Vt as validateFlow, pn as waitingStepIndex };