@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/CHANGELOG.md +383 -0
- package/THIRD-PARTY-NOTICES.md +29 -1
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +6 -1
- package/dist/index.d.ts +136 -25
- package/dist/index.js +695 -476
- package/dist/{ir-B0rox9qW.js → ir-BP8rOTuf.js} +13 -11
- package/dist/ir.d.ts +17 -0
- package/dist/ir.js +2 -2
- package/dist/web.d.ts +11 -0
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { FlowBriefIncomplete as
|
|
4
|
-
import { n as
|
|
5
|
-
import { Cause as
|
|
6
|
-
import { WorkflowRunHandleSchema as
|
|
7
|
-
import { boolean as
|
|
8
|
-
import { tenant as
|
|
9
|
-
import { audit as
|
|
10
|
-
import { softDelete as
|
|
11
|
-
import { awaitSignalSuspending as
|
|
12
|
-
import { defineTool as
|
|
13
|
-
import { createHash as
|
|
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
|
|
16
|
-
id:
|
|
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:
|
|
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(
|
|
38
|
-
id:
|
|
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(
|
|
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,
|
|
141
|
+
}, I = () => F.current, dt = () => {
|
|
68
142
|
F.current = {};
|
|
69
|
-
},
|
|
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
|
-
},
|
|
147
|
+
}, pt = (e) => Number.isFinite(e) && e > 0 ? e : Infinity, mt = (e) => {
|
|
74
148
|
let t = e.env ?? process.env;
|
|
75
|
-
return
|
|
76
|
-
},
|
|
77
|
-
let t = e?.env ?? process.env, n = Number(t[
|
|
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
|
-
},
|
|
153
|
+
}, gt = /\{\{\s*([\w.-]+)\s*\}\}/g, L = (e) => {
|
|
80
154
|
let t = [];
|
|
81
|
-
for (let n of e.matchAll(
|
|
155
|
+
for (let n of e.matchAll(gt)) t.push(n[1]);
|
|
82
156
|
return t;
|
|
83
|
-
}, R = (e, t) => e.replace(
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
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(),
|
|
197
|
+
}, B = /* @__PURE__ */ new Map(), yt = (e) => {
|
|
124
198
|
B.set(e.name, e);
|
|
125
|
-
},
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
})),
|
|
230
|
+
})), W = w.Record({
|
|
149
231
|
key: w.String,
|
|
150
|
-
value:
|
|
151
|
-
}),
|
|
232
|
+
value: U
|
|
233
|
+
}), Dt = (e, t, n = {}) => C.try({
|
|
152
234
|
try: () => {
|
|
153
|
-
let r = w.decodeUnknownSync(
|
|
154
|
-
return w.decodeUnknownSync(
|
|
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
|
-
}),
|
|
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(
|
|
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
|
-
}),
|
|
171
|
-
artifacts:
|
|
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
|
-
}),
|
|
175
|
-
try: () => w.decodeUnknownSync(
|
|
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
|
-
}),
|
|
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(
|
|
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
|
-
}),
|
|
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 }))),
|
|
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
|
-
}),
|
|
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*
|
|
314
|
+
})) : yield* Ze({
|
|
202
315
|
...r,
|
|
203
316
|
system: t.system,
|
|
204
317
|
prompt: n,
|
|
205
|
-
provider:
|
|
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
|
-
}),
|
|
210
|
-
let r =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
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(
|
|
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
|
|
356
|
+
}) : yield* C.fail(new Te({
|
|
228
357
|
flowRef: t,
|
|
229
358
|
message: `no flow registered or stored for "${t}"`
|
|
230
359
|
}));
|
|
231
|
-
}),
|
|
232
|
-
let e = R(n.prompt ?? "", r), o = yield*
|
|
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 =
|
|
236
|
-
if (s.length > 0) return { error: new
|
|
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*
|
|
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*
|
|
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
|
-
|
|
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*
|
|
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:
|
|
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
|
-
|
|
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*
|
|
427
|
+
let r = n.model ?? t.defaultModels?.text, i = yield* Ze({
|
|
298
428
|
...o.right,
|
|
299
429
|
prompt: e,
|
|
300
|
-
...r ? { provider:
|
|
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
|
-
|
|
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*
|
|
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],
|
|
450
|
+
let l = kt(n.mediaInputs, a), u = n.model ?? t.defaultModels?.[s], d = yield* G(t.generateMedia({
|
|
321
451
|
modality: s,
|
|
322
|
-
...
|
|
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
|
|
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
|
-
}),
|
|
343
|
-
let
|
|
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*
|
|
481
|
+
yield* zt(e, n, {
|
|
351
482
|
status: "running",
|
|
352
|
-
steps:
|
|
353
|
-
totalSteps:
|
|
483
|
+
steps: l,
|
|
484
|
+
totalSteps: i.steps.length,
|
|
354
485
|
currentStep: 0,
|
|
355
|
-
startedAt:
|
|
356
|
-
});
|
|
357
|
-
for (let
|
|
358
|
-
if (yield*
|
|
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 (
|
|
493
|
+
if (a.steps.length > 1) {
|
|
363
494
|
let r = [];
|
|
364
|
-
for (let { index: e, step: t } of
|
|
365
|
-
if (t.when !== void 0 && !
|
|
366
|
-
|
|
367
|
-
...
|
|
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:
|
|
370
|
-
skipReason:
|
|
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
|
-
}),
|
|
378
|
-
...
|
|
508
|
+
}), l[e] = {
|
|
509
|
+
...l[e],
|
|
379
510
|
status: "running",
|
|
380
|
-
startedAt:
|
|
511
|
+
startedAt: K()
|
|
381
512
|
};
|
|
382
513
|
}
|
|
383
|
-
yield*
|
|
384
|
-
steps:
|
|
385
|
-
currentStep:
|
|
514
|
+
yield* Z(e, n, {
|
|
515
|
+
steps: l,
|
|
516
|
+
currentStep: a.steps[0].index
|
|
386
517
|
});
|
|
387
|
-
let
|
|
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:
|
|
391
|
-
execute:
|
|
521
|
+
success: Pt,
|
|
522
|
+
execute: Vt(e, t, i, s, {
|
|
392
523
|
runId: n,
|
|
393
|
-
tenantId:
|
|
394
|
-
|
|
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" }),
|
|
400
|
-
for (let { index: e, step: t, result: n } of
|
|
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
|
-
|
|
403
|
-
...
|
|
534
|
+
l[e] = {
|
|
535
|
+
...l[e],
|
|
404
536
|
status: "failed",
|
|
405
|
-
completedAt:
|
|
537
|
+
completedAt: K(),
|
|
406
538
|
errorMessage: n.error
|
|
407
539
|
};
|
|
408
540
|
continue;
|
|
409
541
|
}
|
|
410
|
-
t.outputKey && n.value !== void 0 && (
|
|
411
|
-
...
|
|
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:
|
|
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 (
|
|
422
|
-
steps:
|
|
554
|
+
if (f !== void 0) return yield* Z(e, n, {
|
|
555
|
+
steps: l,
|
|
423
556
|
status: "failed",
|
|
424
|
-
errorMessage:
|
|
425
|
-
completedAt:
|
|
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*
|
|
432
|
-
steps:
|
|
433
|
-
currentStep:
|
|
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 } =
|
|
439
|
-
if (p.when !== void 0 && !
|
|
440
|
-
|
|
441
|
-
...
|
|
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:
|
|
444
|
-
skipReason:
|
|
445
|
-
}, yield*
|
|
446
|
-
steps:
|
|
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
|
|
587
|
+
let a = {
|
|
453
588
|
mode: p.reviewMode ?? "approve",
|
|
454
589
|
...p.options ? { options: p.options } : {},
|
|
455
|
-
prompt: R(p.prompt ?? "",
|
|
590
|
+
prompt: R(p.prompt ?? "", s)
|
|
456
591
|
};
|
|
457
|
-
|
|
458
|
-
...
|
|
592
|
+
l[f] = {
|
|
593
|
+
...l[f],
|
|
459
594
|
status: "waiting",
|
|
460
|
-
startedAt:
|
|
461
|
-
review:
|
|
462
|
-
}, yield*
|
|
463
|
-
steps:
|
|
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*
|
|
601
|
+
}), t.onEvent && (yield* G(t.onEvent({
|
|
467
602
|
kind: "review-needed",
|
|
468
603
|
runId: n,
|
|
469
|
-
flowName:
|
|
470
|
-
ownerId:
|
|
471
|
-
source:
|
|
604
|
+
flowName: i.name,
|
|
605
|
+
ownerId: o.ownerId,
|
|
606
|
+
source: o.source
|
|
472
607
|
})).pipe(C.catchAllCause(() => C.void)));
|
|
473
|
-
let
|
|
608
|
+
let c = mt({
|
|
474
609
|
step: p,
|
|
475
|
-
flow:
|
|
610
|
+
flow: i,
|
|
476
611
|
deps: t
|
|
477
|
-
}),
|
|
478
|
-
name:
|
|
479
|
-
schema:
|
|
480
|
-
timeoutMs:
|
|
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) =>
|
|
619
|
+
})), C.catchAllCause((e) => Ae.isInterruptedOnly(e) ? C.failCause(e) : C.succeed({
|
|
485
620
|
ok: !1,
|
|
486
621
|
cause: e
|
|
487
622
|
})));
|
|
488
|
-
if (!
|
|
489
|
-
let t = Number.isFinite(
|
|
490
|
-
return
|
|
491
|
-
...
|
|
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:
|
|
628
|
+
completedAt: K(),
|
|
494
629
|
errorMessage: t
|
|
495
|
-
}, yield*
|
|
496
|
-
steps:
|
|
630
|
+
}, yield* Z(e, n, {
|
|
631
|
+
steps: l,
|
|
497
632
|
status: "failed",
|
|
498
633
|
errorMessage: t,
|
|
499
|
-
completedAt:
|
|
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
|
|
507
|
-
if (
|
|
508
|
-
...
|
|
642
|
+
let m = u.a;
|
|
643
|
+
if (m.decision === "reject") return l[f] = {
|
|
644
|
+
...l[f],
|
|
509
645
|
status: "failed",
|
|
510
|
-
completedAt:
|
|
646
|
+
completedAt: K(),
|
|
511
647
|
errorMessage: "rejected by reviewer"
|
|
512
|
-
}, yield*
|
|
513
|
-
steps:
|
|
648
|
+
}, yield* Z(e, n, {
|
|
649
|
+
steps: l,
|
|
514
650
|
status: "cancelled",
|
|
515
|
-
humanResponse:
|
|
516
|
-
completedAt:
|
|
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 && (
|
|
523
|
-
...
|
|
659
|
+
p.outputKey && (s[p.outputKey] = m.value ?? m.text ?? m.decision ?? !0), l[f] = {
|
|
660
|
+
...l[f],
|
|
524
661
|
status: "succeeded",
|
|
525
|
-
completedAt:
|
|
526
|
-
output: { text: String(
|
|
527
|
-
}, yield*
|
|
528
|
-
steps:
|
|
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:
|
|
667
|
+
humanResponse: m,
|
|
531
668
|
currentStep: f + 1
|
|
532
669
|
});
|
|
533
670
|
continue;
|
|
534
671
|
}
|
|
535
|
-
|
|
536
|
-
...
|
|
672
|
+
l[f] = {
|
|
673
|
+
...l[f],
|
|
537
674
|
status: "running",
|
|
538
|
-
startedAt:
|
|
539
|
-
}, yield*
|
|
540
|
-
steps:
|
|
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:
|
|
547
|
-
execute:
|
|
683
|
+
success: Pt,
|
|
684
|
+
execute: Vt(e, t, p, s, {
|
|
548
685
|
runId: n,
|
|
549
|
-
tenantId:
|
|
550
|
-
|
|
686
|
+
tenantId: o.tenantId,
|
|
687
|
+
ownerId: o.ownerId
|
|
688
|
+
}, c)
|
|
551
689
|
});
|
|
552
|
-
if (m.error) return
|
|
553
|
-
...
|
|
690
|
+
if (m.error) return l[f] = {
|
|
691
|
+
...l[f],
|
|
554
692
|
status: "failed",
|
|
555
|
-
completedAt:
|
|
693
|
+
completedAt: K(),
|
|
556
694
|
errorMessage: m.error
|
|
557
|
-
}, yield*
|
|
558
|
-
steps:
|
|
695
|
+
}, yield* Z(e, n, {
|
|
696
|
+
steps: l,
|
|
559
697
|
status: "failed",
|
|
560
698
|
errorMessage: m.error,
|
|
561
|
-
completedAt:
|
|
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 && (
|
|
568
|
-
...
|
|
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:
|
|
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
|
-
|
|
577
|
-
|
|
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
|
|
584
|
-
return yield*
|
|
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:
|
|
727
|
+
completedAt: K(),
|
|
588
728
|
costMicroUsd: d
|
|
589
729
|
}), {
|
|
590
730
|
runId: n,
|
|
591
731
|
status: "succeeded",
|
|
592
732
|
output: f
|
|
593
733
|
};
|
|
594
|
-
}),
|
|
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*
|
|
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 =
|
|
743
|
+
let l = ht(o);
|
|
604
744
|
if (c.length >= l) {
|
|
605
|
-
yield*
|
|
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*
|
|
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(
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
788
|
+
}, Kt = (e) => [
|
|
649
789
|
e.orchestrator?.instructions ?? "You are an orchestrator that uses the available tools to produce a bundled result.",
|
|
650
|
-
|
|
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"),
|
|
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(
|
|
800
|
+
steps: w.Array(p),
|
|
660
801
|
error: w.optional(w.String)
|
|
661
|
-
}),
|
|
662
|
-
yield*
|
|
802
|
+
}), Jt = (e, t, n, r, i, a, o, s) => C.gen(function* () {
|
|
803
|
+
yield* zt(e, n, {
|
|
663
804
|
status: "running",
|
|
664
|
-
startedAt:
|
|
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:
|
|
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:
|
|
818
|
+
startedAt: K(),
|
|
678
819
|
...e
|
|
679
820
|
}), t;
|
|
680
821
|
}, d = (e, t) => {
|
|
681
822
|
c[e] = {
|
|
682
823
|
...c[e],
|
|
683
|
-
completedAt:
|
|
824
|
+
completedAt: K(),
|
|
684
825
|
...t
|
|
685
826
|
};
|
|
686
|
-
}, f = () =>
|
|
827
|
+
}, f = () => Z(e, n, {
|
|
687
828
|
steps: c,
|
|
688
829
|
currentStep: c.length,
|
|
689
830
|
costMicroUsd: l
|
|
690
831
|
}), p = {
|
|
691
|
-
run_agent:
|
|
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
|
|
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 (!
|
|
859
|
+
if (!s.ok) return d(i, {
|
|
718
860
|
status: "failed",
|
|
719
|
-
errorMessage:
|
|
720
|
-
}), yield* f(), `ERROR: ${
|
|
721
|
-
let
|
|
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 (!
|
|
729
|
-
let e = String(
|
|
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
|
|
736
|
-
return l +=
|
|
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:
|
|
739
|
-
costMicroUsd:
|
|
740
|
-
}), yield* f(),
|
|
880
|
+
output: { text: c.r.text },
|
|
881
|
+
costMicroUsd: p
|
|
882
|
+
}), yield* f(), c.r.text;
|
|
741
883
|
})
|
|
742
884
|
}),
|
|
743
|
-
generate_media:
|
|
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(
|
|
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:
|
|
757
|
-
let
|
|
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(
|
|
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
|
|
907
|
+
let m = yield* G(t.generateMedia({
|
|
766
908
|
modality: e,
|
|
767
909
|
prompt: r,
|
|
768
910
|
...i ? { model: i } : {},
|
|
769
|
-
...
|
|
770
|
-
...
|
|
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 (!
|
|
925
|
+
if (!m.ok) return d(p, {
|
|
783
926
|
status: "failed",
|
|
784
|
-
errorMessage:
|
|
785
|
-
}), yield* f(), `ERROR: ${
|
|
786
|
-
let
|
|
787
|
-
return
|
|
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:
|
|
790
|
-
}), yield* f(), { error:
|
|
932
|
+
errorMessage: h.error
|
|
933
|
+
}), yield* f(), { error: h.error }) : (l += h.costMicroUsd ?? 0, d(p, {
|
|
791
934
|
status: "succeeded",
|
|
792
|
-
url:
|
|
793
|
-
artifacts:
|
|
794
|
-
...
|
|
795
|
-
costMicroUsd:
|
|
796
|
-
|
|
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:
|
|
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*
|
|
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:
|
|
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 =
|
|
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 ?
|
|
985
|
+
}, m = yield* (t.resolveTools ? G(t.resolveTools(s, {
|
|
842
986
|
runId: n,
|
|
843
|
-
tenantId: o
|
|
844
|
-
|
|
845
|
-
|
|
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
|
|
860
|
-
system:
|
|
861
|
-
prompt:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
898
|
-
costMicroUsd: l
|
|
1047
|
+
completedAt: K(),
|
|
1048
|
+
costMicroUsd: l,
|
|
1049
|
+
costCompleteness: u
|
|
899
1050
|
}), {
|
|
900
1051
|
runId: n,
|
|
901
1052
|
status: "failed"
|
|
902
|
-
}) : (yield*
|
|
1053
|
+
}) : (yield* Z(e, n, {
|
|
903
1054
|
status: "succeeded",
|
|
904
1055
|
steps: c.steps,
|
|
905
1056
|
output: c.object,
|
|
906
|
-
completedAt:
|
|
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
|
-
}),
|
|
914
|
-
let { runId: r, flowRef: i, input: a } = n, o = yield* C.tryPromise(() => e.store.query(O(
|
|
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*
|
|
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:
|
|
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:
|
|
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*
|
|
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:
|
|
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*
|
|
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*
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
1138
|
+
}, Zt = (e) => e.map((e, t) => "id" in e && e.id ? e : {
|
|
987
1139
|
id: `step-${t}`,
|
|
988
1140
|
...e
|
|
989
|
-
}),
|
|
1141
|
+
}), Qt = (e) => {
|
|
990
1142
|
let t = [], n = z(e.steps);
|
|
991
|
-
for (let e of
|
|
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(
|
|
1152
|
+
for (let { step: t } of e.steps) t.outputKey && r.add(m(t.outputKey));
|
|
1001
1153
|
}
|
|
1002
|
-
if (t.length > 0) throw new
|
|
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
|
-
},
|
|
1008
|
-
let t =
|
|
1159
|
+
}, $t = (e) => {
|
|
1160
|
+
let t = f({
|
|
1009
1161
|
name: e.name,
|
|
1010
1162
|
mode: e.mode,
|
|
1011
|
-
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
|
|
1021
|
-
},
|
|
1022
|
-
let r = w.decodeUnknownSync(
|
|
1023
|
-
if (await e.store.update(
|
|
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
|
-
},
|
|
1177
|
+
}, tn = (e, t, n) => {
|
|
1026
1178
|
if (!Number.isFinite(t.getTime())) throw Error("cadence timestamp must be valid");
|
|
1027
|
-
return `cron-${
|
|
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
|
-
},
|
|
1184
|
+
}, nn = async (e) => {
|
|
1033
1185
|
let t = [];
|
|
1034
|
-
for (let n of
|
|
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
|
-
},
|
|
1049
|
-
let
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
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:
|
|
1220
|
+
id: c,
|
|
1061
1221
|
flowRef: o.flowRef,
|
|
1062
1222
|
flowName: o.flowRef,
|
|
1063
1223
|
status: "pending",
|
|
1064
1224
|
source: "cron",
|
|
1065
|
-
requestId:
|
|
1225
|
+
requestId: s,
|
|
1066
1226
|
input: o.defaultInput
|
|
1067
1227
|
}, { conflictColumns: ["id"] });
|
|
1068
|
-
let
|
|
1069
|
-
if (!
|
|
1070
|
-
let
|
|
1071
|
-
...
|
|
1072
|
-
runId:
|
|
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
|
|
1075
|
-
}, o.tenantId === null ? void 0 : { tenantId: o.tenantId })).status === "running" &&
|
|
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:
|
|
1083
|
-
started:
|
|
1242
|
+
matched: i,
|
|
1243
|
+
started: r,
|
|
1244
|
+
reconciled: o
|
|
1084
1245
|
};
|
|
1085
|
-
},
|
|
1086
|
-
n:
|
|
1087
|
-
seed:
|
|
1088
|
-
size:
|
|
1089
|
-
aspectRatio:
|
|
1090
|
-
providerOptions:
|
|
1091
|
-
}),
|
|
1092
|
-
voice:
|
|
1093
|
-
outputFormat:
|
|
1094
|
-
instructions:
|
|
1095
|
-
speed:
|
|
1096
|
-
language:
|
|
1097
|
-
providerOptions:
|
|
1098
|
-
}),
|
|
1099
|
-
aspectRatio:
|
|
1100
|
-
durationSeconds:
|
|
1101
|
-
resolution:
|
|
1102
|
-
fps:
|
|
1103
|
-
seed:
|
|
1104
|
-
generateAudio:
|
|
1105
|
-
maxInlineBytes:
|
|
1106
|
-
providerOptions:
|
|
1107
|
-
}),
|
|
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
|
-
}),
|
|
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
|
-
}),
|
|
1114
|
-
let r =
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
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*
|
|
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*
|
|
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*
|
|
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
|
-
|
|
1335
|
+
...vn(c.usage, c.providerMetadata, r)
|
|
1161
1336
|
};
|
|
1162
1337
|
}
|
|
1163
1338
|
if (n.modality === "audio") {
|
|
1164
|
-
let t = yield*
|
|
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*
|
|
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
|
-
|
|
1361
|
+
...vn(a.usage, a.providerMetadata, r)
|
|
1187
1362
|
};
|
|
1188
1363
|
}
|
|
1189
|
-
let { maxInlineBytes: a, providerOptions: o, ...s } = yield*
|
|
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*
|
|
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
|
-
|
|
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
|
-
},
|
|
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
|
-
}),
|
|
1244
|
-
yield*
|
|
1245
|
-
let
|
|
1246
|
-
if (
|
|
1247
|
-
missing:
|
|
1248
|
-
message: `missing required brief field(s): ${
|
|
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
|
|
1251
|
-
return yield* C.promise(() =>
|
|
1252
|
-
let
|
|
1253
|
-
if (!
|
|
1254
|
-
await
|
|
1255
|
-
id:
|
|
1256
|
-
flowRef:
|
|
1257
|
-
flowName:
|
|
1258
|
-
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:
|
|
1261
|
-
requestId:
|
|
1262
|
-
input:
|
|
1263
|
-
ownerId:
|
|
1435
|
+
source: c,
|
|
1436
|
+
requestId: o,
|
|
1437
|
+
input: i,
|
|
1438
|
+
ownerId: xn(t)
|
|
1264
1439
|
});
|
|
1265
|
-
let
|
|
1266
|
-
runId:
|
|
1267
|
-
flowRef:
|
|
1268
|
-
input:
|
|
1269
|
-
source:
|
|
1270
|
-
requestId:
|
|
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
|
|
1273
|
-
runId:
|
|
1274
|
-
requestId:
|
|
1275
|
-
admission:
|
|
1447
|
+
return v.make({
|
|
1448
|
+
runId: s,
|
|
1449
|
+
requestId: o,
|
|
1450
|
+
admission: l
|
|
1276
1451
|
});
|
|
1277
1452
|
}));
|
|
1278
|
-
}),
|
|
1279
|
-
return yield*
|
|
1280
|
-
try: () =>
|
|
1281
|
-
let
|
|
1282
|
-
if (!
|
|
1283
|
-
let
|
|
1284
|
-
if (!
|
|
1285
|
-
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
|
|
1289
|
-
if (typeof
|
|
1290
|
-
let
|
|
1291
|
-
...
|
|
1292
|
-
runId:
|
|
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 (
|
|
1295
|
-
let
|
|
1296
|
-
return
|
|
1297
|
-
runId:
|
|
1298
|
-
requestId:
|
|
1299
|
-
admission:
|
|
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
|
-
}),
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
1320
|
-
let
|
|
1321
|
-
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:
|
|
1324
|
-
}),
|
|
1325
|
-
if (
|
|
1326
|
-
let
|
|
1327
|
-
if (!
|
|
1328
|
-
let
|
|
1329
|
-
if (!
|
|
1330
|
-
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
|
|
1334
|
-
if (
|
|
1335
|
-
runId:
|
|
1336
|
-
status:
|
|
1337
|
-
message: `run is "${
|
|
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
|
|
1340
|
-
try: () =>
|
|
1341
|
-
catch: () =>
|
|
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 (
|
|
1344
|
-
runId:
|
|
1345
|
-
status:
|
|
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
|
|
1349
|
-
runId: w.Literal(
|
|
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
|
-
...
|
|
1359
|
-
runId:
|
|
1360
|
-
}).pipe(C.mapError(() =>
|
|
1361
|
-
...
|
|
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
|
-
},
|
|
1364
|
-
try: () =>
|
|
1365
|
-
workflowName:
|
|
1366
|
-
executionId:
|
|
1367
|
-
},
|
|
1368
|
-
catch: () =>
|
|
1369
|
-
}),
|
|
1370
|
-
return yield* w.decodeUnknown(
|
|
1371
|
-
runId:
|
|
1372
|
-
stepIndex:
|
|
1373
|
-
executionId:
|
|
1374
|
-
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(() =>
|
|
1377
|
-
}),
|
|
1378
|
-
id: t.id ?? `flow-${
|
|
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
|
-
})),
|
|
1381
|
-
let t =
|
|
1382
|
-
base:
|
|
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
|
-
|
|
1579
|
+
ut(e.humanReviewTimeoutMs === void 0 ? {} : { humanReviewTimeoutMs: e.humanReviewTimeoutMs }), Le({
|
|
1386
1580
|
source: "plugin",
|
|
1387
|
-
table:
|
|
1581
|
+
table: N.tableName,
|
|
1388
1582
|
timeColumn: "createdAt",
|
|
1389
|
-
ttlMs: e.runsTtlMs ??
|
|
1390
|
-
envVar:
|
|
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:
|
|
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
|
|
1648
|
+
return Me({
|
|
1455
1649
|
name: t,
|
|
1456
|
-
baseName:
|
|
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: [
|
|
1459
|
-
|
|
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 {
|
|
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 };
|