@voltro/ai 0.85.0 → 0.86.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +666 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -33
  3. package/dist/agent.js +64 -2
  4. package/dist/agentConstants.js +4 -0
  5. package/dist/agentExecutor.js +51 -0
  6. package/dist/api.js +199 -0
  7. package/dist/appTools.js +80 -0
  8. package/dist/budget.js +201 -0
  9. package/dist/callEvidence.js +51 -0
  10. package/dist/copilot.js +126 -0
  11. package/dist/cost.js +242 -0
  12. package/dist/embed.js +41 -0
  13. package/dist/embeddingProvider.js +51 -0
  14. package/dist/eval.js +130 -0
  15. package/dist/events.d.ts +4 -0
  16. package/dist/events.js +81 -2
  17. package/dist/executableModalities.js +13 -0
  18. package/dist/gateway.js +58 -0
  19. package/dist/gatewayCatalog.js +47 -0
  20. package/dist/gatewayMedia.js +88 -0
  21. package/dist/index.d.ts +11 -0
  22. package/dist/index.js +42 -2750
  23. package/dist/inferenceDispatch.js +493 -0
  24. package/dist/inferenceQueue.js +96 -0
  25. package/dist/jsonOutputValidation.js +27 -0
  26. package/dist/mcpClient.js +332 -0
  27. package/dist/mcpTools.js +80 -0
  28. package/dist/media.js +182 -0
  29. package/dist/mediaBytes.js +19 -0
  30. package/dist/mediaCall.js +13 -0
  31. package/dist/mediaTaskProvider.js +16 -0
  32. package/dist/middleware.js +32 -0
  33. package/dist/observe.js +52 -0
  34. package/dist/prompts.js +103 -0
  35. package/dist/provider.js +303 -0
  36. package/dist/realtimeEvent.js +97 -0
  37. package/dist/realtimeSession.js +154 -0
  38. package/dist/rerank.js +61 -0
  39. package/dist/resumableStream.js +321 -0
  40. package/dist/retrieveReranked.js +16 -0
  41. package/dist/runAndPersist.js +148 -0
  42. package/dist/semanticCache.js +66 -0
  43. package/dist/speechProvider.js +16 -0
  44. package/dist/streamRegistry.js +14 -0
  45. package/dist/streamText.js +170 -0
  46. package/dist/streamTranscribe.js +74 -0
  47. package/dist/streamWakeups.js +44 -0
  48. package/dist/structuredEvidence.js +48 -0
  49. package/dist/test.js +1 -1
  50. package/dist/threads.js +92 -0
  51. package/dist/tools.js +68 -0
  52. package/dist/transcribe.js +64 -0
  53. package/dist/transcriptionEvent.js +46 -0
  54. package/dist/workflow.d.ts +2 -0
  55. package/dist/workflow.js +115 -110
  56. package/package.json +5 -5
  57. package/dist/agentDescriptor-DhoiXVqO.js +0 -63
  58. package/dist/agentEvent-Bl4egdM5.js +0 -211
  59. package/dist/inferenceQueue-DcEulZep.js +0 -1077
  60. package/dist/provider-BnemgE4D.js +0 -409
