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