@voltro/ai 0.83.1 → 0.85.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.
@@ -1,45 +1,46 @@
1
1
  import { c as e, o as t, r as n } from "./provider-BnemgE4D.js";
2
2
  import { NoObjectGeneratedError as r, Output as i, experimental_transcribe as a, generateObject as o, generateText as s, jsonSchema as c, stepCountIs as l, tool as u, 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";
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";
10
11
  //#region src/tools.ts
11
- var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
12
+ var de = (e, t) => e(t), fe = Symbol.for("@voltro/ai/Tool"), pe = (e) => ({
12
13
  ...e,
13
- [me]: !0
14
- }), ge = (e) => typeof e == "object" && !!e && e[me] === !0, _e = (e) => {
14
+ [fe]: !0
15
+ }), me = (e) => typeof e == "object" && !!e && e[fe] === !0, he = (e) => {
15
16
  let t = e.default;
16
17
  if (typeof t != "function") return 0;
17
18
  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
+ for (let r of Object.values(e)) me(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
19
20
  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({
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({
24
25
  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);
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);
28
29
  if (e.handler) {
29
30
  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
+ return m.isEffect(i) ? ge(_e(i, e.name, e.timeoutMs), n.runtime, n.abortSignal) : i;
31
32
  }
32
33
  return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
33
- }, xe = (e) => {
34
- let t = h.make(e);
34
+ }, ye = (e) => {
35
+ let t = ee(e);
35
36
  return t && t.type === "object" ? t : {
36
37
  type: "object",
37
38
  properties: {},
38
39
  additionalProperties: !1
39
40
  };
40
- }, Se = (e) => {
41
+ }, be = (e) => {
41
42
  let t = e.inputJsonSchema;
42
- return t === void 0 ? xe(e.input) : t.type === "object" ? t : {
43
+ return t === void 0 ? ye(e.input) : t.type === "object" ? t : {
43
44
  type: "object",
44
45
  properties: {},
45
46
  additionalProperties: !0
@@ -48,7 +49,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
48
49
  let n = {};
49
50
  for (let [r, i] of Object.entries(e)) n[i.name || r] = u({
50
51
  description: i.description,
51
- inputSchema: c(Se(i)),
52
+ inputSchema: c(be(i)),
52
53
  execute: async (e, n) => {
53
54
  let r = t.abortSignal, a = n?.abortSignal, o = r !== void 0 && a !== void 0 && r !== a ? AbortSignal.any([r, a]) : a ?? r;
54
55
  o?.throwIfAborted();
@@ -56,39 +57,45 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
56
57
  ...t,
57
58
  ...n?.toolCallId === void 0 ? {} : { invocationId: n.toolCallId },
58
59
  ...o === void 0 ? {} : { abortSignal: o }
59
- }, c = await m.runPromise(_.decodeUnknown(i.input)(e));
60
+ }, c = await m.runPromise(g.decodeUnknownEffect(i.input)(e));
60
61
  o?.throwIfAborted();
61
- let l = await be(i, c, s);
62
- return i.output ? m.runPromise(_.decodeUnknown(i.output)(l)) : l;
62
+ let l = await ve(i, c, s);
63
+ return i.output ? m.runPromise(g.decodeUnknownEffect(i.output)(l)) : l;
63
64
  }
64
65
  });
65
66
  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
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
77
84
  }) {}, M = "_voltro_ai_budget", N = "_voltro_ai_budget_reservations", P = T(M, {
78
85
  id: x({ prefix: "aib" }),
79
86
  bucket: E().maxLength(191),
80
87
  tenantId: E().nullable(),
81
- reservedMicroUsd: re().default("0").narrowedFrom("integer"),
88
+ reservedMicroUsd: te().default("0").narrowedFrom("integer"),
82
89
  updatedAt: D().default("now")
83
- }).unique("byAiBudgetBucket", ["bucket"]), Ce = T(N, {
90
+ }).unique("byAiBudgetBucket", ["bucket"]), xe = T(N, {
84
91
  id: x({ prefix: "air" }),
85
92
  reservationId: E().maxLength(191),
86
93
  bucket: E().maxLength(191),
87
94
  tenantId: E().nullable(),
88
- amountMicroUsd: re(),
95
+ amountMicroUsd: te(),
89
96
  releasedAt: D().nullable(),
90
97
  updatedAt: D().default("now")
91
- }).unique("byAiBudgetReservation", ["reservationId"]), F = class extends Error {}, we = (e, t, n) => {
98
+ }).unique("byAiBudgetReservation", ["reservationId"]), F = class extends Error {}, Se = (e, t, n) => {
92
99
  if (!Number.isFinite(e) || e < 0) throw new A({
93
100
  field: t,
94
101
  message: `${t} must be finite and non-negative`
@@ -104,34 +111,34 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
104
111
  let t = String(e);
105
112
  if (!/^(0|[1-9][0-9]*)$/.test(t)) throw Error("AI budget counter is invalid; refusing to assume zero");
106
113
  return BigInt(t);
107
- }, Te = (e) => {
114
+ }, Ce = (e) => {
108
115
  if (typeof e != "string" || e.length === 0 || e.length > 191) throw new A({
109
116
  field: "reservationId",
110
117
  message: "AI budget reservationId must contain 1–191 characters"
111
118
  });
112
119
  return e;
113
- }, Ee = () => {
114
- let e = se(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
115
- for (let t of [M, N]) oe({
120
+ }, we = () => {
121
+ let e = ae(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
122
+ for (let t of [M, N]) ie({
116
123
  source: "plugin",
117
124
  table: t,
118
125
  timeColumn: "updatedAt",
119
126
  ttlMs: e
120
127
  });
121
- }, De = async (e, t) => {
128
+ }, Te = async (e, t) => {
122
129
  for (let n = 0;; n++) try {
123
130
  return await e.transactional(t);
124
131
  } catch (e) {
125
132
  if (!(e instanceof F) || n >= 31) throw e;
126
133
  await new Promise((e) => setTimeout(e, n + 1));
127
134
  }
128
- }, Oe = (e) => e instanceof k || e instanceof A || e instanceof j ? m.fail(e) : m.die(e), ke = (e) => m.tryPromise({
135
+ }, Ee = (e) => e instanceof k || e instanceof A || e instanceof j ? m.fail(e) : m.die(e), De = (e) => m.tryPromise({
129
136
  try: e,
130
137
  catch: (e) => e
131
- }).pipe(m.catchAll(Oe)), Ae = (e, t) => m.gen(function* () {
138
+ }).pipe(m.catch(Ee)), Oe = (e, t) => m.gen(function* () {
132
139
  let { limit: n, amount: r, tenantId: i, bucket: a, reservationId: o } = yield* m.try({
133
140
  try: () => {
134
- let e = we(t.limitUsd, "limitUsd", "down"), n = we(t.addUsd ?? 0, "addUsd", "up"), r = t.tenantId ?? null;
141
+ let e = Se(t.limitUsd, "limitUsd", "down"), n = Se(t.addUsd ?? 0, "addUsd", "up"), r = t.tenantId ?? null;
135
142
  if (t.since !== void 0 && (!(t.since instanceof Date) || !Number.isFinite(t.since.getTime()))) throw new A({
136
143
  field: "since",
137
144
  message: "AI budget since must be a valid Date"
@@ -146,15 +153,15 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
146
153
  amount: n,
147
154
  tenantId: r,
148
155
  bucket: i,
149
- reservationId: Te(t.reservationId ?? b({
156
+ reservationId: Ce(t.reservationId ?? b({
150
157
  kind: "typeid",
151
158
  prefix: "air"
152
159
  }, "_voltro_ai_budget_reservations"))
153
160
  };
154
161
  },
155
162
  catch: (e) => e
156
- }).pipe(m.catchAll(Oe));
157
- Ee();
163
+ }).pipe(m.catch(Ee));
164
+ we();
158
165
  let s = async (e) => {
159
166
  let [t] = await e.query(w(P).where(y("bucket", a)).descriptor);
160
167
  if (t && t.tenantId !== i) throw Error("AI budget bucket belongs to a different tenant");
@@ -167,10 +174,10 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
167
174
  attemptedUsd: t.addUsd ?? 0
168
175
  });
169
176
  };
170
- return r === 0n ? yield* ke(async () => {
177
+ return r === 0n ? yield* De(async () => {
171
178
  let t = await s(e);
172
179
  return c(t ? I(t.reservedMicroUsd) : 0n), null;
173
- }) : yield* ke(() => De(e, async (e) => {
180
+ }) : yield* De(() => Te(e, async (e) => {
174
181
  let t = b({
175
182
  kind: "typeid",
176
183
  prefix: "air"
@@ -225,19 +232,19 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
225
232
  status: "reserved"
226
233
  };
227
234
  }));
228
- }), je = (e, t) => m.gen(function* () {
235
+ }), ke = (e, t) => m.gen(function* () {
229
236
  return yield* m.try({
230
- try: () => Te(t.reservationId),
237
+ try: () => Ce(t.reservationId),
231
238
  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);
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);
234
241
  if (!r) return "not-found";
235
242
  if (r.releasedAt !== null) return "already-released";
236
243
  let i = /* @__PURE__ */ new Date();
237
244
  if (await e.updateMany("_voltro_ai_budget_reservations", {
238
245
  releasedAt: i,
239
246
  updatedAt: i
240
- }, { where: v(y("id", r.id), ae("releasedAt")) }) !== 1) {
247
+ }, { where: v(y("id", r.id), re("releasedAt")) }) !== 1) {
241
248
  let [t] = await e.query(n);
242
249
  if (t !== void 0 && t.releasedAt !== null) return "already-released";
243
250
  throw new F("AI budget release raced; retry");
@@ -252,7 +259,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
252
259
  }, { where: v(y("id", a.id), y("reservedMicroUsd", a.reservedMicroUsd)) }) !== 1) throw new F("AI budget counter changed; discard this release and retry");
253
260
  return "released";
254
261
  }));
255
- }), Me = {
262
+ }), Ae = {
256
263
  "claude-opus-4-8": {
257
264
  inputPer1M: 15,
258
265
  outputPer1M: 75
@@ -297,21 +304,21 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
297
304
  inputPer1M: .1,
298
305
  outputPer1M: .4
299
306
  }
300
- }, L = {}, Ne = (e) => {
307
+ }, L = {}, je = (e) => {
301
308
  let t = L;
302
309
  return L = { ...e }, t;
303
- }, Pe = () => ({
304
- ...Me,
310
+ }, Me = () => ({
311
+ ...Ae,
305
312
  ...L
306
- }), Fe = (e) => {
307
- let t = Pe();
313
+ }), Ne = (e) => {
314
+ let t = Me();
308
315
  if (t[e] !== void 0) return t[e];
309
316
  let n = e.indexOf("/");
310
317
  if (n > 0) {
311
318
  let r = e.slice(n + 1);
312
319
  if (t[r] !== void 0) return t[r];
313
320
  }
314
- }, R = (e) => typeof e.unit == "string", Ie = (e) => R(e) ? {
321
+ }, R = (e) => typeof e.unit == "string", Pe = (e) => R(e) ? {
315
322
  unit: e.unit,
316
323
  input: e.input ?? 0,
317
324
  output: e.output ?? 0
@@ -320,7 +327,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
320
327
  input: e.inputTokens ?? 0,
321
328
  output: e.outputTokens ?? 0
322
329
  }, z = (e, t) => {
323
- let { unit: n, input: r, output: i } = Ie(e);
330
+ let { unit: n, input: r, output: i } = Pe(e);
324
331
  if (t.actualCostUsd !== void 0) {
325
332
  if (!Number.isFinite(t.actualCostUsd) || t.actualCostUsd < 0) throw RangeError("estimateCostUsd: actualCostUsd must be a finite, non-negative USD amount.");
326
333
  let e = r + i, a = e > 0 ? r / e : 0;
@@ -343,7 +350,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
343
350
  costSource: "unpriced",
344
351
  unit: n
345
352
  };
346
- let a = t.price ?? Fe(t.model) ?? {
353
+ let a = t.price ?? Ne(t.model) ?? {
347
354
  inputPer1M: 0,
348
355
  outputPer1M: 0
349
356
  }, o = r / 1e6 * a.inputPer1M, s = i / 1e6 * a.outputPer1M;
@@ -356,7 +363,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
356
363
  costSource: "estimated",
357
364
  unit: n
358
365
  };
359
- }, B = "_voltro_ai_usage", Le = T(B, {
366
+ }, B = "_voltro_ai_usage", Fe = T(B, {
360
367
  id: x({ prefix: "aiu" }),
361
368
  tenantId: E().nullable(),
362
369
  provider: E(),
@@ -375,25 +382,26 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
375
382
  attempt: S().nullable(),
376
383
  receiptKey: E().maxLength(191).backfill((e) => `aiu-pre-receipt-${String(e.id)}`),
377
384
  calledAt: D().default("now")
378
- }).index(["tenantId"]).index(["promptDigest"]).unique("byAiUsageReceipt", ["receiptKey"]), Re = (e) => {
385
+ }).index(["tenantId"]).index(["promptDigest"]).unique("byAiUsageReceipt", ["receiptKey"]), Ie = (e) => {
379
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;
380
387
  return Number.isFinite(n) && n >= 0 ? n : void 0;
381
- }, ze = (e) => {
382
- let t = e?.gateway, n = Re(t?.cost);
388
+ }, Le = (e) => {
389
+ let t = e?.gateway, n = Ie(t?.cost);
383
390
  if (n === void 0) return;
384
- if ((Array.isArray(t?.providerAttempts) ? t.providerAttempts : []).findLast((e) => e?.success === !0)?.credentialType !== "byok") return n;
385
- let r = Re(t?.marketCost);
386
- return r === void 0 ? void 0 : n + r;
387
- }, Be = class extends p.TaggedError("AiUsageReceiptConflict") {
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") {
388
396
  get message() {
389
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])}`);
390
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.`;
391
399
  }
392
- }, Ve = class extends p.TaggedError("AiUsageLedgerError") {
400
+ }, ze = class extends p.TaggedError("AiUsageLedgerError") {
393
401
  get message() {
394
402
  return `AI usage receipt ${this.receiptKey} could not be written: ${this.cause instanceof Error ? this.cause.message : String(this.cause)}`;
395
403
  }
396
- }, He = (e) => ({
404
+ }, Be = (e) => ({
397
405
  tenantId: e.tenantId ?? null,
398
406
  provider: String(e.provider),
399
407
  model: String(e.model),
@@ -401,11 +409,11 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
401
409
  inputTokens: Number(e.inputTokens),
402
410
  outputTokens: Number(e.outputTokens),
403
411
  costMicroUsd: Number(e.costMicroUsd)
404
- }), Ue = (e, t) => (oe({
412
+ }), Ve = (e, t) => (ie({
405
413
  source: "plugin",
406
414
  table: B,
407
415
  timeColumn: "calledAt",
408
- ttlMs: se(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
416
+ ttlMs: ae(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
409
417
  }), m.gen(function* () {
410
418
  let n = z(t.usage, {
411
419
  model: t.model,
@@ -434,7 +442,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
434
442
  calledAt: t.calledAt ?? /* @__PURE__ */ new Date()
435
443
  }, a = yield* m.tryPromise({
436
444
  try: () => e.insertIgnoreWithOutcome(B, i, { conflictColumns: ["receiptKey"] }),
437
- catch: (e) => new Ve({
445
+ catch: (e) => new ze({
438
446
  receiptKey: String(r),
439
447
  cause: e
440
448
  })
@@ -443,16 +451,16 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
443
451
  ...n,
444
452
  receipt: "recorded"
445
453
  };
446
- let o = He(a.row), s = He(i);
447
- return Object.keys(o).some((e) => o[e] !== s[e]) ? yield* m.fail(new Be({
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({
448
456
  receiptKey: String(r),
449
457
  recorded: o,
450
458
  attempted: s
451
459
  })) : {
452
- ...We(a.row, n),
460
+ ...He(a.row, n),
453
461
  receipt: "replayed"
454
462
  };
455
- })), We = (e, t) => {
463
+ })), He = (e, t) => {
456
464
  let n = Number(e.costMicroUsd) / 1e6;
457
465
  return {
458
466
  ...t,
@@ -461,7 +469,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
461
469
  totalCostUsd: n,
462
470
  costSource: e.costSource ?? t.costSource
463
471
  };
464
- }, 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({
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({
465
473
  scope: "voltro:ai:usage",
466
474
  provider: t.provider,
467
475
  model: t.model,
@@ -479,63 +487,68 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
479
487
  attempt: t.attempt ?? 0
480
488
  },
481
489
  ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
482
- })))), Ke = (e, t = {}) => m.promise(async () => {
490
+ })))), We = (e, t = {}) => m.promise(async () => {
483
491
  let n = [
484
492
  ...t.tenantId === void 0 ? [] : [y("tenantId", t.tenantId)],
485
- ...t.since === void 0 ? [] : [ie("calledAt", t.since)],
493
+ ...t.since === void 0 ? [] : [ne("calledAt", t.since)],
486
494
  ...t.promptDigest === void 0 ? [] : [y("promptDigest", t.promptDigest)]
487
- ], r = w(Le), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : v(...n));
495
+ ], r = w(Fe), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : v(...n));
488
496
  return (await e.query(i.descriptor)).reduce((e, t) => e + (Number(t.costMicroUsd) || 0), 0) / 1e6;
489
- }), qe = ee.exponential({
490
- start: .001,
491
- factor: 2,
492
- count: 16
493
- }), 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", {
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", {
494
501
  description: "Total prompt (input) tokens across AI calls.",
495
502
  incremental: !0
496
- }), Xe = g.counter("voltro_ai_output_tokens_total", {
503
+ }), Je = h.counter("voltro_ai_output_tokens_total", {
497
504
  description: "Total completion (output) tokens across AI calls.",
498
505
  incremental: !0
499
- }), Ze = g.counter("voltro_ai_cost_microusd_total", {
506
+ }), Ye = h.counter("voltro_ai_cost_microusd_total", {
500
507
  description: "Total estimated AI spend in micro-USD (USD × 1e6).",
501
508
  incremental: !0
502
509
  }), U = (e, t) => ({
503
510
  provider: e.name,
504
511
  model: e.model ?? e.name,
505
512
  operation: t
506
- }), 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) => {
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) => {
507
520
  let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = z({
508
521
  inputTokens: n,
509
522
  outputTokens: r
510
523
  }, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
511
524
  return m.all([
512
- W(g.incrementBy(Ye, n), e, "ok"),
513
- W(g.incrementBy(Xe, r), e, "ok"),
514
- W(g.incrementBy(Ze, a), e, "ok")
525
+ W(h.update(qe, n), e, "ok"),
526
+ W(h.update(Je, r), e, "ok"),
527
+ W(h.update(Ye, a), e, "ok")
515
528
  ], { discard: !0 });
516
529
  }, G = (e, t, n) => m.gen(function* () {
517
530
  let r = yield* m.clockWith((e) => e.currentTimeMillis);
518
- 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: {
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: {
519
532
  "ai.provider": e.provider,
520
533
  "ai.model": e.model,
521
534
  "ai.operation": e.operation
522
535
  } }));
523
- }), $e = (e, t) => {
536
+ }), Ze = (e, t) => {
524
537
  let n = Date.now();
525
- 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: {
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: {
526
539
  "ai.provider": e.provider,
527
540
  "ai.model": e.model,
528
541
  "ai.operation": e.operation
529
542
  } }));
