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