@voltro/plugin-ai-flows 0.71.1 → 0.72.0

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