530
- }, et = (e) => {
543
+ }, Qe = (e) => {
531
544
  let t = structuredClone(e), n = {
532
545
  strict: !0,
533
546
  strictTypes: !1,
534
547
  strictTuples: !1,
535
548
  strictRequired: !1,
536
549
  allowUnionTypes: !0
537
- }, 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);
538
- de(i);
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);
539
552
  let a = i.compile(t);
540
553
  if ("$async" in a && a.$async === !0) throw Error("asynchronous output schemas are not supported");
541
554
  return c(t, { validate: (e) => a(e) ? {
@@ -545,29 +558,33 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
545
558
  success: !1,
546
559
  error: /* @__PURE__ */ Error("model output does not satisfy the declared JSON Schema")
547
560
  } });
548
- }, tt = _.Number.pipe(_.int(), _.nonNegative(), _.lessThanOrEqualTo(2 ** 53 - 1)), nt = _.Struct({
549
- provider: _.String,
550
- model: _.String,
551
- usage: _.Struct({
552
- inputTokens: _.optional(tt),
553
- outputTokens: _.optional(tt),
554
- totalTokens: _.optional(tt),
555
- completeness: _.Literal("complete", "partial", "unknown")
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
+ ])
556
573
  }),
557
- cost: _.Union(_.Struct({
558
- status: _.Literal("actual"),
559
- source: _.Literal("gateway"),
560
- usd: _.Number.pipe(_.finite(), _.nonNegative())
561
- }), _.Struct({
562
- status: _.Literal("unknown"),
563
- source: _.Literal("unreported")
564
- }))
565
- }), rt = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 ? e : void 0, K = (e, t, n, r) => {
566
- 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 = [
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 = [
567
584
  a,
568
585
  o,
569
586
  s
570
- ].filter((e) => e !== void 0).length, l = ze(r);
587
+ ].filter((e) => e !== void 0).length, l = Le(r);
571
588
  return {
572
589
  provider: e,
573
590
  model: t,
@@ -586,7 +603,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
586
603
  usd: l
587
604
  }
588
605
  };