@@ -1,1077 +0,0 @@
1
- import { c as e, o as t, r as n } from "./provider-BnemgE4D.js";
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, wrapLanguageModel as d } from "ai";
3
- import { Context as f, Data as p, Effect as m, Metric as h, Schema as g, Stream as _ } from "effect";
4
- import { jsonSchemaOf as ee } from "@voltro/protocol";
5
- import { and as v, bigint as te, eq as y, generateId as b, gte as ne, id as x, integer as S, isNull as re, json as C, queryFor as w, registerRetention as ie, retentionTtlMsFromEnv as ae, table as T, text as E, timestamp as D } from "@voltro/database";
6
- import { Ajv as oe } from "ajv";
7
- import { Ajv2019 as se } from "ajv/dist/2019.js";
8
- import { Ajv2020 as ce } from "ajv/dist/2020.js";
9
- import le from "ajv-formats";
10
- import { createHash as ue } from "node:crypto";
11
- //#region src/tools.ts
12
- var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
13
- ...e,
14
- [fe]: !0
15
- }), me = (e) => typeof e == "object" && !!e && e[fe] === !0, he = (e) => {
16
- let t = e.default;
17
- if (typeof t != "function") return 0;
18
- let n = 0;
19
- for (let r of Object.values(e)) me(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
20
- return n;
21
- }, ge = (e, t, n) => {
22
- let r = t ?? f.empty();
23
- return m.runPromiseWith(r)(e, n === void 0 ? {} : { signal: n });
24
- }, _e = (e, t, n) => n ? e.pipe(m.timeoutOrElse({
25
- duration: `${n} millis`,
26
- orElse: () => m.fail(/* @__PURE__ */ Error(`tool '${t}' timed out`))
27
- })) : e, ve = (e, t, n) => {
28
- if (e.execute) return ge(_e(de(e.execute, t), e.name, e.timeoutMs), n.runtime, n.abortSignal);
29
- if (e.handler) {
30
- let r = e.handler, i = r(t, n);
31
- return m.isEffect(i) ? ge(_e(i, e.name, e.timeoutMs), n.runtime, n.abortSignal) : i;
32
- }
33
- return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
34
- }, ye = (e) => {
35
- let t = ee(e);
36
- return t && t.type === "object" ? t : {
37
- type: "object",
38
- properties: {},
39
- additionalProperties: !1
40
- };
41
- }, be = (e) => {
42
- let t = e.inputJsonSchema;
43
- return t === void 0 ? ye(e.input) : t.type === "object" ? t : {
44
- type: "object",
45
- properties: {},
46
- additionalProperties: !0
47
- };
48
- }, O = (e, t = { store: void 0 }) => {
49
- let n = {};
50
- for (let [r, i] of Object.entries(e)) n[i.name || r] = u({
51
- description: i.description,
52
- inputSchema: c(be(i)),
53
- execute: async (e, n) => {
54
- let r = t.abortSignal, a = n?.abortSignal, o = r !== void 0 && a !== void 0 && r !== a ? AbortSignal.any([r, a]) : a ?? r;
55
- o?.throwIfAborted();
56
- let s = {
57
- ...t,
58
- ...n?.toolCallId === void 0 ? {} : { invocationId: n.toolCallId },
59
- ...o === void 0 ? {} : { abortSignal: o }
60
- }, c = await m.runPromise(g.decodeUnknownEffect(i.input)(e));
61
- o?.throwIfAborted();
62
- let l = await ve(i, c, s);
63
- return i.output ? m.runPromise(g.decodeUnknownEffect(i.output)(l)) : l;
64
- }
65
- });
66
- return n;
67
- }, k = class extends g.TaggedError()("AiBudgetExceeded", {
68
- tenantId: g.NullOr(g.String),
69
- limitUsd: g.Number,
70
- spentUsd: g.Number,
71
- attemptedUsd: g.Number
72
- }) {}, A = class extends g.TaggedError()("AiBudgetInvalidInput", {
73
- field: g.Literals([
74
- "limitUsd",
75
- "addUsd",
76
- "since",
77
- "reservationId",
78
- "tenantId"
79
- ]),
80
- message: g.String
81
- }) {}, j = class extends g.TaggedError()("AiBudgetReservationConflict", {
82
- reason: g.Literals(["identity-bound", "already-released"]),
83
- message: g.String
84
- }) {}, M = "_voltro_ai_budget", N = "_voltro_ai_budget_reservations", P = T(M, {
85
- id: x({ prefix: "aib" }),
86
- bucket: E().maxLength(191),
87
- tenantId: E().nullable(),
88
- reservedMicroUsd: te().default("0").narrowedFrom("integer"),
89
- updatedAt: D().default("now")
90
- }).unique("byAiBudgetBucket", ["bucket"]), xe = T(N, {
91
- id: x({ prefix: "air" }),
92
- reservationId: E().maxLength(191),
93
- bucket: E().maxLength(191),
94
- tenantId: E().nullable(),
95
- amountMicroUsd: te(),
96
- releasedAt: D().nullable(),
97
- updatedAt: D().default("now")
98
- }).unique("byAiBudgetReservation", ["reservationId"]), F = class extends Error {}, Se = (e, t, n) => {
99
- if (!Number.isFinite(e) || e < 0) throw new A({
100
- field: t,
101
- message: `${t} must be finite and non-negative`
102
- });
103
- let r = e * 1e6, i = n === "up" ? Math.ceil(r) : Math.floor(r);
104
- if (!Number.isSafeInteger(i)) throw new A({
105
- field: t,
106
- message: `${t} exceeds the safe micro-USD range`
107
- });
108
- return BigInt(i);
109
- }, I = (e) => {
110
- if (typeof e == "number" && !Number.isSafeInteger(e)) throw Error("AI budget counter is not an exact integer");
111
- let t = String(e);
112
- if (!/^(0|[1-9][0-9]*)$/.test(t)) throw Error("AI budget counter is invalid; refusing to assume zero");
113
- return BigInt(t);
114
- }, Ce = (e) => {
115
- if (typeof e != "string" || e.length === 0 || e.length > 191) throw new A({
116
- field: "reservationId",
117
- message: "AI budget reservationId must contain 1–191 characters"
118
- });
119
- return e;
120
- }, we = () => {
121
- let e = ae(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
122
- for (let t of [M, N]) ie({
123
- source: "plugin",
124
- table: t,
125
- timeColumn: "updatedAt",
126
- ttlMs: e
127
- });
128
- }, Te = async (e, t) => {
129
- for (let n = 0;; n++) try {
130
- return await e.transactional(t);
131
- } catch (e) {
132
- if (!(e instanceof F) || n >= 31) throw e;
133
- await new Promise((e) => setTimeout(e, n + 1));
134
- }
135
- }, Ee = (e) => e instanceof k || e instanceof A || e instanceof j ? m.fail(e) : m.die(e), De = (e) => m.tryPromise({
136
- try: e,
137
- catch: (e) => e
138
- }).pipe(m.catch(Ee)), Oe = (e, t) => m.gen(function* () {
139
- let { limit: n, amount: r, tenantId: i, bucket: a, reservationId: o } = yield* m.try({
140
- try: () => {
141
- let e = Se(t.limitUsd, "limitUsd", "down"), n = Se(t.addUsd ?? 0, "addUsd", "up"), r = t.tenantId ?? null;
142
- if (t.since !== void 0 && (!(t.since instanceof Date) || !Number.isFinite(t.since.getTime()))) throw new A({
143
- field: "since",
144
- message: "AI budget since must be a valid Date"
145
- });
146
- let i = `${r ?? "global"}::${t.since === void 0 ? "all" : t.since.getTime()}`;
147
- if (i.length > 191) throw new A({
148
- field: "tenantId",
149
- message: "AI budget tenant/window key exceeds 191 characters"
150
- });
151
- return {
152
- limit: e,
153
- amount: n,
154
- tenantId: r,
155
- bucket: i,
156
- reservationId: Ce(t.reservationId ?? b({
157
- kind: "typeid",
158
- prefix: "air"
159
- }, "_voltro_ai_budget_reservations"))
160
- };
161
- },
162
- catch: (e) => e
163
- }).pipe(m.catch(Ee));
164
- we();
165
- let s = async (e) => {
166
- let [t] = await e.query(w(P).where(y("bucket", a)).descriptor);
167
- if (t && t.tenantId !== i) throw Error("AI budget bucket belongs to a different tenant");
168
- return t;
169
- }, c = (e) => {
170
- if (r === 0n ? e >= n : e + r > n) throw new k({
171
- tenantId: i,
172
- limitUsd: t.limitUsd,
173
- spentUsd: Number(e) / 1e6,
174
- attemptedUsd: t.addUsd ?? 0
175
- });
176
- };
177
- return r === 0n ? yield* De(async () => {
178
- let t = await s(e);
179
- return c(t ? I(t.reservedMicroUsd) : 0n), null;
180
- }) : yield* De(() => Te(e, async (e) => {
181
- let t = b({
182
- kind: "typeid",
183
- prefix: "air"
184
- }, N), n = /* @__PURE__ */ new Date(), l = await e.insertIgnore(N, {
185
- id: t,
186
- reservationId: o,
187
- bucket: a,
188
- tenantId: i,
189
- amountMicroUsd: String(r),
190
- releasedAt: null,
191
- updatedAt: n
192
- }, { conflictColumns: ["reservationId"] });
193
- if (l.id !== t) {
194
- if (l.tenantId !== i || l.bucket !== a || I(l.amountMicroUsd) !== r) throw new j({
195
- reason: "identity-bound",
196
- message: "AI budget reservationId is already bound to another tenant, amount or window"
197
- });
198
- if (l.releasedAt !== null) throw new j({
199
- reason: "already-released",
200
- message: "AI budget reservation was released; new spend requires a new reservationId"
201
- });
202
- return {
203
- reservationId: o,
204
- tenantId: i,
205
- amountMicroUsd: String(r),
206
- status: "replayed"
207
- };
208
- }
209
- let u = await s(e), d = u ? I(u.reservedMicroUsd) : 0n;
210
- if (c(d), u) {
211
- if (await e.updateMany("_voltro_ai_budget", {
212
- reservedMicroUsd: String(d + r),
213
- updatedAt: n
214
- }, { where: v(y("id", u.id), y("reservedMicroUsd", u.reservedMicroUsd)) }) !== 1) throw new F("AI budget counter changed; discard this receipt and retry");
215
- } else {
216
- let t = b({
217
- kind: "typeid",
218
- prefix: "aib"
219
- }, M);
220
- if ((await e.insertIgnore("_voltro_ai_budget", {
221
- id: t,
222
- bucket: a,
223
- tenantId: i,
224
- reservedMicroUsd: String(r),
225
- updatedAt: n
226
- }, { conflictColumns: ["bucket"] })).id !== t) throw new F("AI budget counter was created concurrently; discard this receipt and retry");
227
- }
228
- return {
229
- reservationId: o,
230
- tenantId: i,
231
- amountMicroUsd: String(r),
232
- status: "reserved"
233
- };
234
- }));
235
- }), ke = (e, t) => m.gen(function* () {
236
- return yield* m.try({
237
- try: () => Ce(t.reservationId),
238
- catch: (e) => e
239
- }).pipe(m.catch((e) => e instanceof A ? m.fail(e) : m.die(e))), yield* m.promise(() => Te(e, async (e) => {
240
- let n = w(xe).where(v(y("reservationId", t.reservationId), t.tenantId === null ? re("tenantId") : y("tenantId", t.tenantId))).descriptor, [r] = await e.query(n);
241
- if (!r) return "not-found";
242
- if (r.releasedAt !== null) return "already-released";
243
- let i = /* @__PURE__ */ new Date();
244
- if (await e.updateMany("_voltro_ai_budget_reservations", {
245
- releasedAt: i,
246
- updatedAt: i
247
- }, { where: v(y("id", r.id), re("releasedAt")) }) !== 1) {
248
- let [t] = await e.query(n);
249
- if (t !== void 0 && t.releasedAt !== null) return "already-released";
250
- throw new F("AI budget release raced; retry");
251
- }
252
- let [a] = await e.query(w(P).where(y("bucket", r.bucket)).descriptor);
253
- if (!a || a.tenantId !== t.tenantId) throw Error("AI budget counter missing or mismatched; refusing unproved credit");
254
- let o = I(a.reservedMicroUsd), s = I(r.amountMicroUsd);
255
- if (s > o) throw Error("AI budget receipt exceeds its counter; refusing unproved credit");
256
- if (await e.updateMany("_voltro_ai_budget", {
257
- reservedMicroUsd: String(o - s),
258
- updatedAt: i
259
- }, { where: v(y("id", a.id), y("reservedMicroUsd", a.reservedMicroUsd)) }) !== 1) throw new F("AI budget counter changed; discard this release and retry");
260
- return "released";
261
- }));
262
- }), Ae = {
263
- "claude-opus-4-8": {
264
- inputPer1M: 15,
265
- outputPer1M: 75
266
- },
267
- "claude-opus-4-6": {
268
- inputPer1M: 15,
269
- outputPer1M: 75
270
- },
271
- "claude-sonnet-4-6": {
272
- inputPer1M: 3,
273
- outputPer1M: 15
274
- },
275
- "claude-haiku-4-5": {
276
- inputPer1M: 1,
277
- outputPer1M: 5
278
- },
279
- "claude-haiku-4-5-20251001": {
280
- inputPer1M: 1,
281
- outputPer1M: 5
282
- },
283
- "gpt-5.5": {
284
- inputPer1M: 5,
285
- outputPer1M: 30
286
- },
287
- "gpt-4o": {
288
- inputPer1M: 2.5,
289
- outputPer1M: 10
290
- },
291
- "gpt-4o-mini": {
292
- inputPer1M: .15,
293
- outputPer1M: .6
294
- },
295
- "gemini-2.5-pro": {
296
- inputPer1M: 1.25,
297
- outputPer1M: 10
298
- },
299
- "gemini-2.5-flash": {
300
- inputPer1M: .3,
301
- outputPer1M: 2.5
302
- },
303
- "gemini-2.0-flash": {
304
- inputPer1M: .1,
305
- outputPer1M: .4
306
- }
307
- }, L = {}, je = (e) => {
308
- let t = L;
309
- return L = { ...e }, t;
310
- }, Me = () => ({
311
- ...Ae,
312
- ...L
313
- }), Ne = (e) => {
314
- let t = Me();
315
- if (t[e] !== void 0) return t[e];
316
- let n = e.indexOf("/");
317
- if (n > 0) {
318
- let r = e.slice(n + 1);
319
- if (t[r] !== void 0) return t[r];
320
- }
321
- }, R = (e) => typeof e.unit == "string", Pe = (e) => R(e) ? {
322
- unit: e.unit,
323
- input: e.input ?? 0,
324
- output: e.output ?? 0
325
- } : {
326
- unit: "tokens",
327
- input: e.inputTokens ?? 0,
328
- output: e.outputTokens ?? 0
329
- }, z = (e, t) => {
330
- let { unit: n, input: r, output: i } = Pe(e);
331
- if (t.actualCostUsd !== void 0) {
332
- if (!Number.isFinite(t.actualCostUsd) || t.actualCostUsd < 0) throw RangeError("estimateCostUsd: actualCostUsd must be a finite, non-negative USD amount.");
333
- let e = r + i, a = e > 0 ? r / e : 0;
334
- return {
335
- inputTokens: r,
336
- outputTokens: i,
337
- inputCostUsd: t.actualCostUsd * a,
338
- outputCostUsd: t.actualCostUsd * (1 - a),
339
- totalCostUsd: t.actualCostUsd,
340
- costSource: "gateway",
341
- unit: n
342
- };
343
- }
344
- if (n !== "tokens" && t.price === void 0) return {
345
- inputTokens: r,
346
- outputTokens: i,
347
- inputCostUsd: 0,
348
- outputCostUsd: 0,
349
- totalCostUsd: 0,
350
- costSource: "unpriced",
351
- unit: n
352
- };
353
- let a = t.price ?? Ne(t.model) ?? {
354
- inputPer1M: 0,
355
- outputPer1M: 0
356
- }, o = r / 1e6 * a.inputPer1M, s = i / 1e6 * a.outputPer1M;
357
- return {
358
- inputTokens: r,
359
- outputTokens: i,
360
- inputCostUsd: o,
361
- outputCostUsd: s,
362
- totalCostUsd: o + s,
363
- costSource: "estimated",
364
- unit: n
365
- };
366
- }, B = "_voltro_ai_usage", Fe = T(B, {
367
- id: x({ prefix: "aiu" }),
368
- tenantId: E().nullable(),
369
- provider: E(),
370
- model: E(),
371
- operation: E(),
372
- agent: E().nullable(),
373
- inputTokens: S().default(0),
374
- outputTokens: S().default(0),
375
- costMicroUsd: S().default(0),
376
- costSource: E().default("estimated"),
377
- unit: E().default("tokens"),
378
- promptId: E().nullable(),
379
- promptDigest: E().nullable(),
380
- promptRevision: S().nullable(),
381
- requestId: E().maxLength(191).nullable(),
382
- attempt: S().nullable(),
383
- receiptKey: E().maxLength(191).backfill((e) => `aiu-pre-receipt-${String(e.id)}`),
384
- calledAt: D().default("now")
385
- }).index(["tenantId"]).index(["promptDigest"]).unique("byAiUsageReceipt", ["receiptKey"]), Ie = (e) => {
386
- let t = typeof e == "string" ? e.trim() : void 0, n = typeof e == "number" ? e : t !== void 0 && /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(t) ? Number(t) : NaN;
387
- return Number.isFinite(n) && n >= 0 ? n : void 0;
388
- }, Le = (e) => {
389
- let t = e?.gateway, n = Ie(t?.cost);
390
- if (n === void 0) return;
391
- let r = (Array.isArray(t?.routing?.modelAttempts) ? t.routing.modelAttempts : []).findLast((e) => e?.success === !0);
392
- if ((Array.isArray(r?.providerAttempts) ? r.providerAttempts : []).findLast((e) => e?.success === !0)?.credentialType !== "byok") return n;
393
- let i = Ie(t?.marketCost);
394
- return i === void 0 ? void 0 : n + i;
395
- }, Re = class extends p.TaggedError("AiUsageReceiptConflict") {
396
- get message() {
397
- 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])}`);
398
- 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.`;
399
- }
400
- }, ze = class extends p.TaggedError("AiUsageLedgerError") {
401
- get message() {
402
- return `AI usage receipt ${this.receiptKey} could not be written: ${this.cause instanceof Error ? this.cause.message : String(this.cause)}`;
403
- }
404
- }, Be = (e) => ({
405
- tenantId: e.tenantId ?? null,
406
- provider: String(e.provider),
407
- model: String(e.model),
408
- operation: String(e.operation),
409
- inputTokens: Number(e.inputTokens),
410
- outputTokens: Number(e.outputTokens),
411
- costMicroUsd: Number(e.costMicroUsd)
412
- }), Ve = (e, t) => (ie({
413
- source: "plugin",
414
- table: B,
415
- timeColumn: "calledAt",
416
- ttlMs: ae(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
417
- }), m.gen(function* () {
418
- let n = z(t.usage, {
419
- model: t.model,
420
- ...t.price === void 0 ? {} : { price: t.price },
421
- ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
422
- }), r = t.receiptKey ?? (t.requestId === void 0 ? b({
423
- kind: "typeid",
424
- prefix: "aiu"
425
- }, "_voltro_ai_usage") : `${t.requestId}#${t.attempt ?? 0}`), i = {
426
- tenantId: t.tenantId ?? null,
427
- provider: t.provider,
428
- model: t.model,
429
- operation: t.operation,
430
- agent: t.agent ?? null,
431
- inputTokens: n.inputTokens,
432
- outputTokens: n.outputTokens,
433
- costMicroUsd: Math.round(n.totalCostUsd * 1e6),
434
- costSource: n.costSource,
435
- unit: n.unit,
436
- promptId: t.prompt?.promptId ?? null,
437
- promptDigest: t.prompt?.digest ?? null,
438
- promptRevision: t.prompt?.revision ?? null,
439
- requestId: t.requestId ?? null,
440
- attempt: t.attempt ?? null,
441
- receiptKey: r,
442
- calledAt: t.calledAt ?? /* @__PURE__ */ new Date()
443
- }, a = yield* m.tryPromise({
444
- try: () => e.insertIgnoreWithOutcome(B, i, { conflictColumns: ["receiptKey"] }),
445
- catch: (e) => new ze({
446
- receiptKey: String(r),
447
- cause: e
448
- })
449
- });
450
- if (a.outcome === "inserted") return {
451
- ...n,
452
- receipt: "recorded"
453
- };
454
- let o = Be(a.row), s = Be(i);
455
- return Object.keys(o).some((e) => o[e] !== s[e]) ? yield* m.fail(new Re({
456
- receiptKey: String(r),
457
- recorded: o,
458
- attempted: s
459
- })) : {
460
- ...He(a.row, n),
461
- receipt: "replayed"
462
- };
463
- })), He = (e, t) => {
464
- let n = Number(e.costMicroUsd) / 1e6;
465
- return {
466
- ...t,
467
- inputTokens: Number(e.inputTokens),
468
- outputTokens: Number(e.outputTokens),
469
- totalCostUsd: n,
470
- costSource: e.costSource ?? t.costSource
471
- };
472
- }, Ue = (e, t) => Ve(e, t).pipe(m.asVoid, m.catchCause((e) => m.logError("AI usage NOT booked as recorded — the call itself succeeded and was returned", e).pipe(m.annotateLogs({
473
- scope: "voltro:ai:usage",
474
- provider: t.provider,
475
- model: t.model,
476
- operation: t.operation,
477
- ...R(t.usage) ? {
478
- unit: t.usage.unit,
479
- input: t.usage.input ?? null,
480
- output: t.usage.output ?? null
481
- } : {
482
- inputTokens: t.usage.inputTokens ?? null,
483
- outputTokens: t.usage.outputTokens ?? null
484
- },
485
- ...t.requestId === void 0 ? {} : {
486
- requestId: t.requestId,
487
- attempt: t.attempt ?? 0
488
- },
489
- ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
490
- })))), We = (e, t = {}) => m.promise(async () => {
491
- let n = [
492
- ...t.tenantId === void 0 ? [] : [y("tenantId", t.tenantId)],
493
- ...t.since === void 0 ? [] : [ne("calledAt", t.since)],
494
- ...t.promptDigest === void 0 ? [] : [y("promptDigest", t.promptDigest)]
495
- ], r = w(Fe), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : v(...n));
496
- return (await e.query(i.descriptor)).reduce((e, t) => e + (Number(t.costMicroUsd) || 0), 0) / 1e6;
497
- }), Ge = Array.from({ length: 16 }, (e, t) => .001 * 2 ** t), V = h.counter("voltro_ai_calls_total", { description: "Total AI provider calls (generate + stream)." }), Ke = h.counter("voltro_ai_call_errors_total", { description: "AI provider calls that errored." }), H = h.histogram("voltro_ai_call_duration_seconds", {
498
- boundaries: Ge,
499
- description: "AI provider call duration in seconds."
500
- }), qe = h.counter("voltro_ai_input_tokens_total", {
501
- description: "Total prompt (input) tokens across AI calls.",
502
- incremental: !0
503
- }), Je = h.counter("voltro_ai_output_tokens_total", {
504
- description: "Total completion (output) tokens across AI calls.",
505
- incremental: !0
506
- }), Ye = h.counter("voltro_ai_cost_microusd_total", {
507
- description: "Total estimated AI spend in micro-USD (USD × 1e6).",
508
- incremental: !0
509
- }), U = (e, t) => ({
510
- provider: e.name,
511
- model: e.model ?? e.name,
512
- operation: t
513
- }), W = (e, t, n) => m.updateService(e, h.CurrentMetricAttributes, (e) => ({
514
- ...e,
515
- provider: t.provider,
516
- model: t.model,
517
- operation: t.operation,
518
- status: n
519
- })), Xe = (e, t) => {
520
- let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = z({
521
- inputTokens: n,
522
- outputTokens: r
523
- }, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
524
- return m.all([
525
- W(h.update(qe, n), e, "ok"),
526
- W(h.update(Je, r), e, "ok"),
527
- W(h.update(Ye, a), e, "ok")
528
- ], { discard: !0 });
529
- }, G = (e, t, n) => m.gen(function* () {
530
- let r = yield* m.clockWith((e) => e.currentTimeMillis);
531
- return yield* n.pipe(m.tap((n) => Xe(e, t(n))), m.tap(() => W(h.update(V, 1), e, "ok").pipe(m.andThen(m.clockWith((e) => e.currentTimeMillis).pipe(m.flatMap((t) => W(h.update(H, (t - r) / 1e3), e, "ok")))))), m.tapError(() => W(h.update(V, 1), e, "error").pipe(m.andThen(W(h.update(Ke, 1), e, "error")), m.andThen(m.clockWith((e) => e.currentTimeMillis).pipe(m.flatMap((t) => W(h.update(H, (t - r) / 1e3), e, "error")))))), m.withSpan("voltro.ai.call", { attributes: {
532
- "ai.provider": e.provider,
533
- "ai.model": e.model,
534
- "ai.operation": e.operation
535
- } }));
536
- }), Ze = (e, t) => {
537
- let n = Date.now();
538
- return t.pipe(_.tap((t) => t._tag === "done" ? W(h.update(V, 1), e, "ok").pipe(m.andThen(W(h.update(H, (Date.now() - n) / 1e3), e, "ok")), m.andThen(Xe(e, t.usage ?? {}))) : t._tag === "error" ? W(h.update(V, 1), e, "error").pipe(m.andThen(W(h.update(Ke, 1), e, "error")), m.andThen(W(h.update(H, (Date.now() - n) / 1e3), e, "error"))) : m.void), _.withSpan("voltro.ai.call", { attributes: {
539
- "ai.provider": e.provider,
540
- "ai.model": e.model,
541
- "ai.operation": e.operation
542
- } }));
543
- }, Qe = (e) => {
544
- let t = structuredClone(e), n = {
545
- strict: !0,
546
- strictTypes: !1,
547
- strictTuples: !1,
548
- strictRequired: !1,
549
- allowUnionTypes: !0
550
- }, r = t.$schema, i = r === "https://json-schema.org/draft/2020-12/schema" ? new ce(n) : r === "https://json-schema.org/draft/2019-09/schema" ? new se(n) : new oe(n);
551
- le(i);
552
- let a = i.compile(t);
553
- if ("$async" in a && a.$async === !0) throw Error("asynchronous output schemas are not supported");
554
- return c(t, { validate: (e) => a(e) ? {
555
- success: !0,
556
- value: e
557
- } : {
558
- success: !1,
559
- error: /* @__PURE__ */ Error("model output does not satisfy the declared JSON Schema")
560
- } });
561
- }, $e = g.Number.pipe(g.check(g.isInt()), g.check(g.isGreaterThanOrEqualTo(0)), g.check(g.isLessThanOrEqualTo(2 ** 53 - 1))), et = g.Struct({
562
- provider: g.String,
563
- model: g.String,
564
- usage: g.Struct({
565
- inputTokens: g.optional($e),
566
- outputTokens: g.optional($e),
567
- totalTokens: g.optional($e),
568
- completeness: g.Literals([
569
- "complete",
570
- "partial",
571
- "unknown"
572
- ])
573
- }),
574
- cost: g.Union([g.Struct({
575
- status: g.Literal("actual"),
576
- source: g.Literal("gateway"),
577
- usd: g.Number.pipe(g.check(g.isFinite()), g.check(g.isGreaterThanOrEqualTo(0)))
578
- }), g.Struct({
579
- status: g.Literal("unknown"),
580
- source: g.Literal("unreported")
581
- })])
582
- }), tt = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 ? e : void 0, K = (e, t, n, r) => {
583
- let i = typeof n == "object" && n ? n : {}, a = tt("inputTokens" in i ? i.inputTokens : void 0), o = tt("outputTokens" in i ? i.outputTokens : void 0), s = tt("totalTokens" in i ? i.totalTokens : void 0), c = [
584
- a,
585
- o,
586
- s
587
- ].filter((e) => e !== void 0).length, l = Le(r);
588
- return {
589
- provider: e,
590
- model: t,
591
- usage: {
592
- ...a === void 0 ? {} : { inputTokens: a },
593
- ...o === void 0 ? {} : { outputTokens: o },
594
- ...s === void 0 ? {} : { totalTokens: s },
595
- completeness: c === 3 ? "complete" : c === 0 ? "unknown" : "partial"
596
- },
597
- cost: l === void 0 ? {
598
- status: "unknown",
599
- source: "unreported"
600
- } : {
601
- status: "actual",
602
- source: "gateway",
603
- usd: l
604
- }
605
- };
606
- }, nt = (e, t) => {
607
- let n = [];
608
- return {
609
- model: d({
610
- model: t,
611
- middleware: {
612
- specificationVersion: "v4",
613
- wrapGenerate: async ({ doGenerate: r }) => {
614
- let i = await r(), a = i.usage.inputTokens.total, o = i.usage.outputTokens.total;
615
- return n.push(K(e, t.modelId, {
616
- inputTokens: a,
617
- outputTokens: o,
618
- totalTokens: a !== void 0 && o !== void 0 ? a + o : void 0
619
- }, i.providerMetadata)), i;
620
- }
621
- }
622
- }),
623
- evidence: (r) => {
624
- if (n.length === 0) return K(e, t.modelId, r);
625
- let i = (e) => {
626
- let t = 0;
627
- for (let r of n) {
628
- let n = r.usage[e];
629
- if (n === void 0) return;
630
- t += n;
631
- }
632
- return t;
633
- }, a = 0;
634
- for (let e of n) {
635
- if (e.cost.status !== "actual") {
636
- a = void 0;
637
- break;
638
- }
639
- a += e.cost.usd;
640
- }
641
- return K(e, t.modelId, {
642
- inputTokens: i("inputTokens"),
643
- outputTokens: i("outputTokens"),
644
- totalTokens: i("totalTokens")
645
- }, a === void 0 ? void 0 : { gateway: { cost: a } });
646
- }
647
- };
648
- }, q = class extends g.TaggedError()("AiError", {
649
- reason: g.Literals(["generation", "decode"]),
650
- message: g.String,
651
- evidence: g.optional(et)
652
- }) {}, J = (e, t = {}) => {
653
- let n = String(e?.message ?? e), r = rt(e), i = new q({
654
- reason: "generation",
655
- message: `${t.prefix === void 0 ? "" : `${t.prefix}: `}${n}${r.length > 0 ? ` (${r.join(" <- ")})` : ""}`,
656
- ...t.evidence === void 0 ? {} : { evidence: t.evidence }
657
- });
658
- return Object.defineProperty(i, "cause", {
659
- value: e,
660
- enumerable: !1,
661
- configurable: !0,
662
- writable: !0
663
- }), i;
664
- }, rt = (e) => {
665
- let t = [], n = e;
666
- for (let e = 0; e < 8 && typeof n == "object" && n; e++) {
667
- let e = n;
668
- 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;
669
- }
670
- return t;
671
- }, it = (e, t, n) => {
672
- let r = [e, ...t ?? []], i = (e) => n(r[e]).pipe(m.catchTag("AiError", (t) => t.reason === "generation" && e + 1 < r.length ? i(e + 1) : m.fail(t)));
673
- return i(0);
674
- }, at = (e) => m.gen(function* () {
675
- let r = e.messages === void 0 ? e.prompt === void 0 ? void 0 : { prompt: e.prompt } : { messages: [...e.messages] };
676
- if (r === void 0 || e.prompt !== void 0 && e.messages !== void 0) return yield* m.fail(new q({
677
- reason: "generation",
678
- message: "generateText: supply exactly one of prompt or messages"
679
- }));
680
- let i = e.tools === void 0 ? void 0 : yield* m.context(), a = e.tools === void 0 || i === void 0 ? void 0 : O(e.tools, {
681
- store: void 0,
682
- ...e.toolContext,
683
- ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
684
- runtime: i
685
- });
686
- return yield* it(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateText"), (e) => e.usage, m.tryPromise({
687
- try: async () => {
688
- let i = t(n), o = await s({
689
- model: i,
690
- ...r,
691
- ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
692
- ...a === void 0 ? {} : {
693
- tools: a,
694
- stopWhen: l(e.maxSteps ?? 8)
695
- },
696
- ...e.system === void 0 ? {} : { system: e.system },
697
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
698
- ...e.temperature === void 0 ? {} : { temperature: e.temperature },
699
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
700
- }), c = a !== void 0 && o.totalUsage !== void 0 ? o.totalUsage : o.usage;
701
- return {
702
- text: o.text,
703
- sources: o.sources,
704
- usage: {
705
- inputTokens: c.inputTokens,
706
- outputTokens: c.outputTokens,
707
- totalTokens: c.totalTokens
708
- },
709
- providerMetadata: o.providerMetadata
710
- };
711
- },
712
- catch: (e) => J(e)
713
- })));
714
- }), ot = (e, t) => m.gen(function* () {
715
- let n = ee(e);
716
- if (n?.type !== "object") {
717
- let e = n?.anyOf === void 0 ? `type:${JSON.stringify(n?.type ?? null)}` : "anyOf (e.g. Schema.Struct({}) or a union)";
718
- return yield* m.fail(new q({
719
- reason: "generation",
720
- 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(...) })).`
721
- }));
722
- }
723
- return n;
724
- }), st = (e, t) => ot(e, t), ct = (e) => it(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateObject"), (e) => e.usage, m.gen(function* () {
725
- let i = yield* m.try({
726
- try: () => Qe(e.jsonSchema),
727
- catch: () => new q({
728
- reason: "decode",
729
- message: "generateObjectJson: invalid or unsupported output JSON Schema; no provider call was made"
730
- })
731
- }), a = nt(n.name, t(n)), s = a.model, c = yield* m.tryPromise({
732
- try: () => o({
733
- model: s,
734
- schema: i,
735
- prompt: e.prompt,
736
- ...e.system === void 0 ? {} : { system: e.system },
737
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
738
- ...e.temperature === void 0 ? {} : { temperature: e.temperature },
739
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
740
- }),
741
- catch: (e) => r.isInstance(e) ? new q({
742
- reason: "decode",
743
- message: "model output failed JSON Schema validation",
744
- evidence: a.evidence(e.usage)
745
- }) : J(e, {
746
- prefix: "structured provider call failed",
747
- evidence: K(n.name, s.modelId, void 0)
748
- })
749
- });
750
- return {
751
- object: c.object,
752
- evidence: K(n.name, s.modelId, c.usage, c.providerMetadata),
753
- usage: {
754
- inputTokens: c.usage.inputTokens,
755
- outputTokens: c.usage.outputTokens,
756
- totalTokens: c.usage.totalTokens
757
- },
758
- providerMetadata: c.providerMetadata
759
- };
760
- }))), lt = (e) => m.gen(function* () {
761
- let t = yield* ct({
762
- jsonSchema: yield* ot(e.schema, "generateObject"),
763
- prompt: e.prompt,
764
- ...e.system === void 0 ? {} : { system: e.system },
765
- ...e.provider === void 0 ? {} : { provider: e.provider },
766
- ...e.fallbacks === void 0 ? {} : { fallbacks: e.fallbacks },
767
- ...e.maxTokens === void 0 ? {} : { maxTokens: e.maxTokens },
768
- ...e.temperature === void 0 ? {} : { temperature: e.temperature },
769
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
770
- }), n = yield* g.decodeUnknownEffect(e.schema)(t.object).pipe(m.mapError(() => new q({
771
- reason: "decode",
772
- message: "model output failed schema decode",
773
- evidence: t.evidence
774
- })));
775
- return {
776
- ...t,
777
- object: n
778
- };
779
- }), ut = (e) => m.gen(function* () {
780
- let a = yield* m.context(), o = yield* ot(e.schema, "generateObjectWithTools"), u = {
781
- store: void 0,
782
- ...e.toolContext,
783
- ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
784
- runtime: a
785
- }, d = O(e.tools, u);
786
- return yield* it(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateObjectWithTools"), (e) => e.usage, m.gen(function* () {
787
- let a = nt(n.name, t(n)), u = a.model, f = yield* m.tryPromise({
788
- try: () => s({
789
- model: u,
790
- prompt: e.prompt,
791
- tools: d,
792
- ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
793
- stopWhen: l(e.maxSteps ?? 8),
794
- output: i.object({ schema: c(o) }),
795
- ...e.system === void 0 ? {} : { system: e.system },
796
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
797
- ...e.temperature === void 0 ? {} : { temperature: e.temperature },
798
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
799
- }),
800
- catch: (e) => r.isInstance(e) ? new q({
801
- reason: "decode",
802
- message: "model output failed structured decode",
803
- evidence: a.evidence(e.usage)
804
- }) : J(e, {
805
- prefix: "structured provider call failed",
806
- evidence: K(n.name, u.modelId, void 0)
807
- })
808
- }), p = f.totalUsage, h = a.evidence(p), _ = yield* m.try({
809
- try: () => f.output,
810
- catch: () => new q({
811
- reason: "decode",
812
- message: "model output failed structured decode",
813
- evidence: h
814
- })
815
- });
816
- return {
817
- object: yield* g.decodeUnknownEffect(e.schema)(_).pipe(m.mapError(() => new q({
818
- reason: "decode",
819
- message: "model output failed schema decode",
820
- evidence: h
821
- }))),
822
- evidence: h,
823
- usage: {
824
- inputTokens: p.inputTokens,
825
- outputTokens: p.outputTokens,
826
- totalTokens: p.totalTokens
827
- },
828
- providerMetadata: f.providerMetadata
829
- };
830
- })));
831
- }), dt = class extends f.Service()("@voltro/AiService") {}, ft = {
832
- generateText: (e) => at(e),
833
- generateObject: (e) => lt(e)
834
- }, pt = async (e, t) => {
835
- if ("bytes" in e) return {
836
- audio: e.bytes,
837
- mediaType: e.mediaType
838
- };
839
- if ("url" in e) {
840
- let t = await fetch(e.url);
841
- if (!t.ok) throw Error(`transcribe: GET ${e.url} answered ${t.status}.`);
842
- let n = t.headers.get("content-type") ?? void 0;
843
- return {
844
- audio: new Uint8Array(await t.arrayBuffer()),
845
- ...n === void 0 ? {} : { mediaType: n }
846
- };
847
- }
848
- if (t === void 0) throw Error("transcribe: `source.storageRef` needs a `resolveRef` to turn the reference into bytes.\n → pass `resolveRef: (ref) => storage.read(ref)`. It is injected rather than imported so @voltro/ai does not depend on storage; the app owns tenancy and signing for that read.");
849
- let { bytes: n, mediaType: r } = await t(e.storageRef);
850
- return {
851
- audio: n,
852
- mediaType: r
853
- };
854
- }, mt = (e) => {
855
- if (!Array.isArray(e) || e.length === 0) return;
856
- let t = [];
857
- for (let n of e) {
858
- let e = typeof n.startSecond == "number" ? n.startSecond : typeof n.start == "number" ? n.start : void 0, r = typeof n.endSecond == "number" ? n.endSecond : typeof n.end == "number" ? n.end : void 0, i = typeof n.text == "string" ? n.text : void 0;
859
- if (e === void 0 || r === void 0 || i === void 0) continue;
860
- let a = typeof n.speaker == "string" ? n.speaker : void 0;
861
- t.push({
862
- start: e,
863
- end: r,
864
- text: i,
865
- ...a === void 0 ? {} : { speaker: a }
866
- });
867
- }
868
- return t.length > 0 ? t : void 0;
869
- }, ht = (t) => {
870
- let r = t.provider ?? n();
871
- return G(U(r, "transcribe"), () => ({}), m.tryPromise({
872
- try: async () => {
873
- let { audio: n, mediaType: i } = await pt(t.source, t.resolveRef), o = await a({
874
- model: e(r),
875
- audio: n,
876
- ...i === void 0 ? {} : { mediaType: i },
877
- ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
878
- }), s = t.timestamps === "none" ? void 0 : mt(o.segments);
879
- return {
880
- text: o.text,
881
- ...o.language === void 0 ? {} : { language: o.language },
882
- ...o.durationInSeconds === void 0 ? {} : { durationSec: o.durationInSeconds },
883
- ...s === void 0 ? {} : { segments: s },
884
- ...o.providerMetadata === void 0 ? {} : { providerMetadata: o.providerMetadata }
885
- };
886
- },
887
- catch: (e) => J(e)
888
- }));
889
- }, gt = (e) => `sha256:${ue("sha256").update(e).digest("hex").slice(0, 16)}`, _t = class extends g.TaggedError()("PromptRenderError", {
890
- promptId: g.String,
891
- missing: g.Array(g.String),
892
- message: g.String
893
- }) {}, vt = /\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, yt = (e) => {
894
- let t = /* @__PURE__ */ new Set();
895
- for (let n of e.matchAll(vt)) {
896
- let e = n[1];
897
- e !== void 0 && t.add(e);
898
- }
899
- return [...t];
900
- }, bt = (e, t) => gt(`${e.length}:${e}${(t ?? "").length}:${t ?? ""}`), xt = (e) => {
901
- let t = bt(e.template, e.system), n = yt(e.template);
902
- return {
903
- ...e,
904
- digest: t,
905
- variables: n,
906
- render: (r = {}) => m.suspend(() => {
907
- let i = n.filter((e) => r[e] === void 0);
908
- if (i.length > 0) return m.fail(new _t({
909
- promptId: e.id,
910
- missing: i,
911
- message: `prompt '${e.id}' needs ${i.map((e) => `{{${e}}}`).join(", ")}, which ${i.length === 1 ? "was" : "were"} not supplied.`
912
- }));
913
- let a = e.template.replace(vt, (e, t) => String(r[t]));
914
- return m.succeed({
915
- promptId: e.id,
916
- digest: t,
917
- ...e.label === void 0 ? {} : { label: e.label },
918
- prompt: a,
919
- ...e.system === void 0 ? {} : { system: e.system },
920
- definition: e
921
- });
922
- })
923
- };
924
- }, St = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", Y = "_voltro_prompts", X = T(Y, {
925
- id: x({ prefix: "prm" }),
926
- promptId: E().maxLength(191),
927
- digest: E().maxLength(191),
928
- revision: S().default(1),
929
- label: E().nullable(),
930
- template: E().nullable(),
931
- system: E().nullable(),
932
- templateChars: S().default(0),
933
- firstSeenAt: D().default("now"),
934
- lastUsedAt: D().default("now")
935
- }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), Ct = 8760, wt = () => {
936
- ie({
937
- source: "framework",
938
- table: Y,
939
- timeColumn: "lastUsedAt",
940
- ttlMs: ae(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, Ct),
941
- envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
942
- label: "ai prompt versions"
943
- });
944
- }, Z = (e) => ({
945
- promptId: String(e.promptId),
946
- digest: String(e.digest),
947
- revision: Number(e.revision) || 1,
948
- label: e.label ?? null,
949
- template: e.template ?? null,
950
- system: e.system ?? null,
951
- firstSeenAt: e.firstSeenAt ?? null,
952
- lastUsedAt: e.lastUsedAt ?? null
953
- }), Tt = (e, t) => m.gen(function* () {
954
- wt();
955
- let n = t.digest ?? xt(t).digest;
956
- return yield* m.promise(async () => {
957
- let r = (await e.query(w(X).where(v(y("promptId", t.id), y("digest", n))).descriptor))[0];
958
- if (r !== void 0) {
959
- let t = /* @__PURE__ */ new Date();
960
- return await e.updateMany(Y, { lastUsedAt: t }, { where: y("id", String(r.id)) }), Z({
961
- ...r,
962
- lastUsedAt: t
963
- });
964
- }
965
- let i = (await e.query(w(X).where(y("promptId", t.id)).descriptor)).reduce((e, t) => Math.max(e, Number(t.revision) || 0), 0) + 1, a = /* @__PURE__ */ new Date(), o = {
966
- id: b({
967
- kind: "typeid",
968
- prefix: "prm"
969
- }, Y),
970
- promptId: t.id,
971
- digest: n,
972
- revision: i,
973
- label: t.label ?? null,
974
- template: t.template,
975
- system: t.system ?? null,
976
- templateChars: t.template.length,
977
- firstSeenAt: a,
978
- lastUsedAt: a
979
- };
980
- return Z(await e.insertIgnore(Y, o, { conflictColumns: ["promptId", "digest"] }) ?? o);
981
- });
982
- }), Et = (e, t) => m.promise(async () => {
983
- let n = (await e.query(w(X).where(y("digest", t)).descriptor))[0];
984
- return n === void 0 ? null : Z(n);
985
- }), Dt = (e, t) => m.promise(async () => [...await e.query(w(X).where(y("promptId", t)).orderBy("revision", "desc").descriptor)].sort((e, t) => (Number(t.revision) || 0) - (Number(e.revision) || 0)).map(Z)), Ot = "_voltro_ai_inferences", kt = T(Ot, {
986
- id: x({ prefix: "aiinf" }),
987
- tenantId: E().nullable(),
988
- executionId: E(),
989
- workflowName: E(),
990
- runId: E().nullable(),
991
- signalName: E(),
992
- stepName: E(),
993
- status: E().oneOf([
994
- "pending",
995
- "running",
996
- "succeeded",
997
- "failed"
998
- ]).default("pending"),
999
- kind: E().oneOf([
1000
- "text",
1001
- "object",
1002
- "transcription",
1003
- "media"
1004
- ]).default("text"),
1005
- provider: E(),
1006
- model: E(),
1007
- prompt: E(),
1008
- system: E().nullable(),
1009
- promptId: E().nullable(),
1010
- promptDigest: E().nullable(),
1011
- promptRevision: S().nullable(),
1012
- maxTokens: S().nullable(),
1013
- providerOptions: C().nullable(),
1014
- jsonSchema: C().nullable(),
1015
- transcription: C().nullable(),
1016
- media: C().nullable(),
1017
- taskHandle: C().nullable(),
1018
- taskSubmittedAt: D().nullable(),
1019
- result: C().nullable(),
1020
- errorMessage: E().nullable(),
1021
- attempts: S().default(0),
1022
- fence: S().default(0),
1023
- leaseUntil: D().nullable(),
1024
- claimedBy: E().nullable(),
1025
- queuedAt: D().nullable(),
1026
- enqueuedAt: D().default("now"),
1027
- startedAt: D().nullable(),
1028
- completedAt: D().nullable(),
1029
- durationMs: S().nullable()
1030
- }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), At = 3e5, jt = 4, Q = (e, t) => {
1031
- let n = typeof e == "number" ? e : Number(e);
1032
- return Number.isFinite(n) ? Math.trunc(n) : t;
1033
- }, $ = (e) => e == null ? null : String(e), Mt = (e) => {
1034
- if (e instanceof Date) return e;
1035
- if (typeof e == "string" || typeof e == "number") {
1036
- let t = new Date(e);
1037
- return Number.isNaN(t.getTime()) ? null : t;
1038
- }
1039
- return null;
1040
- }, Nt = (e) => ({
1041
- id: String(e.id),
1042
- tenantId: $(e.tenantId),
1043
- executionId: String(e.executionId),
1044
- workflowName: String(e.workflowName),
1045
- runId: $(e.runId),
1046
- signalName: String(e.signalName),
1047
- stepName: String(e.stepName),
1048
- kind: e.kind === "object" ? "object" : e.kind === "transcription" ? "transcription" : e.kind === "media" ? "media" : "text",
1049
- provider: String(e.provider),
1050
- model: String(e.model),
1051
- prompt: String(e.prompt ?? ""),
1052
- system: $(e.system),
1053
- promptId: $(e.promptId),
1054
- promptDigest: $(e.promptDigest),
1055
- promptRevision: e.promptRevision === null || e.promptRevision === void 0 ? null : Q(e.promptRevision, 0),
1056
- maxTokens: e.maxTokens === null || e.maxTokens === void 0 ? null : Q(e.maxTokens, 0),
1057
- providerOptions: e.providerOptions ?? null,
1058
- jsonSchema: e.jsonSchema ?? null,
1059
- transcription: e.transcription ?? null,
1060
- media: e.media ?? null,
1061
- taskHandle: typeof e.taskHandle == "object" ? e.taskHandle : null,
1062
- taskSubmittedAt: Mt(e.taskSubmittedAt),
1063
- attempts: Q(e.attempts, 0),
1064
- fence: Q(e.fence, 0)
1065
- }), Pt = (e) => {
1066
- let t = e.attempts + 1;
1067
- return t >= e.maxAttempts ? {
1068
- kind: "give-up",
1069
- attempts: t
1070
- } : {
1071
- kind: "retry",
1072
- attempts: t,
1073
- delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
1074
- };
1075
- }, Ft = (e) => `voltro.ai.infer:${e}`, It = (e, t) => `aiinf_${ue("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
1076
- //#endregion
1077
- export { j as $, et as A, z as B, J as C, ut as D, ct as E, ze as F, Ne as G, R as H, Re as I, je as J, Ve as K, Ae as L, Ze as M, G as N, at as O, B as P, A as Q, We as R, dt as S, lt as T, Me as U, Le as V, Pe as W, M as X, N as Y, k as Z, Dt as _, Pt as a, pe as at, ht as b, Nt as c, _t as d, xe as et, xt as f, bt as g, Et as h, kt as i, O as it, U as j, st as k, Ct as l, gt as m, jt as n, ke as nt, Ft as o, me as ot, St as p, Ue as q, At as r, Oe as rt, It as s, he as st, Ot as t, P as tt, Y as u, X as v, ft as w, q as x, Tt as y, Fe as z };