@voltro/ai 0.73.0 → 0.75.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 +449 -0
- package/dist/index.d.ts +238 -1
- package/dist/index.js +625 -537
- package/dist/{inferenceQueue-CXEVU6mI.js → inferenceQueue-CdWTzRp7.js} +310 -229
- package/dist/workflow.d.ts +26 -6
- package/dist/workflow.js +80 -79
- package/package.json +5 -5
|
@@ -1,45 +1,45 @@
|
|
|
1
1
|
import { c as e, o as t, r as n } from "./provider-Cts1BRhY.js";
|
|
2
2
|
import { NoObjectGeneratedError as r, Output as i, experimental_transcribe as a, generateObject as o, generateText as s, jsonSchema as c, stepCountIs as l, tool as u } from "ai";
|
|
3
|
-
import { Context as d,
|
|
4
|
-
import { and as
|
|
5
|
-
import { Ajv as
|
|
6
|
-
import { Ajv2019 as
|
|
7
|
-
import { Ajv2020 as
|
|
8
|
-
import
|
|
9
|
-
import { createHash as
|
|
3
|
+
import { Context as d, Data as f, Effect as p, JSONSchema as m, Metric as h, MetricBoundaries as ee, Runtime as te, Schema as g, Stream as ne } from "effect";
|
|
4
|
+
import { and as _, bigint as re, eq as v, generateId as y, gte as ie, id as b, integer as x, isNull as ae, json as S, queryFor as C, registerRetention as w, retentionTtlMsFromEnv as oe, table as T, text as E, timestamp as D } from "@voltro/database";
|
|
5
|
+
import { Ajv as se } from "ajv";
|
|
6
|
+
import { Ajv2019 as ce } from "ajv/dist/2019.js";
|
|
7
|
+
import { Ajv2020 as le } from "ajv/dist/2020.js";
|
|
8
|
+
import ue from "ajv-formats";
|
|
9
|
+
import { createHash as de } from "node:crypto";
|
|
10
10
|
//#region src/tools.ts
|
|
11
|
-
var
|
|
11
|
+
var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
|
|
12
12
|
...e,
|
|
13
|
-
[
|
|
14
|
-
}),
|
|
13
|
+
[pe]: !0
|
|
14
|
+
}), he = (e) => typeof e == "object" && !!e && e[pe] === !0, ge = (e) => {
|
|
15
15
|
let t = e.default;
|
|
16
16
|
if (typeof t != "function") return 0;
|
|
17
17
|
let n = 0;
|
|
18
|
-
for (let r of Object.values(e))
|
|
18
|
+
for (let r of Object.values(e)) he(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
|
|
19
19
|
return n;
|
|
20
|
-
},
|
|
20
|
+
}, _e = (e, t, n) => {
|
|
21
21
|
let r = t ?? te.defaultRuntime;
|
|
22
22
|
return te.runPromise(r)(e, n === void 0 ? {} : { signal: n });
|
|
23
|
-
},
|
|
23
|
+
}, ve = (e, t, n) => n ? e.pipe(p.timeoutFail({
|
|
24
24
|
duration: `${n} millis`,
|
|
25
25
|
onTimeout: () => /* @__PURE__ */ Error(`tool '${t}' timed out`)
|
|
26
|
-
})) : e,
|
|
27
|
-
if (e.execute) return
|
|
26
|
+
})) : e, ye = (e, t, n) => {
|
|
27
|
+
if (e.execute) return _e(ve(fe(e.execute, t), e.name, e.timeoutMs), n.runtime, n.abortSignal);
|
|
28
28
|
if (e.handler) {
|
|
29
29
|
let r = e.handler, i = r(t, n);
|
|
30
|
-
return
|
|
30
|
+
return p.isEffect(i) ? _e(ve(i, e.name, e.timeoutMs), n.runtime, n.abortSignal) : i;
|
|
31
31
|
}
|
|
32
32
|
return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
|
|
33
|
-
},
|
|
34
|
-
let t =
|
|
33
|
+
}, be = (e) => {
|
|
34
|
+
let t = m.make(e);
|
|
35
35
|
return t && t.type === "object" ? t : {
|
|
36
36
|
type: "object",
|
|
37
37
|
properties: {},
|
|
38
38
|
additionalProperties: !1
|
|
39
39
|
};
|
|
40
|
-
},
|
|
40
|
+
}, xe = (e) => {
|
|
41
41
|
let t = e.inputJsonSchema;
|
|
42
|
-
return t === void 0 ?
|
|
42
|
+
return t === void 0 ? be(e.input) : t.type === "object" ? t : {
|
|
43
43
|
type: "object",
|
|
44
44
|
properties: {},
|
|
45
45
|
additionalProperties: !0
|
|
@@ -48,7 +48,7 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
48
48
|
let n = {};
|
|
49
49
|
for (let [r, i] of Object.entries(e)) n[i.name || r] = u({
|
|
50
50
|
description: i.description,
|
|
51
|
-
inputSchema: c(
|
|
51
|
+
inputSchema: c(xe(i)),
|
|
52
52
|
execute: async (e, n) => {
|
|
53
53
|
let r = n?.abortSignal ?? t.abortSignal;
|
|
54
54
|
r?.throwIfAborted();
|
|
@@ -56,33 +56,33 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
56
56
|
...t,
|
|
57
57
|
...n?.toolCallId === void 0 ? {} : { invocationId: n.toolCallId },
|
|
58
58
|
...r === void 0 ? {} : { abortSignal: r }
|
|
59
|
-
}, o = await
|
|
59
|
+
}, o = await p.runPromise(g.decodeUnknown(i.input)(e));
|
|
60
60
|
r?.throwIfAborted();
|
|
61
|
-
let s = await
|
|
62
|
-
return i.output ?
|
|
61
|
+
let s = await ye(i, o, a);
|
|
62
|
+
return i.output ? p.runPromise(g.decodeUnknown(i.output)(s)) : s;
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
return n;
|
|
66
|
-
}, k = class extends
|
|
67
|
-
tenantId:
|
|
68
|
-
limitUsd:
|
|
69
|
-
spentUsd:
|
|
70
|
-
attemptedUsd:
|
|
66
|
+
}, k = class extends g.TaggedError()("AiBudgetExceeded", {
|
|
67
|
+
tenantId: g.NullOr(g.String),
|
|
68
|
+
limitUsd: g.Number,
|
|
69
|
+
spentUsd: g.Number,
|
|
70
|
+
attemptedUsd: g.Number
|
|
71
71
|
}) {}, A = "_voltro_ai_budget", j = "_voltro_ai_budget_reservations", M = T(A, {
|
|
72
|
-
id:
|
|
72
|
+
id: b({ prefix: "aib" }),
|
|
73
73
|
bucket: E().maxLength(191),
|
|
74
74
|
tenantId: E().nullable(),
|
|
75
75
|
reservedMicroUsd: re().default("0").narrowedFrom("integer"),
|
|
76
76
|
updatedAt: D().default("now")
|
|
77
|
-
}).unique("byAiBudgetBucket", ["bucket"]),
|
|
78
|
-
id:
|
|
77
|
+
}).unique("byAiBudgetBucket", ["bucket"]), Se = T(j, {
|
|
78
|
+
id: b({ prefix: "air" }),
|
|
79
79
|
reservationId: E().maxLength(191),
|
|
80
80
|
bucket: E().maxLength(191),
|
|
81
81
|
tenantId: E().nullable(),
|
|
82
82
|
amountMicroUsd: re(),
|
|
83
83
|
releasedAt: D().nullable(),
|
|
84
84
|
updatedAt: D().default("now")
|
|
85
|
-
}).unique("byAiBudgetReservation", ["reservationId"]), N = class extends Error {},
|
|
85
|
+
}).unique("byAiBudgetReservation", ["reservationId"]), N = class extends Error {}, Ce = (e, t, n) => {
|
|
86
86
|
if (!Number.isFinite(e) || e < 0) throw RangeError(`${t} must be finite and non-negative`);
|
|
87
87
|
let r = e * 1e6, i = n === "up" ? Math.ceil(r) : Math.floor(r);
|
|
88
88
|
if (!Number.isSafeInteger(i)) throw RangeError(`${t} exceeds the safe micro-USD range`);
|
|
@@ -92,39 +92,39 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
92
92
|
let t = String(e);
|
|
93
93
|
if (!/^(0|[1-9][0-9]*)$/.test(t)) throw Error("AI budget counter is invalid; refusing to assume zero");
|
|
94
94
|
return BigInt(t);
|
|
95
|
-
},
|
|
95
|
+
}, we = (e) => {
|
|
96
96
|
if (typeof e != "string" || e.length === 0 || e.length > 191) throw RangeError("AI budget reservationId must contain 1–191 characters");
|
|
97
97
|
return e;
|
|
98
|
-
},
|
|
99
|
-
let e =
|
|
100
|
-
for (let t of [A, j])
|
|
98
|
+
}, Te = () => {
|
|
99
|
+
let e = oe(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
|
|
100
|
+
for (let t of [A, j]) w({
|
|
101
101
|
source: "plugin",
|
|
102
102
|
table: t,
|
|
103
103
|
timeColumn: "updatedAt",
|
|
104
104
|
ttlMs: e
|
|
105
105
|
});
|
|
106
|
-
},
|
|
106
|
+
}, Ee = async (e, t) => {
|
|
107
107
|
for (let n = 0;; n++) try {
|
|
108
108
|
return await e.transactional(t);
|
|
109
109
|
} catch (e) {
|
|
110
110
|
if (!(e instanceof N) || n >= 31) throw e;
|
|
111
111
|
await new Promise((e) => setTimeout(e, n + 1));
|
|
112
112
|
}
|
|
113
|
-
},
|
|
113
|
+
}, De = (e) => p.tryPromise({
|
|
114
114
|
try: e,
|
|
115
115
|
catch: (e) => e
|
|
116
|
-
}).pipe(
|
|
117
|
-
let n =
|
|
116
|
+
}).pipe(p.catchAll((e) => e instanceof k ? p.fail(e) : p.die(e))), Oe = (e, t) => p.gen(function* () {
|
|
117
|
+
let n = Ce(t.limitUsd, "limitUsd", "down"), r = Ce(t.addUsd ?? 0, "addUsd", "up"), i = t.tenantId ?? null;
|
|
118
118
|
if (t.since !== void 0 && !Number.isFinite(t.since.getTime())) throw RangeError("AI budget since must be a valid Date");
|
|
119
119
|
let a = `${i ?? "global"}::${t.since === void 0 ? "all" : t.since.getTime()}`;
|
|
120
120
|
if (a.length > 191) throw RangeError("AI budget tenant/window key exceeds 191 characters");
|
|
121
|
-
let o =
|
|
121
|
+
let o = we(t.reservationId ?? y({
|
|
122
122
|
kind: "typeid",
|
|
123
123
|
prefix: "air"
|
|
124
124
|
}, "_voltro_ai_budget_reservations"));
|
|
125
|
-
|
|
125
|
+
Te();
|
|
126
126
|
let s = async (e) => {
|
|
127
|
-
let [t] = await e.query(
|
|
127
|
+
let [t] = await e.query(C(M).where(v("bucket", a)).descriptor);
|
|
128
128
|
if (t && t.tenantId !== i) throw Error("AI budget bucket belongs to a different tenant");
|
|
129
129
|
return t;
|
|
130
130
|
}, c = (e) => {
|
|
@@ -135,11 +135,11 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
135
135
|
attemptedUsd: t.addUsd ?? 0
|
|
136
136
|
});
|
|
137
137
|
};
|
|
138
|
-
return r === 0n ? yield*
|
|
138
|
+
return r === 0n ? yield* De(async () => {
|
|
139
139
|
let t = await s(e);
|
|
140
140
|
return c(t ? P(t.reservedMicroUsd) : 0n), null;
|
|
141
|
-
}) : yield*
|
|
142
|
-
let t =
|
|
141
|
+
}) : yield* De(() => Ee(e, async (e) => {
|
|
142
|
+
let t = y({
|
|
143
143
|
kind: "typeid",
|
|
144
144
|
prefix: "air"
|
|
145
145
|
}, j), n = /* @__PURE__ */ new Date(), l = await e.insertIgnore(j, {
|
|
@@ -166,9 +166,9 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
166
166
|
if (await e.updateMany("_voltro_ai_budget", {
|
|
167
167
|
reservedMicroUsd: String(d + r),
|
|
168
168
|
updatedAt: n
|
|
169
|
-
}, { where:
|
|
169
|
+
}, { where: _(v("id", u.id), v("reservedMicroUsd", u.reservedMicroUsd)) }) !== 1) throw new N("AI budget counter changed; discard this receipt and retry");
|
|
170
170
|
} else {
|
|
171
|
-
let t =
|
|
171
|
+
let t = y({
|
|
172
172
|
kind: "typeid",
|
|
173
173
|
prefix: "aib"
|
|
174
174
|
}, A);
|
|
@@ -187,31 +187,31 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
187
187
|
status: "reserved"
|
|
188
188
|
};
|
|
189
189
|
}));
|
|
190
|
-
}),
|
|
191
|
-
return
|
|
192
|
-
let n =
|
|
190
|
+
}), ke = (e, t) => p.gen(function* () {
|
|
191
|
+
return we(t.reservationId), yield* p.promise(() => Ee(e, async (e) => {
|
|
192
|
+
let n = C(Se).where(_(v("reservationId", t.reservationId), t.tenantId === null ? ae("tenantId") : v("tenantId", t.tenantId))).descriptor, [r] = await e.query(n);
|
|
193
193
|
if (!r) return "not-found";
|
|
194
194
|
if (r.releasedAt !== null) return "already-released";
|
|
195
195
|
let i = /* @__PURE__ */ new Date();
|
|
196
196
|
if (await e.updateMany("_voltro_ai_budget_reservations", {
|
|
197
197
|
releasedAt: i,
|
|
198
198
|
updatedAt: i
|
|
199
|
-
}, { where:
|
|
199
|
+
}, { where: _(v("id", r.id), ae("releasedAt")) }) !== 1) {
|
|
200
200
|
let [t] = await e.query(n);
|
|
201
201
|
if (t !== void 0 && t.releasedAt !== null) return "already-released";
|
|
202
202
|
throw new N("AI budget release raced; retry");
|
|
203
203
|
}
|
|
204
|
-
let [a] = await e.query(
|
|
204
|
+
let [a] = await e.query(C(M).where(v("bucket", r.bucket)).descriptor);
|
|
205
205
|
if (!a || a.tenantId !== t.tenantId) throw Error("AI budget counter missing or mismatched; refusing unproved credit");
|
|
206
206
|
let o = P(a.reservedMicroUsd), s = P(r.amountMicroUsd);
|
|
207
207
|
if (s > o) throw Error("AI budget receipt exceeds its counter; refusing unproved credit");
|
|
208
208
|
if (await e.updateMany("_voltro_ai_budget", {
|
|
209
209
|
reservedMicroUsd: String(o - s),
|
|
210
210
|
updatedAt: i
|
|
211
|
-
}, { where:
|
|
211
|
+
}, { where: _(v("id", a.id), v("reservedMicroUsd", a.reservedMicroUsd)) }) !== 1) throw new N("AI budget counter changed; discard this release and retry");
|
|
212
212
|
return "released";
|
|
213
213
|
}));
|
|
214
|
-
}),
|
|
214
|
+
}), Ae = {
|
|
215
215
|
"claude-opus-4-8": {
|
|
216
216
|
inputPer1M: 15,
|
|
217
217
|
outputPer1M: 75
|
|
@@ -256,21 +256,21 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
256
256
|
inputPer1M: .1,
|
|
257
257
|
outputPer1M: .4
|
|
258
258
|
}
|
|
259
|
-
}, F = {},
|
|
259
|
+
}, F = {}, je = (e) => {
|
|
260
260
|
let t = F;
|
|
261
261
|
return F = { ...e }, t;
|
|
262
|
-
},
|
|
263
|
-
...
|
|
262
|
+
}, Me = () => ({
|
|
263
|
+
...Ae,
|
|
264
264
|
...F
|
|
265
|
-
}),
|
|
266
|
-
let t =
|
|
265
|
+
}), Ne = (e) => {
|
|
266
|
+
let t = Me();
|
|
267
267
|
if (t[e] !== void 0) return t[e];
|
|
268
268
|
let n = e.indexOf("/");
|
|
269
269
|
if (n > 0) {
|
|
270
270
|
let r = e.slice(n + 1);
|
|
271
271
|
if (t[r] !== void 0) return t[r];
|
|
272
272
|
}
|
|
273
|
-
},
|
|
273
|
+
}, I = (e) => typeof e.unit == "string", Pe = (e) => I(e) ? {
|
|
274
274
|
unit: e.unit,
|
|
275
275
|
input: e.input ?? 0,
|
|
276
276
|
output: e.output ?? 0
|
|
@@ -278,7 +278,7 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
278
278
|
unit: "tokens",
|
|
279
279
|
input: e.inputTokens ?? 0,
|
|
280
280
|
output: e.outputTokens ?? 0
|
|
281
|
-
},
|
|
281
|
+
}, L = (e, t) => {
|
|
282
282
|
let { unit: n, input: r, output: i } = Pe(e);
|
|
283
283
|
if (t.actualCostUsd !== void 0) {
|
|
284
284
|
if (!Number.isFinite(t.actualCostUsd) || t.actualCostUsd < 0) throw RangeError("estimateCostUsd: actualCostUsd must be a finite, non-negative USD amount.");
|
|
@@ -302,7 +302,7 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
302
302
|
costSource: "unpriced",
|
|
303
303
|
unit: n
|
|
304
304
|
};
|
|
305
|
-
let a = t.price ??
|
|
305
|
+
let a = t.price ?? Ne(t.model) ?? {
|
|
306
306
|
inputPer1M: 0,
|
|
307
307
|
outputPer1M: 0
|
|
308
308
|
}, o = r / 1e6 * a.inputPer1M, s = i / 1e6 * a.outputPer1M;
|
|
@@ -315,42 +315,59 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
315
315
|
costSource: "estimated",
|
|
316
316
|
unit: n
|
|
317
317
|
};
|
|
318
|
-
},
|
|
319
|
-
id:
|
|
318
|
+
}, R = "_voltro_ai_usage", Fe = T(R, {
|
|
319
|
+
id: b({ prefix: "aiu" }),
|
|
320
320
|
tenantId: E().nullable(),
|
|
321
321
|
provider: E(),
|
|
322
322
|
model: E(),
|
|
323
323
|
operation: E(),
|
|
324
324
|
agent: E().nullable(),
|
|
325
|
-
inputTokens:
|
|
326
|
-
outputTokens:
|
|
327
|
-
costMicroUsd:
|
|
325
|
+
inputTokens: x().default(0),
|
|
326
|
+
outputTokens: x().default(0),
|
|
327
|
+
costMicroUsd: x().default(0),
|
|
328
328
|
costSource: E().default("estimated"),
|
|
329
329
|
unit: E().default("tokens"),
|
|
330
330
|
promptId: E().nullable(),
|
|
331
331
|
promptDigest: E().nullable(),
|
|
332
|
-
promptRevision:
|
|
332
|
+
promptRevision: x().nullable(),
|
|
333
333
|
requestId: E().maxLength(191).nullable(),
|
|
334
|
-
attempt:
|
|
334
|
+
attempt: x().nullable(),
|
|
335
335
|
receiptKey: E().maxLength(191).backfill((e) => `aiu-pre-receipt-${String(e.id)}`),
|
|
336
336
|
calledAt: D().default("now")
|
|
337
337
|
}).index(["tenantId"]).index(["promptDigest"]).unique("byAiUsageReceipt", ["receiptKey"]), Ie = (e) => {
|
|
338
338
|
let t = e?.gateway?.cost, n = typeof t == "string" ? t.trim() : void 0, r = typeof t == "number" ? t : n !== void 0 && /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(n) ? Number(n) : NaN;
|
|
339
339
|
return Number.isFinite(r) && r >= 0 ? r : void 0;
|
|
340
|
-
}, Le = (
|
|
340
|
+
}, Le = class extends f.TaggedError("AiUsageReceiptConflict") {
|
|
341
|
+
get message() {
|
|
342
|
+
let e = Object.keys(this.recorded).filter((e) => this.recorded[e] !== this.attempted[e]).map((e) => `${e} ${String(this.recorded[e])} → ${String(this.attempted[e])}`);
|
|
343
|
+
return `AI usage receipt ${this.receiptKey} was recorded again with different values (${e.join(", ")}). A replay of the same paid call has the same values; the row keeps what was recorded first.`;
|
|
344
|
+
}
|
|
345
|
+
}, Re = class extends f.TaggedError("AiUsageLedgerError") {
|
|
346
|
+
get message() {
|
|
347
|
+
return `AI usage receipt ${this.receiptKey} could not be written: ${this.cause instanceof Error ? this.cause.message : String(this.cause)}`;
|
|
348
|
+
}
|
|
349
|
+
}, ze = (e) => ({
|
|
350
|
+
tenantId: e.tenantId ?? null,
|
|
351
|
+
provider: String(e.provider),
|
|
352
|
+
model: String(e.model),
|
|
353
|
+
operation: String(e.operation),
|
|
354
|
+
inputTokens: Number(e.inputTokens),
|
|
355
|
+
outputTokens: Number(e.outputTokens),
|
|
356
|
+
costMicroUsd: Number(e.costMicroUsd)
|
|
357
|
+
}), Be = (e, t) => (w({
|
|
341
358
|
source: "plugin",
|
|
342
|
-
table:
|
|
359
|
+
table: R,
|
|
343
360
|
timeColumn: "calledAt",
|
|
344
|
-
ttlMs:
|
|
345
|
-
}),
|
|
346
|
-
let n =
|
|
361
|
+
ttlMs: oe(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
|
|
362
|
+
}), p.gen(function* () {
|
|
363
|
+
let n = L(t.usage, {
|
|
347
364
|
model: t.model,
|
|
348
365
|
...t.price === void 0 ? {} : { price: t.price },
|
|
349
366
|
...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
|
|
350
|
-
}), r = t.receiptKey ?? (t.requestId === void 0 ?
|
|
367
|
+
}), r = t.receiptKey ?? (t.requestId === void 0 ? y({
|
|
351
368
|
kind: "typeid",
|
|
352
369
|
prefix: "aiu"
|
|
353
|
-
}, "_voltro_ai_usage") : `${t.requestId}#${t.attempt ?? 0}`), i =
|
|
370
|
+
}, "_voltro_ai_usage") : `${t.requestId}#${t.attempt ?? 0}`), i = {
|
|
354
371
|
tenantId: t.tenantId ?? null,
|
|
355
372
|
provider: t.provider,
|
|
356
373
|
model: t.model,
|
|
@@ -368,68 +385,110 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
368
385
|
attempt: t.attempt ?? null,
|
|
369
386
|
receiptKey: r,
|
|
370
387
|
calledAt: t.calledAt ?? /* @__PURE__ */ new Date()
|
|
371
|
-
},
|
|
372
|
-
|
|
388
|
+
}, a = yield* p.tryPromise({
|
|
389
|
+
try: () => e.insertIgnoreWithOutcome(R, i, { conflictColumns: ["receiptKey"] }),
|
|
390
|
+
catch: (e) => new Re({
|
|
391
|
+
receiptKey: String(r),
|
|
392
|
+
cause: e
|
|
393
|
+
})
|
|
394
|
+
});
|
|
395
|
+
if (a.outcome === "inserted") return {
|
|
373
396
|
...n,
|
|
374
|
-
receipt:
|
|
397
|
+
receipt: "recorded"
|
|
398
|
+
};
|
|
399
|
+
let o = ze(a.row), s = ze(i);
|
|
400
|
+
return Object.keys(o).some((e) => o[e] !== s[e]) ? yield* p.fail(new Le({
|
|
401
|
+
receiptKey: String(r),
|
|
402
|
+
recorded: o,
|
|
403
|
+
attempted: s
|
|
404
|
+
})) : {
|
|
405
|
+
...Ve(a.row, n),
|
|
406
|
+
receipt: "replayed"
|
|
407
|
+
};
|
|
408
|
+
})), Ve = (e, t) => {
|
|
409
|
+
let n = Number(e.costMicroUsd) / 1e6;
|
|
410
|
+
return {
|
|
411
|
+
...t,
|
|
412
|
+
inputTokens: Number(e.inputTokens),
|
|
413
|
+
outputTokens: Number(e.outputTokens),
|
|
414
|
+
totalCostUsd: n,
|
|
415
|
+
costSource: e.costSource ?? t.costSource
|
|
375
416
|
};
|
|
376
|
-
}
|
|
417
|
+
}, He = (e, t) => Be(e, t).pipe(p.asVoid, p.catchAllCause((e) => p.logError("AI usage NOT booked as recorded — the call itself succeeded and was returned", e).pipe(p.annotateLogs({
|
|
418
|
+
scope: "voltro:ai:usage",
|
|
419
|
+
provider: t.provider,
|
|
420
|
+
model: t.model,
|
|
421
|
+
operation: t.operation,
|
|
422
|
+
...I(t.usage) ? {
|
|
423
|
+
unit: t.usage.unit,
|
|
424
|
+
input: t.usage.input ?? null,
|
|
425
|
+
output: t.usage.output ?? null
|
|
426
|
+
} : {
|
|
427
|
+
inputTokens: t.usage.inputTokens ?? null,
|
|
428
|
+
outputTokens: t.usage.outputTokens ?? null
|
|
429
|
+
},
|
|
430
|
+
...t.requestId === void 0 ? {} : {
|
|
431
|
+
requestId: t.requestId,
|
|
432
|
+
attempt: t.attempt ?? 0
|
|
433
|
+
},
|
|
434
|
+
...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
|
|
435
|
+
})))), Ue = (e, t = {}) => p.promise(async () => {
|
|
377
436
|
let n = [
|
|
378
|
-
...t.tenantId === void 0 ? [] : [
|
|
437
|
+
...t.tenantId === void 0 ? [] : [v("tenantId", t.tenantId)],
|
|
379
438
|
...t.since === void 0 ? [] : [ie("calledAt", t.since)],
|
|
380
|
-
...t.promptDigest === void 0 ? [] : [
|
|
381
|
-
], r =
|
|
439
|
+
...t.promptDigest === void 0 ? [] : [v("promptDigest", t.promptDigest)]
|
|
440
|
+
], r = C(Fe), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : _(...n));
|
|
382
441
|
return (await e.query(i.descriptor)).reduce((e, t) => e + (Number(t.costMicroUsd) || 0), 0) / 1e6;
|
|
383
|
-
}),
|
|
442
|
+
}), We = ee.exponential({
|
|
384
443
|
start: .001,
|
|
385
444
|
factor: 2,
|
|
386
445
|
count: 16
|
|
387
|
-
}),
|
|
446
|
+
}), z = h.counter("voltro_ai_calls_total", { description: "Total AI provider calls (generate + stream)." }), Ge = h.counter("voltro_ai_call_errors_total", { description: "AI provider calls that errored." }), B = h.histogram("voltro_ai_call_duration_seconds", We, "AI provider call duration in seconds."), Ke = h.counter("voltro_ai_input_tokens_total", {
|
|
388
447
|
description: "Total prompt (input) tokens across AI calls.",
|
|
389
448
|
incremental: !0
|
|
390
|
-
}),
|
|
449
|
+
}), qe = h.counter("voltro_ai_output_tokens_total", {
|
|
391
450
|
description: "Total completion (output) tokens across AI calls.",
|
|
392
451
|
incremental: !0
|
|
393
|
-
}),
|
|
452
|
+
}), Je = h.counter("voltro_ai_cost_microusd_total", {
|
|
394
453
|
description: "Total estimated AI spend in micro-USD (USD × 1e6).",
|
|
395
454
|
incremental: !0
|
|
396
|
-
}),
|
|
455
|
+
}), V = (e, t) => ({
|
|
397
456
|
provider: e.name,
|
|
398
457
|
model: e.model ?? e.name,
|
|
399
458
|
operation: t
|
|
400
|
-
}),
|
|
401
|
-
let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i =
|
|
459
|
+
}), H = (e, t, n) => e.pipe(p.tagMetrics("provider", t.provider), p.tagMetrics("model", t.model), p.tagMetrics("operation", t.operation), p.tagMetrics("status", n)), Ye = (e, t) => {
|
|
460
|
+
let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = L({
|
|
402
461
|
inputTokens: n,
|
|
403
462
|
outputTokens: r
|
|
404
463
|
}, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
|
|
405
|
-
return
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
464
|
+
return p.all([
|
|
465
|
+
H(h.incrementBy(Ke, n), e, "ok"),
|
|
466
|
+
H(h.incrementBy(qe, r), e, "ok"),
|
|
467
|
+
H(h.incrementBy(Je, a), e, "ok")
|
|
409
468
|
], { discard: !0 });
|
|
410
|
-
},
|
|
411
|
-
let r = yield*
|
|
412
|
-
return yield* n.pipe(
|
|
469
|
+
}, U = (e, t, n) => p.gen(function* () {
|
|
470
|
+
let r = yield* p.clockWith((e) => e.currentTimeMillis);
|
|
471
|
+
return yield* n.pipe(p.tap((n) => Ye(e, t(n))), p.tap(() => H(h.increment(z), e, "ok").pipe(p.zipRight(p.clockWith((e) => e.currentTimeMillis).pipe(p.flatMap((t) => H(h.update(B, (t - r) / 1e3), e, "ok")))))), p.tapError(() => H(h.increment(z), e, "error").pipe(p.zipRight(H(h.increment(Ge), e, "error")), p.zipRight(p.clockWith((e) => e.currentTimeMillis).pipe(p.flatMap((t) => H(h.update(B, (t - r) / 1e3), e, "error")))))), p.withSpan("voltro.ai.call", { attributes: {
|
|
413
472
|
"ai.provider": e.provider,
|
|
414
473
|
"ai.model": e.model,
|
|
415
474
|
"ai.operation": e.operation
|
|
416
475
|
} }));
|
|
417
|
-
}),
|
|
476
|
+
}), Xe = (e, t) => {
|
|
418
477
|
let n = Date.now();
|
|
419
|
-
return t.pipe(ne.tap((t) => t._tag === "done" ?
|
|
478
|
+
return t.pipe(ne.tap((t) => t._tag === "done" ? H(h.increment(z), e, "ok").pipe(p.zipRight(H(h.update(B, (Date.now() - n) / 1e3), e, "ok")), p.zipRight(Ye(e, t.usage ?? {}))) : t._tag === "error" ? H(h.increment(z), e, "error").pipe(p.zipRight(H(h.increment(Ge), e, "error")), p.zipRight(H(h.update(B, (Date.now() - n) / 1e3), e, "error"))) : p.void), ne.withSpan("voltro.ai.call", { attributes: {
|
|
420
479
|
"ai.provider": e.provider,
|
|
421
480
|
"ai.model": e.model,
|
|
422
481
|
"ai.operation": e.operation
|
|
423
482
|
} }));
|
|
424
|
-
},
|
|
483
|
+
}, Ze = (e) => {
|
|
425
484
|
let t = structuredClone(e), n = {
|
|
426
485
|
strict: !0,
|
|
427
486
|
strictTypes: !1,
|
|
428
487
|
strictTuples: !1,
|
|
429
488
|
strictRequired: !1,
|
|
430
489
|
allowUnionTypes: !0
|
|
431
|
-
}, r = t.$schema, i = r === "https://json-schema.org/draft/2020-12/schema" ? new
|
|
432
|
-
|
|
490
|
+
}, r = t.$schema, i = r === "https://json-schema.org/draft/2020-12/schema" ? new le(n) : r === "https://json-schema.org/draft/2019-09/schema" ? new ce(n) : new se(n);
|
|
491
|
+
ue(i);
|
|
433
492
|
let a = i.compile(t);
|
|
434
493
|
if ("$async" in a && a.$async === !0) throw Error("asynchronous output schemas are not supported");
|
|
435
494
|
return c(t, { validate: (e) => a(e) ? {
|
|
@@ -439,25 +498,25 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
439
498
|
success: !1,
|
|
440
499
|
error: /* @__PURE__ */ Error("model output does not satisfy the declared JSON Schema")
|
|
441
500
|
} });
|
|
442
|
-
},
|
|
443
|
-
provider:
|
|
444
|
-
model:
|
|
445
|
-
usage:
|
|
446
|
-
inputTokens:
|
|
447
|
-
outputTokens:
|
|
448
|
-
totalTokens:
|
|
449
|
-
completeness:
|
|
501
|
+
}, W = g.Number.pipe(g.int(), g.nonNegative(), g.lessThanOrEqualTo(2 ** 53 - 1)), Qe = g.Struct({
|
|
502
|
+
provider: g.String,
|
|
503
|
+
model: g.String,
|
|
504
|
+
usage: g.Struct({
|
|
505
|
+
inputTokens: g.optional(W),
|
|
506
|
+
outputTokens: g.optional(W),
|
|
507
|
+
totalTokens: g.optional(W),
|
|
508
|
+
completeness: g.Literal("complete", "partial", "unknown")
|
|
450
509
|
}),
|
|
451
|
-
cost:
|
|
452
|
-
status:
|
|
453
|
-
source:
|
|
454
|
-
usd:
|
|
455
|
-
}),
|
|
456
|
-
status:
|
|
457
|
-
source:
|
|
510
|
+
cost: g.Union(g.Struct({
|
|
511
|
+
status: g.Literal("actual"),
|
|
512
|
+
source: g.Literal("gateway"),
|
|
513
|
+
usd: g.Number.pipe(g.finite(), g.nonNegative())
|
|
514
|
+
}), g.Struct({
|
|
515
|
+
status: g.Literal("unknown"),
|
|
516
|
+
source: g.Literal("unreported")
|
|
458
517
|
}))
|
|
459
|
-
}),
|
|
460
|
-
let i = typeof n == "object" && n ? n : {}, a =
|
|
518
|
+
}), G = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 ? e : void 0, K = (e, t, n, r) => {
|
|
519
|
+
let i = typeof n == "object" && n ? n : {}, a = G("inputTokens" in i ? i.inputTokens : void 0), o = G("outputTokens" in i ? i.outputTokens : void 0), s = G("totalTokens" in i ? i.totalTokens : void 0), c = [
|
|
461
520
|
a,
|
|
462
521
|
o,
|
|
463
522
|
s
|
|
@@ -480,26 +539,45 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
480
539
|
usd: l
|
|
481
540
|
}
|
|
482
541
|
};
|
|
483
|
-
},
|
|
484
|
-
reason:
|
|
485
|
-
message:
|
|
486
|
-
evidence:
|
|
487
|
-
}) {},
|
|
488
|
-
let
|
|
542
|
+
}, q = class extends g.TaggedError()("AiError", {
|
|
543
|
+
reason: g.Literal("generation", "decode"),
|
|
544
|
+
message: g.String,
|
|
545
|
+
evidence: g.optional(Qe)
|
|
546
|
+
}) {}, J = (e, t = {}) => {
|
|
547
|
+
let n = String(e?.message ?? e), r = $e(e), i = new q({
|
|
548
|
+
reason: "generation",
|
|
549
|
+
message: `${t.prefix === void 0 ? "" : `${t.prefix}: `}${n}${r.length > 0 ? ` (${r.join(" <- ")})` : ""}`,
|
|
550
|
+
...t.evidence === void 0 ? {} : { evidence: t.evidence }
|
|
551
|
+
});
|
|
552
|
+
return Object.defineProperty(i, "cause", {
|
|
553
|
+
value: e,
|
|
554
|
+
enumerable: !1,
|
|
555
|
+
configurable: !0,
|
|
556
|
+
writable: !0
|
|
557
|
+
}), i;
|
|
558
|
+
}, $e = (e) => {
|
|
559
|
+
let t = [], n = e;
|
|
560
|
+
for (let e = 0; e < 8 && typeof n == "object" && n; e++) {
|
|
561
|
+
let e = n;
|
|
562
|
+
typeof e.code == "string" && e.code.length > 0 && !t.includes(e.code) && t.push(e.code), n = typeof e.lastError == "object" && e.lastError !== null ? e.lastError : e.cause;
|
|
563
|
+
}
|
|
564
|
+
return t;
|
|
565
|
+
}, et = (e, t, n) => {
|
|
566
|
+
let r = [e, ...t ?? []], i = (e) => n(r[e]).pipe(p.catchTag("AiError", (t) => t.reason === "generation" && e + 1 < r.length ? i(e + 1) : p.fail(t)));
|
|
489
567
|
return i(0);
|
|
490
|
-
},
|
|
568
|
+
}, tt = (e) => p.gen(function* () {
|
|
491
569
|
let r = e.messages === void 0 ? e.prompt === void 0 ? void 0 : { prompt: e.prompt } : { messages: [...e.messages] };
|
|
492
|
-
if (r === void 0 || e.prompt !== void 0 && e.messages !== void 0) return yield*
|
|
570
|
+
if (r === void 0 || e.prompt !== void 0 && e.messages !== void 0) return yield* p.fail(new q({
|
|
493
571
|
reason: "generation",
|
|
494
572
|
message: "generateText: supply exactly one of prompt or messages"
|
|
495
573
|
}));
|
|
496
|
-
let i = e.tools === void 0 ? void 0 : yield*
|
|
574
|
+
let i = e.tools === void 0 ? void 0 : yield* p.runtime(), a = e.tools === void 0 || i === void 0 ? void 0 : O(e.tools, {
|
|
497
575
|
store: void 0,
|
|
498
576
|
...e.toolContext,
|
|
499
577
|
...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
|
|
500
578
|
runtime: i
|
|
501
579
|
});
|
|
502
|
-
return yield*
|
|
580
|
+
return yield* et(e.provider ?? n(), e.fallbacks, (n) => U(V(n, "generateText"), (e) => e.usage, p.tryPromise({
|
|
503
581
|
try: async () => {
|
|
504
582
|
let i = t(n), o = await s({
|
|
505
583
|
model: i,
|
|
@@ -525,29 +603,26 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
525
603
|
providerMetadata: o.providerMetadata
|
|
526
604
|
};
|
|
527
605
|
},
|
|
528
|
-
catch: (e) =>
|
|
529
|
-
reason: "generation",
|
|
530
|
-
message: String(e?.message ?? e)
|
|
531
|
-
})
|
|
606
|
+
catch: (e) => J(e)
|
|
532
607
|
})));
|
|
533
|
-
}),
|
|
534
|
-
let n =
|
|
608
|
+
}), nt = (e, t) => p.gen(function* () {
|
|
609
|
+
let n = m.make(e);
|
|
535
610
|
if (n?.type !== "object") {
|
|
536
611
|
let e = n?.anyOf === void 0 ? `type:${JSON.stringify(n?.type ?? null)}` : "anyOf (e.g. Schema.Struct({}) or a union)";
|
|
537
|
-
return yield*
|
|
612
|
+
return yield* p.fail(new q({
|
|
538
613
|
reason: "generation",
|
|
539
614
|
message: `${t}: the output schema must render as a top-level JSON object (type:"object"), but got ${e}. Use a Schema.Struct({ ... }) as the output schema — wrap arrays/scalars in a field (e.g. Schema.Struct({ items: Schema.Array(...) })).`
|
|
540
615
|
}));
|
|
541
616
|
}
|
|
542
617
|
return n;
|
|
543
|
-
}),
|
|
544
|
-
let i = yield*
|
|
545
|
-
try: () =>
|
|
546
|
-
catch: () => new
|
|
618
|
+
}), rt = (e, t) => nt(e, t), it = (e) => et(e.provider ?? n(), e.fallbacks, (n) => U(V(n, "generateObject"), (e) => e.usage, p.gen(function* () {
|
|
619
|
+
let i = yield* p.try({
|
|
620
|
+
try: () => Ze(e.jsonSchema),
|
|
621
|
+
catch: () => new q({
|
|
547
622
|
reason: "decode",
|
|
548
623
|
message: "generateObjectJson: invalid or unsupported output JSON Schema; no provider call was made"
|
|
549
624
|
})
|
|
550
|
-
}), a = t(n), s = yield*
|
|
625
|
+
}), a = t(n), s = yield* p.tryPromise({
|
|
551
626
|
try: () => o({
|
|
552
627
|
model: a,
|
|
553
628
|
schema: i,
|
|
@@ -557,19 +632,18 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
557
632
|
...e.temperature === void 0 ? {} : { temperature: e.temperature },
|
|
558
633
|
...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
|
|
559
634
|
}),
|
|
560
|
-
catch: (e) => r.isInstance(e) ? new
|
|
635
|
+
catch: (e) => r.isInstance(e) ? new q({
|
|
561
636
|
reason: "decode",
|
|
562
637
|
message: "model output failed JSON Schema validation",
|
|
563
|
-
evidence:
|
|
564
|
-
}) :
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
evidence: G(n.name, a.modelId, void 0)
|
|
638
|
+
evidence: K(n.name, a.modelId, e.usage)
|
|
639
|
+
}) : J(e, {
|
|
640
|
+
prefix: "structured provider call failed",
|
|
641
|
+
evidence: K(n.name, a.modelId, void 0)
|
|
568
642
|
})
|
|
569
643
|
});
|
|
570
644
|
return {
|
|
571
645
|
object: s.object,
|
|
572
|
-
evidence:
|
|
646
|
+
evidence: K(n.name, a.modelId, s.usage, s.providerMetadata),
|
|
573
647
|
usage: {
|
|
574
648
|
inputTokens: s.usage.inputTokens,
|
|
575
649
|
outputTokens: s.usage.outputTokens,
|
|
@@ -577,9 +651,9 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
577
651
|
},
|
|
578
652
|
providerMetadata: s.providerMetadata
|
|
579
653
|
};
|
|
580
|
-
}))),
|
|
581
|
-
let t = yield*
|
|
582
|
-
jsonSchema: yield*
|
|
654
|
+
}))), at = (e) => p.gen(function* () {
|
|
655
|
+
let t = yield* it({
|
|
656
|
+
jsonSchema: yield* nt(e.schema, "generateObject"),
|
|
583
657
|
prompt: e.prompt,
|
|
584
658
|
...e.system === void 0 ? {} : { system: e.system },
|
|
585
659
|
...e.provider === void 0 ? {} : { provider: e.provider },
|
|
@@ -587,7 +661,7 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
587
661
|
...e.maxTokens === void 0 ? {} : { maxTokens: e.maxTokens },
|
|
588
662
|
...e.temperature === void 0 ? {} : { temperature: e.temperature },
|
|
589
663
|
...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
|
|
590
|
-
}), n = yield*
|
|
664
|
+
}), n = yield* g.decodeUnknown(e.schema)(t.object).pipe(p.mapError(() => new q({
|
|
591
665
|
reason: "decode",
|
|
592
666
|
message: "model output failed schema decode",
|
|
593
667
|
evidence: t.evidence
|
|
@@ -596,15 +670,15 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
596
670
|
...t,
|
|
597
671
|
object: n
|
|
598
672
|
};
|
|
599
|
-
}),
|
|
600
|
-
let a = yield*
|
|
673
|
+
}), ot = (e) => p.gen(function* () {
|
|
674
|
+
let a = yield* p.runtime(), o = yield* nt(e.schema, "generateObjectWithTools"), u = {
|
|
601
675
|
store: void 0,
|
|
602
676
|
...e.toolContext,
|
|
603
677
|
...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
|
|
604
678
|
runtime: a
|
|
605
679
|
}, d = O(e.tools, u);
|
|
606
|
-
return yield*
|
|
607
|
-
let a = t(n), u = yield*
|
|
680
|
+
return yield* et(e.provider ?? n(), e.fallbacks, (n) => U(V(n, "generateObjectWithTools"), (e) => e.usage, p.gen(function* () {
|
|
681
|
+
let a = t(n), u = yield* p.tryPromise({
|
|
608
682
|
try: () => s({
|
|
609
683
|
model: a,
|
|
610
684
|
prompt: e.prompt,
|
|
@@ -617,42 +691,41 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
617
691
|
...e.temperature === void 0 ? {} : { temperature: e.temperature },
|
|
618
692
|
...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
|
|
619
693
|
}),
|
|
620
|
-
catch: (e) => r.isInstance(e) ? new
|
|
694
|
+
catch: (e) => r.isInstance(e) ? new q({
|
|
621
695
|
reason: "decode",
|
|
622
696
|
message: "model output failed structured decode",
|
|
623
|
-
evidence:
|
|
624
|
-
}) :
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
evidence: G(n.name, a.modelId, void 0)
|
|
697
|
+
evidence: K(n.name, a.modelId, e.usage)
|
|
698
|
+
}) : J(e, {
|
|
699
|
+
prefix: "structured provider call failed",
|
|
700
|
+
evidence: K(n.name, a.modelId, void 0)
|
|
628
701
|
})
|
|
629
|
-
}),
|
|
702
|
+
}), f = u.totalUsage, m = K(n.name, a.modelId, f, u.steps.length === 1 ? u.providerMetadata : void 0), h = yield* p.try({
|
|
630
703
|
try: () => u.output,
|
|
631
|
-
catch: () => new
|
|
704
|
+
catch: () => new q({
|
|
632
705
|
reason: "decode",
|
|
633
706
|
message: "model output failed structured decode",
|
|
634
707
|
evidence: m
|
|
635
708
|
})
|
|
636
709
|
});
|
|
637
710
|
return {
|
|
638
|
-
object: yield*
|
|
711
|
+
object: yield* g.decodeUnknown(e.schema)(h).pipe(p.mapError(() => new q({
|
|
639
712
|
reason: "decode",
|
|
640
713
|
message: "model output failed schema decode",
|
|
641
714
|
evidence: m
|
|
642
715
|
}))),
|
|
643
716
|
evidence: m,
|
|
644
717
|
usage: {
|
|
645
|
-
inputTokens:
|
|
646
|
-
outputTokens:
|
|
647
|
-
totalTokens:
|
|
718
|
+
inputTokens: f.inputTokens,
|
|
719
|
+
outputTokens: f.outputTokens,
|
|
720
|
+
totalTokens: f.totalTokens
|
|
648
721
|
},
|
|
649
722
|
providerMetadata: u.providerMetadata
|
|
650
723
|
};
|
|
651
724
|
})));
|
|
652
|
-
}),
|
|
653
|
-
generateText: (e) =>
|
|
654
|
-
generateObject: (e) =>
|
|
655
|
-
},
|
|
725
|
+
}), st = class extends d.Tag("@voltro/AiService")() {}, ct = {
|
|
726
|
+
generateText: (e) => tt(e),
|
|
727
|
+
generateObject: (e) => at(e)
|
|
728
|
+
}, lt = async (e, t) => {
|
|
656
729
|
if ("bytes" in e) return {
|
|
657
730
|
audio: e.bytes,
|
|
658
731
|
mediaType: e.mediaType
|
|
@@ -672,7 +745,7 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
672
745
|
audio: n,
|
|
673
746
|
mediaType: r
|
|
674
747
|
};
|
|
675
|
-
},
|
|
748
|
+
}, ut = (e) => {
|
|
676
749
|
if (!Array.isArray(e) || e.length === 0) return;
|
|
677
750
|
let t = [];
|
|
678
751
|
for (let n of e) {
|
|
@@ -687,16 +760,16 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
687
760
|
});
|
|
688
761
|
}
|
|
689
762
|
return t.length > 0 ? t : void 0;
|
|
690
|
-
},
|
|
763
|
+
}, dt = (t) => {
|
|
691
764
|
let r = t.provider ?? n();
|
|
692
|
-
return
|
|
765
|
+
return U(V(r, "transcribe"), () => ({}), p.tryPromise({
|
|
693
766
|
try: async () => {
|
|
694
|
-
let { audio: n, mediaType: i } = await
|
|
767
|
+
let { audio: n, mediaType: i } = await lt(t.source, t.resolveRef), o = await a({
|
|
695
768
|
model: e(r),
|
|
696
769
|
audio: n,
|
|
697
770
|
...i === void 0 ? {} : { mediaType: i },
|
|
698
771
|
...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
|
|
699
|
-
}), s = t.timestamps === "none" ? void 0 :
|
|
772
|
+
}), s = t.timestamps === "none" ? void 0 : ut(o.segments);
|
|
700
773
|
return {
|
|
701
774
|
text: o.text,
|
|
702
775
|
...o.language === void 0 ? {} : { language: o.language },
|
|
@@ -705,37 +778,34 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
705
778
|
...o.providerMetadata === void 0 ? {} : { providerMetadata: o.providerMetadata }
|
|
706
779
|
};
|
|
707
780
|
},
|
|
708
|
-
catch: (e) =>
|
|
709
|
-
reason: "generation",
|
|
710
|
-
message: String(e?.message ?? e)
|
|
711
|
-
})
|
|
781
|
+
catch: (e) => J(e)
|
|
712
782
|
}));
|
|
713
|
-
},
|
|
714
|
-
promptId:
|
|
715
|
-
missing:
|
|
716
|
-
message:
|
|
717
|
-
}) {},
|
|
783
|
+
}, ft = (e) => `sha256:${de("sha256").update(e).digest("hex").slice(0, 16)}`, pt = class extends g.TaggedError()("PromptRenderError", {
|
|
784
|
+
promptId: g.String,
|
|
785
|
+
missing: g.Array(g.String),
|
|
786
|
+
message: g.String
|
|
787
|
+
}) {}, mt = /\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, ht = (e) => {
|
|
718
788
|
let t = /* @__PURE__ */ new Set();
|
|
719
|
-
for (let n of e.matchAll(
|
|
789
|
+
for (let n of e.matchAll(mt)) {
|
|
720
790
|
let e = n[1];
|
|
721
791
|
e !== void 0 && t.add(e);
|
|
722
792
|
}
|
|
723
793
|
return [...t];
|
|
724
|
-
},
|
|
725
|
-
let t =
|
|
794
|
+
}, gt = (e, t) => ft(`${e.length}:${e}${(t ?? "").length}:${t ?? ""}`), _t = (e) => {
|
|
795
|
+
let t = gt(e.template, e.system), n = ht(e.template);
|
|
726
796
|
return {
|
|
727
797
|
...e,
|
|
728
798
|
digest: t,
|
|
729
799
|
variables: n,
|
|
730
|
-
render: (r = {}) =>
|
|
800
|
+
render: (r = {}) => p.suspend(() => {
|
|
731
801
|
let i = n.filter((e) => r[e] === void 0);
|
|
732
|
-
if (i.length > 0) return
|
|
802
|
+
if (i.length > 0) return p.fail(new pt({
|
|
733
803
|
promptId: e.id,
|
|
734
804
|
missing: i,
|
|
735
805
|
message: `prompt '${e.id}' needs ${i.map((e) => `{{${e}}}`).join(", ")}, which ${i.length === 1 ? "was" : "were"} not supplied.`
|
|
736
806
|
}));
|
|
737
|
-
let a = e.template.replace(
|
|
738
|
-
return
|
|
807
|
+
let a = e.template.replace(mt, (e, t) => String(r[t]));
|
|
808
|
+
return p.succeed({
|
|
739
809
|
promptId: e.id,
|
|
740
810
|
digest: t,
|
|
741
811
|
...e.label === void 0 ? {} : { label: e.label },
|
|
@@ -745,23 +815,23 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
745
815
|
});
|
|
746
816
|
})
|
|
747
817
|
};
|
|
748
|
-
},
|
|
749
|
-
id:
|
|
818
|
+
}, vt = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", Y = "_voltro_prompts", X = T(Y, {
|
|
819
|
+
id: b({ prefix: "prm" }),
|
|
750
820
|
promptId: E().maxLength(191),
|
|
751
821
|
digest: E().maxLength(191),
|
|
752
|
-
revision:
|
|
822
|
+
revision: x().default(1),
|
|
753
823
|
label: E().nullable(),
|
|
754
824
|
template: E().nullable(),
|
|
755
825
|
system: E().nullable(),
|
|
756
|
-
templateChars:
|
|
826
|
+
templateChars: x().default(0),
|
|
757
827
|
firstSeenAt: D().default("now"),
|
|
758
828
|
lastUsedAt: D().default("now")
|
|
759
|
-
}).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]),
|
|
760
|
-
|
|
829
|
+
}).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), yt = 8760, bt = () => {
|
|
830
|
+
w({
|
|
761
831
|
source: "framework",
|
|
762
832
|
table: Y,
|
|
763
833
|
timeColumn: "lastUsedAt",
|
|
764
|
-
ttlMs:
|
|
834
|
+
ttlMs: oe(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, yt),
|
|
765
835
|
envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
|
|
766
836
|
label: "ai prompt versions"
|
|
767
837
|
});
|
|
@@ -774,20 +844,20 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
774
844
|
system: e.system ?? null,
|
|
775
845
|
firstSeenAt: e.firstSeenAt ?? null,
|
|
776
846
|
lastUsedAt: e.lastUsedAt ?? null
|
|
777
|
-
}),
|
|
778
|
-
|
|
779
|
-
let n = t.digest ??
|
|
780
|
-
return yield*
|
|
781
|
-
let r = (await e.query(
|
|
847
|
+
}), xt = (e, t) => p.gen(function* () {
|
|
848
|
+
bt();
|
|
849
|
+
let n = t.digest ?? _t(t).digest;
|
|
850
|
+
return yield* p.promise(async () => {
|
|
851
|
+
let r = (await e.query(C(X).where(_(v("promptId", t.id), v("digest", n))).descriptor))[0];
|
|
782
852
|
if (r !== void 0) {
|
|
783
853
|
let t = /* @__PURE__ */ new Date();
|
|
784
|
-
return await e.updateMany(Y, { lastUsedAt: t }, { where:
|
|
854
|
+
return await e.updateMany(Y, { lastUsedAt: t }, { where: v("id", String(r.id)) }), Z({
|
|
785
855
|
...r,
|
|
786
856
|
lastUsedAt: t
|
|
787
857
|
});
|
|
788
858
|
}
|
|
789
|
-
let i = (await e.query(
|
|
790
|
-
id:
|
|
859
|
+
let i = (await e.query(C(X).where(v("promptId", t.id)).descriptor)).reduce((e, t) => Math.max(e, Number(t.revision) || 0), 0) + 1, a = /* @__PURE__ */ new Date(), o = {
|
|
860
|
+
id: y({
|
|
791
861
|
kind: "typeid",
|
|
792
862
|
prefix: "prm"
|
|
793
863
|
}, Y),
|
|
@@ -803,11 +873,11 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
803
873
|
};
|
|
804
874
|
return Z(await e.insertIgnore(Y, o, { conflictColumns: ["promptId", "digest"] }) ?? o);
|
|
805
875
|
});
|
|
806
|
-
}),
|
|
807
|
-
let n = (await e.query(
|
|
876
|
+
}), St = (e, t) => p.promise(async () => {
|
|
877
|
+
let n = (await e.query(C(X).where(v("digest", t)).descriptor))[0];
|
|
808
878
|
return n === void 0 ? null : Z(n);
|
|
809
|
-
}),
|
|
810
|
-
id:
|
|
879
|
+
}), Ct = (e, t) => p.promise(async () => [...await e.query(C(X).where(v("promptId", t)).orderBy("revision", "desc").descriptor)].sort((e, t) => (Number(t.revision) || 0) - (Number(e.revision) || 0)).map(Z)), wt = "_voltro_ai_inferences", Tt = T(wt, {
|
|
880
|
+
id: b({ prefix: "aiinf" }),
|
|
811
881
|
tenantId: E().nullable(),
|
|
812
882
|
executionId: E(),
|
|
813
883
|
workflowName: E(),
|
|
@@ -832,26 +902,35 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
832
902
|
system: E().nullable(),
|
|
833
903
|
promptId: E().nullable(),
|
|
834
904
|
promptDigest: E().nullable(),
|
|
835
|
-
promptRevision:
|
|
836
|
-
maxTokens:
|
|
837
|
-
providerOptions:
|
|
838
|
-
jsonSchema:
|
|
839
|
-
transcription:
|
|
840
|
-
media:
|
|
841
|
-
|
|
905
|
+
promptRevision: x().nullable(),
|
|
906
|
+
maxTokens: x().nullable(),
|
|
907
|
+
providerOptions: S().nullable(),
|
|
908
|
+
jsonSchema: S().nullable(),
|
|
909
|
+
transcription: S().nullable(),
|
|
910
|
+
media: S().nullable(),
|
|
911
|
+
taskHandle: S().nullable(),
|
|
912
|
+
taskSubmittedAt: D().nullable(),
|
|
913
|
+
result: S().nullable(),
|
|
842
914
|
errorMessage: E().nullable(),
|
|
843
|
-
attempts:
|
|
844
|
-
fence:
|
|
915
|
+
attempts: x().default(0),
|
|
916
|
+
fence: x().default(0),
|
|
845
917
|
leaseUntil: D().nullable(),
|
|
846
918
|
claimedBy: E().nullable(),
|
|
847
919
|
enqueuedAt: D().default("now"),
|
|
848
920
|
startedAt: D().nullable(),
|
|
849
921
|
completedAt: D().nullable(),
|
|
850
|
-
durationMs:
|
|
851
|
-
}).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]),
|
|
922
|
+
durationMs: x().nullable()
|
|
923
|
+
}).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), Et = 3e5, Dt = 4, Q = (e, t) => {
|
|
852
924
|
let n = typeof e == "number" ? e : Number(e);
|
|
853
925
|
return Number.isFinite(n) ? Math.trunc(n) : t;
|
|
854
|
-
}, $ = (e) => e == null ? null : String(e),
|
|
926
|
+
}, $ = (e) => e == null ? null : String(e), Ot = (e) => {
|
|
927
|
+
if (e instanceof Date) return e;
|
|
928
|
+
if (typeof e == "string" || typeof e == "number") {
|
|
929
|
+
let t = new Date(e);
|
|
930
|
+
return Number.isNaN(t.getTime()) ? null : t;
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}, kt = (e) => ({
|
|
855
934
|
id: String(e.id),
|
|
856
935
|
tenantId: $(e.tenantId),
|
|
857
936
|
executionId: String(e.executionId),
|
|
@@ -872,9 +951,11 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
872
951
|
jsonSchema: e.jsonSchema ?? null,
|
|
873
952
|
transcription: e.transcription ?? null,
|
|
874
953
|
media: e.media ?? null,
|
|
954
|
+
taskHandle: typeof e.taskHandle == "object" ? e.taskHandle : null,
|
|
955
|
+
taskSubmittedAt: Ot(e.taskSubmittedAt),
|
|
875
956
|
attempts: Q(e.attempts, 0),
|
|
876
957
|
fence: Q(e.fence, 0)
|
|
877
|
-
}),
|
|
958
|
+
}), At = (e) => {
|
|
878
959
|
let t = e.attempts + 1;
|
|
879
960
|
return t >= e.maxAttempts ? {
|
|
880
961
|
kind: "give-up",
|
|
@@ -884,6 +965,6 @@ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
|
|
|
884
965
|
attempts: t,
|
|
885
966
|
delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
|
|
886
967
|
};
|
|
887
|
-
},
|
|
968
|
+
}, jt = (e) => `voltro.ai.infer:${e}`, Mt = (e, t) => `aiinf_${de("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
|
|
888
969
|
//#endregion
|
|
889
|
-
export {
|
|
970
|
+
export { M as $, Qe as A, L as B, J as C, ot as D, it as E, Re as F, Ne as G, I as H, Le as I, je as J, Be as K, Ae as L, Xe as M, U as N, tt as O, R as P, Se as Q, Ue as R, st as S, at as T, Me as U, Ie as V, Pe as W, A as X, j as Y, k as Z, Ct as _, At as a, ge as at, dt as b, kt as c, pt as d, ke as et, _t as f, gt as g, St as h, Tt as i, he as it, V as j, rt as k, yt as l, ft as m, Dt as n, O as nt, jt as o, vt as p, He as q, Et as r, me as rt, Mt as s, wt as t, Oe as tt, Y as u, X as v, ct as w, q as x, xt as y, Fe as z };
|