589
- }, it = (e, t) => {
606
+ }, nt = (e, t) => {
590
607
  let n = [];
591
608
  return {
592
609
  model: d({
@@ -628,12 +645,12 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
628
645
  }, a === void 0 ? void 0 : { gateway: { cost: a } });
629
646
  }
630
647
  };
631
- }, q = class extends _.TaggedError()("AiError", {
632
- reason: _.Literal("generation", "decode"),
633
- message: _.String,
634
- evidence: _.optional(nt)
648
+ }, q = class extends g.TaggedError()("AiError", {
649
+ reason: g.Literals(["generation", "decode"]),
650
+ message: g.String,
651
+ evidence: g.optional(et)
635
652
  }) {}, J = (e, t = {}) => {
636
- let n = String(e?.message ?? e), r = at(e), i = new q({
653
+ let n = String(e?.message ?? e), r = rt(e), i = new q({
637
654
  reason: "generation",
638
655
  message: `${t.prefix === void 0 ? "" : `${t.prefix}: `}${n}${r.length > 0 ? ` (${r.join(" <- ")})` : ""}`,
639
656
  ...t.evidence === void 0 ? {} : { evidence: t.evidence }
@@ -644,29 +661,29 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
644
661
  configurable: !0,
645
662
  writable: !0
646
663
  }), i;
647
- }, at = (e) => {
664
+ }, rt = (e) => {
648
665
  let t = [], n = e;
649
666
  for (let e = 0; e < 8 && typeof n == "object" && n; e++) {
650
667
  let e = n;
651
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;
652
669
  }
653
670
  return t;
654
- }, ot = (e, t, n) => {
671
+ }, it = (e, t, n) => {
655
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)));
656
673
  return i(0);
657
- }, st = (e) => m.gen(function* () {
674
+ }, at = (e) => m.gen(function* () {
658
675
  let r = e.messages === void 0 ? e.prompt === void 0 ? void 0 : { prompt: e.prompt } : { messages: [...e.messages] };
659
676
  if (r === void 0 || e.prompt !== void 0 && e.messages !== void 0) return yield* m.fail(new q({
660
677
  reason: "generation",
661
678
  message: "generateText: supply exactly one of prompt or messages"
662
679
  }));
663
- let i = e.tools === void 0 ? void 0 : yield* m.runtime(), a = e.tools === void 0 || i === void 0 ? void 0 : O(e.tools, {
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, {
664
681
  store: void 0,
665
682
  ...e.toolContext,
666
683
  ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
667
684
  runtime: i
668
685
  });
669
- return yield* ot(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateText"), (e) => e.usage, m.tryPromise({
686
+ return yield* it(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateText"), (e) => e.usage, m.tryPromise({
670
687
  try: async () => {
671
688
  let i = t(n), o = await s({
672
689
  model: i,
@@ -694,8 +711,8 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
694
711
  },
695
712
  catch: (e) => J(e)
696
713
  })));
697
- }), ct = (e, t) => m.gen(function* () {
698
- let n = h.make(e);
714
+ }), ot = (e, t) => m.gen(function* () {
715
+ let n = ee(e);
699
716
  if (n?.type !== "object") {
700
717
  let e = n?.anyOf === void 0 ? `type:${JSON.stringify(n?.type ?? null)}` : "anyOf (e.g. Schema.Struct({}) or a union)";
701
718
  return yield* m.fail(new q({
@@ -704,14 +721,14 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
704
721
  }));
705
722
  }
706
723
  return n;
707
- }), 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* () {
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* () {
708
725
  let i = yield* m.try({
709
- try: () => et(e.jsonSchema),
726
+ try: () => Qe(e.jsonSchema),
710
727
  catch: () => new q({
711
728
  reason: "decode",
712
729
  message: "generateObjectJson: invalid or unsupported output JSON Schema; no provider call was made"
713
730
  })
714
- }), a = it(n.name, t(n)), s = a.model, c = yield* m.tryPromise({
731
+ }), a = nt(n.name, t(n)), s = a.model, c = yield* m.tryPromise({
715
732
  try: () => o({
716
733
  model: s,
717
734
  schema: i,
@@ -740,9 +757,9 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
740
757
  },
741
758
  providerMetadata: c.providerMetadata
742
759
  };
743
- }))), dt = (e) => m.gen(function* () {
744
- let t = yield* ut({
745
- jsonSchema: yield* ct(e.schema, "generateObject"),
760
+ }))), lt = (e) => m.gen(function* () {
761
+ let t = yield* ct({
762
+ jsonSchema: yield* ot(e.schema, "generateObject"),
746
763
  prompt: e.prompt,
747
764
  ...e.system === void 0 ? {} : { system: e.system },
748
765
  ...e.provider === void 0 ? {} : { provider: e.provider },
@@ -750,7 +767,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
750
767
  ...e.maxTokens === void 0 ? {} : { maxTokens: e.maxTokens },
751
768
  ...e.temperature === void 0 ? {} : { temperature: e.temperature },
752
769
  ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
753
- }), n = yield* _.decodeUnknown(e.schema)(t.object).pipe(m.mapError(() => new q({
770
+ }), n = yield* g.decodeUnknownEffect(e.schema)(t.object).pipe(m.mapError(() => new q({
754
771
  reason: "decode",
755
772
  message: "model output failed schema decode",
756
773
  evidence: t.evidence
@@ -759,15 +776,15 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
759
776
  ...t,
760
777
  object: n
761
778
  };
762
- }), ft = (e) => m.gen(function* () {
763
- let a = yield* m.runtime(), o = yield* ct(e.schema, "generateObjectWithTools"), u = {
779
+ }), ut = (e) => m.gen(function* () {
780
+ let a = yield* m.context(), o = yield* ot(e.schema, "generateObjectWithTools"), u = {
764
781
  store: void 0,
765
782
  ...e.toolContext,
766
783
  ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
767
784
  runtime: a
768
785
  }, d = O(e.tools, u);
769
- return yield* ot(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateObjectWithTools"), (e) => e.usage, m.gen(function* () {
770
- let a = it(n.name, t(n)), u = a.model, f = yield* m.tryPromise({
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({
771
788
  try: () => s({
772
789
  model: u,
773
790
  prompt: e.prompt,
@@ -788,7 +805,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
788
805
  prefix: "structured provider call failed",
789
806
  evidence: K(n.name, u.modelId, void 0)
790
807
  })
791
- }), p = f.totalUsage, h = a.evidence(p), g = yield* m.try({
808
+ }), p = f.totalUsage, h = a.evidence(p), _ = yield* m.try({
792
809
  try: () => f.output,
793
810
  catch: () => new q({
794
811
  reason: "decode",
@@ -797,7 +814,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
797
814
  })
798
815
  });
799
816
  return {
800
- object: yield* _.decodeUnknown(e.schema)(g).pipe(m.mapError(() => new q({
817
+ object: yield* g.decodeUnknownEffect(e.schema)(_).pipe(m.mapError(() => new q({
801
818
  reason: "decode",
802
819
  message: "model output failed schema decode",
803
820
  evidence: h
@@ -811,10 +828,10 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
811
828
  providerMetadata: f.providerMetadata
812
829
  };
813
830
  })));
814
- }), pt = class extends f.Tag("@voltro/AiService")() {}, mt = {
815
- generateText: (e) => st(e),
816
- generateObject: (e) => dt(e)
817
- }, ht = async (e, t) => {
831
+ }), dt = class extends f.Service()("@voltro/AiService") {}, ft = {
832
+ generateText: (e) => at(e),
833
+ generateObject: (e) => lt(e)
834
+ }, pt = async (e, t) => {
818
835
  if ("bytes" in e) return {
819
836
  audio: e.bytes,
820
837
  mediaType: e.mediaType
@@ -834,7 +851,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
834
851
  audio: n,
835
852
  mediaType: r
836
853
  };
837
- }, gt = (e) => {
854
+ }, mt = (e) => {
838
855
  if (!Array.isArray(e) || e.length === 0) return;
839
856
  let t = [];
840
857
  for (let n of e) {
@@ -849,16 +866,16 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
849
866
  });
850
867
  }
851
868
  return t.length > 0 ? t : void 0;
852
- }, _t = (t) => {
869
+ }, ht = (t) => {
853
870
  let r = t.provider ?? n();
854
871
  return G(U(r, "transcribe"), () => ({}), m.tryPromise({
855
872
  try: async () => {
856
- let { audio: n, mediaType: i } = await ht(t.source, t.resolveRef), o = await a({
873
+ let { audio: n, mediaType: i } = await pt(t.source, t.resolveRef), o = await a({
857
874
  model: e(r),
858
875
  audio: n,
859
876
  ...i === void 0 ? {} : { mediaType: i },
860
877
  ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
861
- }), s = t.timestamps === "none" ? void 0 : gt(o.segments);
878
+ }), s = t.timestamps === "none" ? void 0 : mt(o.segments);
862
879
  return {
863
880
  text: o.text,
864
881
  ...o.language === void 0 ? {} : { language: o.language },
@@ -869,31 +886,31 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
869
886
  },
870
887
  catch: (e) => J(e)
871
888
  }));
872
- }, vt = (e) => `sha256:${fe("sha256").update(e).digest("hex").slice(0, 16)}`, yt = class extends _.TaggedError()("PromptRenderError", {
873
- promptId: _.String,
874
- missing: _.Array(_.String),
875
- message: _.String
876
- }) {}, bt = /\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, xt = (e) => {
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) => {
877
894
  let t = /* @__PURE__ */ new Set();
878
- for (let n of e.matchAll(bt)) {
895
+ for (let n of e.matchAll(vt)) {
879
896
  let e = n[1];
880
897
  e !== void 0 && t.add(e);
881
898
  }
882
899
  return [...t];
883
- }, St = (e, t) => vt(`${e.length}:${e}${(t ?? "").length}:${t ?? ""}`), Ct = (e) => {
884
- let t = St(e.template, e.system), n = xt(e.template);
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);
885
902
  return {
886
903
  ...e,
887
904
  digest: t,
888
905
  variables: n,
889
906
  render: (r = {}) => m.suspend(() => {
890
907
  let i = n.filter((e) => r[e] === void 0);
891
- if (i.length > 0) return m.fail(new yt({
908
+ if (i.length > 0) return m.fail(new _t({
892
909
  promptId: e.id,
893
910
  missing: i,
894
911
  message: `prompt '${e.id}' needs ${i.map((e) => `{{${e}}}`).join(", ")}, which ${i.length === 1 ? "was" : "were"} not supplied.`
895
912
  }));
896
- let a = e.template.replace(bt, (e, t) => String(r[t]));
913
+ let a = e.template.replace(vt, (e, t) => String(r[t]));
897
914
  return m.succeed({
898
915
  promptId: e.id,
899
916
  digest: t,
@@ -904,7 +921,7 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
904
921
  });
905
922
  })
906
923
  };
907
- }, wt = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", Y = "_voltro_prompts", X = T(Y, {
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, {
908
925
  id: x({ prefix: "prm" }),
909
926
  promptId: E().maxLength(191),
910
927
  digest: E().maxLength(191),
@@ -915,12 +932,12 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
915
932
  templateChars: S().default(0),
916
933
  firstSeenAt: D().default("now"),
917
934
  lastUsedAt: D().default("now")
918
- }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), Tt = 8760, Et = () => {
919
- oe({
935
+ }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), Ct = 8760, wt = () => {
936
+ ie({
920
937
  source: "framework",
921
938
  table: Y,
922
939
  timeColumn: "lastUsedAt",
923
- ttlMs: se(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, Tt),
940
+ ttlMs: ae(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, Ct),
924
941
  envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
925
942
  label: "ai prompt versions"
926
943
  });
@@ -933,9 +950,9 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
933
950
  system: e.system ?? null,
934
951
  firstSeenAt: e.firstSeenAt ?? null,
935
952
  lastUsedAt: e.lastUsedAt ?? null
936
- }), Dt = (e, t) => m.gen(function* () {
937
- Et();
938
- let n = t.digest ?? Ct(t).digest;
953
+ }), Tt = (e, t) => m.gen(function* () {
954
+ wt();
955
+ let n = t.digest ?? xt(t).digest;
939
956
  return yield* m.promise(async () => {
940
957
  let r = (await e.query(w(X).where(v(y("promptId", t.id), y("digest", n))).descriptor))[0];
941
958
  if (r !== void 0) {
@@ -962,10 +979,10 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
962
979
  };
963
980
  return Z(await e.insertIgnore(Y, o, { conflictColumns: ["promptId", "digest"] }) ?? o);
964
981
  });
965
- }), Ot = (e, t) => m.promise(async () => {
982
+ }), Et = (e, t) => m.promise(async () => {
966
983
  let n = (await e.query(w(X).where(y("digest", t)).descriptor))[0];
967
984
  return n === void 0 ? null : Z(n);
968
- }), 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, {
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, {
969
986
  id: x({ prefix: "aiinf" }),
970
987
  tenantId: E().nullable(),
971
988
  executionId: E(),
@@ -1010,17 +1027,17 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
1010
1027
  startedAt: D().nullable(),
1011
1028
  completedAt: D().nullable(),
1012
1029
  durationMs: S().nullable()
1013
- }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), Mt = 3e5, Nt = 4, Q = (e, t) => {
1030
+ }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), At = 3e5, jt = 4, Q = (e, t) => {
1014
1031
  let n = typeof e == "number" ? e : Number(e);
1015
1032
  return Number.isFinite(n) ? Math.trunc(n) : t;
1016
- }, $ = (e) => e == null ? null : String(e), Pt = (e) => {
1033
+ }, $ = (e) => e == null ? null : String(e), Mt = (e) => {
1017
1034
  if (e instanceof Date) return e;
1018
1035
  if (typeof e == "string" || typeof e == "number") {
1019
1036
  let t = new Date(e);
1020
1037
  return Number.isNaN(t.getTime()) ? null : t;
1021
1038
  }
1022
1039
  return null;
1023
- }, Ft = (e) => ({
1040
+ }, Nt = (e) => ({
1024
1041
  id: String(e.id),
1025
1042
  tenantId: $(e.tenantId),
1026
1043
  executionId: String(e.executionId),
@@ -1042,10 +1059,10 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
1042
1059
  transcription: e.transcription ?? null,
1043
1060
  media: e.media ?? null,
1044
1061
  taskHandle: typeof e.taskHandle == "object" ? e.taskHandle : null,
1045
- taskSubmittedAt: Pt(e.taskSubmittedAt),
1062
+ taskSubmittedAt: Mt(e.taskSubmittedAt),
1046
1063
  attempts: Q(e.attempts, 0),
1047
1064
  fence: Q(e.fence, 0)
1048
- }), It = (e) => {
1065
+ }), Pt = (e) => {
1049
1066
  let t = e.attempts + 1;
1050
1067
  return t >= e.maxAttempts ? {
1051
1068
  kind: "give-up",
@@ -1055,6 +1072,6 @@ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
1055
1072
  attempts: t,
1056
1073
  delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
1057
1074
  };
1058
- }, Lt = (e) => `voltro.ai.infer:${e}`, Rt = (e, t) => `aiinf_${fe("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
1075
+ }, Ft = (e) => `voltro.ai.infer:${e}`, It = (e, t) => `aiinf_${ue("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
1059
1076
  //#endregion
1060
- 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 };
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 };