@voltro/ai 0.80.0 → 0.82.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,54 +1,54 @@
1
1
  import { c as e, o as t, r as n } from "./provider-BsyDya-H.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
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 T, retentionTtlMsFromEnv as oe, table as E, text as D, timestamp as O } from "@voltro/database";
5
- import { Ajv as se } from "ajv";
6
- import { Ajv2019 as ce } from "ajv/dist/2019.js";
7
- import { Ajv2020 as le } from "ajv/dist/2020.js";
8
- import ue from "ajv-formats";
9
- import { createHash as de } from "node:crypto";
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
10
  //#region src/tools.ts
11
- var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
11
+ var pe = (e, t) => e(t), me = Symbol.for("@voltro/ai/Tool"), he = (e) => ({
12
12
  ...e,
13
- [pe]: !0
14
- }), he = (e) => typeof e == "object" && !!e && e[pe] === !0, ge = (e) => {
13
+ [me]: !0
14
+ }), ge = (e) => typeof e == "object" && !!e && e[me] === !0, _e = (e) => {
15
15
  let t = e.default;
16
16
  if (typeof t != "function") return 0;
17
17
  let n = 0;
18
- for (let r of Object.values(e)) he(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
18
+ for (let r of Object.values(e)) ge(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
19
19
  return n;
20
- }, _e = (e, t, n) => {
20
+ }, ve = (e, t, n) => {
21
21
  let r = t ?? te.defaultRuntime;
22
22
  return te.runPromise(r)(e, n === void 0 ? {} : { signal: n });
23
- }, ve = (e, t, n) => n ? e.pipe(m.timeoutFail({
23
+ }, ye = (e, t, n) => n ? e.pipe(m.timeoutFail({
24
24
  duration: `${n} millis`,
25
25
  onTimeout: () => /* @__PURE__ */ Error(`tool '${t}' timed out`)
26
- })) : e, ye = (e, t, n) => {
27
- if (e.execute) return _e(ve(fe(e.execute, t), e.name, e.timeoutMs), n.runtime, n.abortSignal);
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
28
  if (e.handler) {
29
29
  let r = e.handler, i = r(t, n);
30
- return m.isEffect(i) ? _e(ve(i, e.name, e.timeoutMs), n.runtime, n.abortSignal) : i;
30
+ return m.isEffect(i) ? ve(ye(i, e.name, e.timeoutMs), n.runtime, n.abortSignal) : i;
31
31
  }
32
32
  return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
33
- }, be = (e) => {
33
+ }, xe = (e) => {
34
34
  let t = h.make(e);
35
35
  return t && t.type === "object" ? t : {
36
36
  type: "object",
37
37
  properties: {},
38
38
  additionalProperties: !1
39
39
  };
40
- }, xe = (e) => {
40
+ }, Se = (e) => {
41
41
  let t = e.inputJsonSchema;
42
- return t === void 0 ? be(e.input) : t.type === "object" ? t : {
42
+ return t === void 0 ? xe(e.input) : t.type === "object" ? t : {
43
43
  type: "object",
44
44
  properties: {},
45
45
  additionalProperties: !0
46
46
  };
47
- }, k = (e, t = { store: void 0 }) => {
47
+ }, O = (e, t = { store: void 0 }) => {
48
48
  let n = {};
49
49
  for (let [r, i] of Object.entries(e)) n[i.name || r] = u({
50
50
  description: i.description,
51
- inputSchema: c(xe(i)),
51
+ inputSchema: c(Se(i)),
52
52
  execute: async (e, n) => {
53
53
  let r = t.abortSignal, a = n?.abortSignal, o = r !== void 0 && a !== void 0 && r !== a ? AbortSignal.any([r, a]) : a ?? r;
54
54
  o?.throwIfAborted();
@@ -58,86 +58,86 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
58
58
  ...o === void 0 ? {} : { abortSignal: o }
59
59
  }, c = await m.runPromise(_.decodeUnknown(i.input)(e));
60
60
  o?.throwIfAborted();
61
- let l = await ye(i, c, s);
61
+ let l = await be(i, c, s);
62
62
  return i.output ? m.runPromise(_.decodeUnknown(i.output)(l)) : l;
63
63
  }
64
64
  });
65
65
  return n;
66
- }, A = class extends _.TaggedError()("AiBudgetExceeded", {
66
+ }, k = class extends _.TaggedError()("AiBudgetExceeded", {
67
67
  tenantId: _.NullOr(_.String),
68
68
  limitUsd: _.Number,
69
69
  spentUsd: _.Number,
70
70
  attemptedUsd: _.Number
71
- }) {}, j = class extends _.TaggedError()("AiBudgetInvalidInput", {
71
+ }) {}, A = class extends _.TaggedError()("AiBudgetInvalidInput", {
72
72
  field: _.Literal("limitUsd", "addUsd", "since", "reservationId", "tenantId"),
73
73
  message: _.String
74
- }) {}, M = class extends _.TaggedError()("AiBudgetReservationConflict", {
74
+ }) {}, j = class extends _.TaggedError()("AiBudgetReservationConflict", {
75
75
  reason: _.Literal("identity-bound", "already-released"),
76
76
  message: _.String
77
- }) {}, N = "_voltro_ai_budget", P = "_voltro_ai_budget_reservations", F = E(N, {
77
+ }) {}, M = "_voltro_ai_budget", N = "_voltro_ai_budget_reservations", P = T(M, {
78
78
  id: x({ prefix: "aib" }),
79
- bucket: D().maxLength(191),
80
- tenantId: D().nullable(),
79
+ bucket: E().maxLength(191),
80
+ tenantId: E().nullable(),
81
81
  reservedMicroUsd: re().default("0").narrowedFrom("integer"),
82
- updatedAt: O().default("now")
83
- }).unique("byAiBudgetBucket", ["bucket"]), Se = E(P, {
82
+ updatedAt: D().default("now")
83
+ }).unique("byAiBudgetBucket", ["bucket"]), Ce = T(N, {
84
84
  id: x({ prefix: "air" }),
85
- reservationId: D().maxLength(191),
86
- bucket: D().maxLength(191),
87
- tenantId: D().nullable(),
85
+ reservationId: E().maxLength(191),
86
+ bucket: E().maxLength(191),
87
+ tenantId: E().nullable(),
88
88
  amountMicroUsd: re(),
89
- releasedAt: O().nullable(),
90
- updatedAt: O().default("now")
91
- }).unique("byAiBudgetReservation", ["reservationId"]), I = class extends Error {}, Ce = (e, t, n) => {
92
- if (!Number.isFinite(e) || e < 0) throw new j({
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
93
  field: t,
94
94
  message: `${t} must be finite and non-negative`
95
95
  });
96
96
  let r = e * 1e6, i = n === "up" ? Math.ceil(r) : Math.floor(r);
97
- if (!Number.isSafeInteger(i)) throw new j({
97
+ if (!Number.isSafeInteger(i)) throw new A({
98
98
  field: t,
99
99
  message: `${t} exceeds the safe micro-USD range`
100
100
  });
101
101
  return BigInt(i);
102
- }, L = (e) => {
102
+ }, I = (e) => {
103
103
  if (typeof e == "number" && !Number.isSafeInteger(e)) throw Error("AI budget counter is not an exact integer");
104
104
  let t = String(e);
105
105
  if (!/^(0|[1-9][0-9]*)$/.test(t)) throw Error("AI budget counter is invalid; refusing to assume zero");
106
106
  return BigInt(t);
107
- }, we = (e) => {
108
- if (typeof e != "string" || e.length === 0 || e.length > 191) throw new j({
107
+ }, Te = (e) => {
108
+ if (typeof e != "string" || e.length === 0 || e.length > 191) throw new A({
109
109
  field: "reservationId",
110
110
  message: "AI budget reservationId must contain 1–191 characters"
111
111
  });
112
112
  return e;
113
- }, Te = () => {
114
- let e = oe(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
115
- for (let t of [N, P]) T({
113
+ }, Ee = () => {
114
+ let e = se(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760);
115
+ for (let t of [M, N]) oe({
116
116
  source: "plugin",
117
117
  table: t,
118
118
  timeColumn: "updatedAt",
119
119
  ttlMs: e
120
120
  });
121
- }, Ee = async (e, t) => {
121
+ }, De = async (e, t) => {
122
122
  for (let n = 0;; n++) try {
123
123
  return await e.transactional(t);
124
124
  } catch (e) {
125
- if (!(e instanceof I) || n >= 31) throw e;
125
+ if (!(e instanceof F) || n >= 31) throw e;
126
126
  await new Promise((e) => setTimeout(e, n + 1));
127
127
  }
128
- }, De = (e) => e instanceof A || e instanceof j || e instanceof M ? m.fail(e) : m.die(e), Oe = (e) => m.tryPromise({
128
+ }, Oe = (e) => e instanceof k || e instanceof A || e instanceof j ? m.fail(e) : m.die(e), ke = (e) => m.tryPromise({
129
129
  try: e,
130
130
  catch: (e) => e
131
- }).pipe(m.catchAll(De)), ke = (e, t) => m.gen(function* () {
131
+ }).pipe(m.catchAll(Oe)), Ae = (e, t) => m.gen(function* () {
132
132
  let { limit: n, amount: r, tenantId: i, bucket: a, reservationId: o } = yield* m.try({
133
133
  try: () => {
134
- let e = Ce(t.limitUsd, "limitUsd", "down"), n = Ce(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 j({
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
136
  field: "since",
137
137
  message: "AI budget since must be a valid Date"
138
138
  });
139
139
  let i = `${r ?? "global"}::${t.since === void 0 ? "all" : t.since.getTime()}`;
140
- if (i.length > 191) throw new j({
140
+ if (i.length > 191) throw new A({
141
141
  field: "tenantId",
142
142
  message: "AI budget tenant/window key exceeds 191 characters"
143
143
  });
@@ -146,35 +146,35 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
146
146
  amount: n,
147
147
  tenantId: r,
148
148
  bucket: i,
149
- reservationId: we(t.reservationId ?? b({
149
+ reservationId: Te(t.reservationId ?? b({
150
150
  kind: "typeid",
151
151
  prefix: "air"
152
152
  }, "_voltro_ai_budget_reservations"))
153
153
  };
154
154
  },
155
155
  catch: (e) => e
156
- }).pipe(m.catchAll(De));
157
- Te();
156
+ }).pipe(m.catchAll(Oe));
157
+ Ee();
158
158
  let s = async (e) => {
159
- let [t] = await e.query(w(F).where(y("bucket", a)).descriptor);
159
+ let [t] = await e.query(w(P).where(y("bucket", a)).descriptor);
160
160
  if (t && t.tenantId !== i) throw Error("AI budget bucket belongs to a different tenant");
161
161
  return t;
162
162
  }, c = (e) => {
163
- if (r === 0n ? e >= n : e + r > n) throw new A({
163
+ if (r === 0n ? e >= n : e + r > n) throw new k({
164
164
  tenantId: i,
165
165
  limitUsd: t.limitUsd,
166
166
  spentUsd: Number(e) / 1e6,
167
167
  attemptedUsd: t.addUsd ?? 0
168
168
  });
169
169
  };
170
- return r === 0n ? yield* Oe(async () => {
170
+ return r === 0n ? yield* ke(async () => {
171
171
  let t = await s(e);
172
- return c(t ? L(t.reservedMicroUsd) : 0n), null;
173
- }) : yield* Oe(() => Ee(e, async (e) => {
172
+ return c(t ? I(t.reservedMicroUsd) : 0n), null;
173
+ }) : yield* ke(() => De(e, async (e) => {
174
174
  let t = b({
175
175
  kind: "typeid",
176
176
  prefix: "air"
177
- }, P), n = /* @__PURE__ */ new Date(), l = await e.insertIgnore(P, {
177
+ }, N), n = /* @__PURE__ */ new Date(), l = await e.insertIgnore(N, {
178
178
  id: t,
179
179
  reservationId: o,
180
180
  bucket: a,
@@ -184,11 +184,11 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
184
184
  updatedAt: n
185
185
  }, { conflictColumns: ["reservationId"] });
186
186
  if (l.id !== t) {
187
- if (l.tenantId !== i || l.bucket !== a || L(l.amountMicroUsd) !== r) throw new M({
187
+ if (l.tenantId !== i || l.bucket !== a || I(l.amountMicroUsd) !== r) throw new j({
188
188
  reason: "identity-bound",
189
189
  message: "AI budget reservationId is already bound to another tenant, amount or window"
190
190
  });
191
- if (l.releasedAt !== null) throw new M({
191
+ if (l.releasedAt !== null) throw new j({
192
192
  reason: "already-released",
193
193
  message: "AI budget reservation was released; new spend requires a new reservationId"
194
194
  });
@@ -199,24 +199,24 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
199
199
  status: "replayed"
200
200
  };
201
201
  }
202
- let u = await s(e), d = u ? L(u.reservedMicroUsd) : 0n;
202
+ let u = await s(e), d = u ? I(u.reservedMicroUsd) : 0n;
203
203
  if (c(d), u) {
204
204
  if (await e.updateMany("_voltro_ai_budget", {
205
205
  reservedMicroUsd: String(d + r),
206
206
  updatedAt: n
207
- }, { where: v(y("id", u.id), y("reservedMicroUsd", u.reservedMicroUsd)) }) !== 1) throw new I("AI budget counter changed; discard this receipt and retry");
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
208
  } else {
209
209
  let t = b({
210
210
  kind: "typeid",
211
211
  prefix: "aib"
212
- }, N);
212
+ }, M);
213
213
  if ((await e.insertIgnore("_voltro_ai_budget", {
214
214
  id: t,
215
215
  bucket: a,
216
216
  tenantId: i,
217
217
  reservedMicroUsd: String(r),
218
218
  updatedAt: n
219
- }, { conflictColumns: ["bucket"] })).id !== t) throw new I("AI budget counter was created concurrently; discard this receipt and retry");
219
+ }, { conflictColumns: ["bucket"] })).id !== t) throw new F("AI budget counter was created concurrently; discard this receipt and retry");
220
220
  }
221
221
  return {
222
222
  reservationId: o,
@@ -225,12 +225,12 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
225
225
  status: "reserved"
226
226
  };
227
227
  }));
228
- }), Ae = (e, t) => m.gen(function* () {
228
+ }), je = (e, t) => m.gen(function* () {
229
229
  return yield* m.try({
230
- try: () => we(t.reservationId),
230
+ try: () => Te(t.reservationId),
231
231
  catch: (e) => e
232
- }).pipe(m.catchAll((e) => e instanceof j ? m.fail(e) : m.die(e))), yield* m.promise(() => Ee(e, async (e) => {
233
- let n = w(Se).where(v(y("reservationId", t.reservationId), t.tenantId === null ? ae("tenantId") : y("tenantId", t.tenantId))).descriptor, [r] = await e.query(n);
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
234
  if (!r) return "not-found";
235
235
  if (r.releasedAt !== null) return "already-released";
236
236
  let i = /* @__PURE__ */ new Date();
@@ -240,19 +240,19 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
240
240
  }, { where: v(y("id", r.id), ae("releasedAt")) }) !== 1) {
241
241
  let [t] = await e.query(n);
242
242
  if (t !== void 0 && t.releasedAt !== null) return "already-released";
243
- throw new I("AI budget release raced; retry");
243
+ throw new F("AI budget release raced; retry");
244
244
  }
245
- let [a] = await e.query(w(F).where(y("bucket", r.bucket)).descriptor);
245
+ let [a] = await e.query(w(P).where(y("bucket", r.bucket)).descriptor);
246
246
  if (!a || a.tenantId !== t.tenantId) throw Error("AI budget counter missing or mismatched; refusing unproved credit");
247
- let o = L(a.reservedMicroUsd), s = L(r.amountMicroUsd);
247
+ let o = I(a.reservedMicroUsd), s = I(r.amountMicroUsd);
248
248
  if (s > o) throw Error("AI budget receipt exceeds its counter; refusing unproved credit");
249
249
  if (await e.updateMany("_voltro_ai_budget", {
250
250
  reservedMicroUsd: String(o - s),
251
251
  updatedAt: i
252
- }, { where: v(y("id", a.id), y("reservedMicroUsd", a.reservedMicroUsd)) }) !== 1) throw new I("AI budget counter changed; discard this release and retry");
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
253
  return "released";
254
254
  }));
255
- }), je = {
255
+ }), Me = {
256
256
  "claude-opus-4-8": {
257
257
  inputPer1M: 15,
258
258
  outputPer1M: 75
@@ -297,21 +297,21 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
297
297
  inputPer1M: .1,
298
298
  outputPer1M: .4
299
299
  }
300
- }, R = {}, Me = (e) => {
301
- let t = R;
302
- return R = { ...e }, t;
303
- }, Ne = () => ({
304
- ...je,
305
- ...R
306
- }), Pe = (e) => {
307
- let t = Ne();
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
308
  if (t[e] !== void 0) return t[e];
309
309
  let n = e.indexOf("/");
310
310
  if (n > 0) {
311
311
  let r = e.slice(n + 1);
312
312
  if (t[r] !== void 0) return t[r];
313
313
  }
314
- }, z = (e) => typeof e.unit == "string", Fe = (e) => z(e) ? {
314
+ }, R = (e) => typeof e.unit == "string", Ie = (e) => R(e) ? {
315
315
  unit: e.unit,
316
316
  input: e.input ?? 0,
317
317
  output: e.output ?? 0
@@ -319,8 +319,8 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
319
319
  unit: "tokens",
320
320
  input: e.inputTokens ?? 0,
321
321
  output: e.outputTokens ?? 0
322
- }, Ie = (e, t) => {
323
- let { unit: n, input: r, output: i } = Fe(e);
322
+ }, z = (e, t) => {
323
+ let { unit: n, input: r, output: i } = Ie(e);
324
324
  if (t.actualCostUsd !== void 0) {
325
325
  if (!Number.isFinite(t.actualCostUsd) || t.actualCostUsd < 0) throw RangeError("estimateCostUsd: actualCostUsd must be a finite, non-negative USD amount.");
326
326
  let e = r + i, a = e > 0 ? r / e : 0;
@@ -343,7 +343,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
343
343
  costSource: "unpriced",
344
344
  unit: n
345
345
  };
346
- let a = t.price ?? Pe(t.model) ?? {
346
+ let a = t.price ?? Fe(t.model) ?? {
347
347
  inputPer1M: 0,
348
348
  outputPer1M: 0
349
349
  }, o = r / 1e6 * a.inputPer1M, s = i / 1e6 * a.outputPer1M;
@@ -356,25 +356,25 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
356
356
  costSource: "estimated",
357
357
  unit: n
358
358
  };
359
- }, B = "_voltro_ai_usage", Le = E(B, {
359
+ }, B = "_voltro_ai_usage", Le = T(B, {
360
360
  id: x({ prefix: "aiu" }),
361
- tenantId: D().nullable(),
362
- provider: D(),
363
- model: D(),
364
- operation: D(),
365
- agent: D().nullable(),
361
+ tenantId: E().nullable(),
362
+ provider: E(),
363
+ model: E(),
364
+ operation: E(),
365
+ agent: E().nullable(),
366
366
  inputTokens: S().default(0),
367
367
  outputTokens: S().default(0),
368
368
  costMicroUsd: S().default(0),
369
- costSource: D().default("estimated"),
370
- unit: D().default("tokens"),
371
- promptId: D().nullable(),
372
- promptDigest: D().nullable(),
369
+ costSource: E().default("estimated"),
370
+ unit: E().default("tokens"),
371
+ promptId: E().nullable(),
372
+ promptDigest: E().nullable(),
373
373
  promptRevision: S().nullable(),
374
- requestId: D().maxLength(191).nullable(),
374
+ requestId: E().maxLength(191).nullable(),
375
375
  attempt: S().nullable(),
376
- receiptKey: D().maxLength(191).backfill((e) => `aiu-pre-receipt-${String(e.id)}`),
377
- calledAt: O().default("now")
376
+ receiptKey: E().maxLength(191).backfill((e) => `aiu-pre-receipt-${String(e.id)}`),
377
+ calledAt: D().default("now")
378
378
  }).index(["tenantId"]).index(["promptDigest"]).unique("byAiUsageReceipt", ["receiptKey"]), Re = (e) => {
379
379
  let t = e?.gateway?.cost, n = typeof t == "string" ? t.trim() : void 0, r = typeof t == "number" ? t : n !== void 0 && /^(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i.test(n) ? Number(n) : NaN;
380
380
  return Number.isFinite(r) && r >= 0 ? r : void 0;
@@ -395,13 +395,13 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
395
395
  inputTokens: Number(e.inputTokens),
396
396
  outputTokens: Number(e.outputTokens),
397
397
  costMicroUsd: Number(e.costMicroUsd)
398
- }), He = (e, t) => (T({
398
+ }), He = (e, t) => (oe({
399
399
  source: "plugin",
400
400
  table: B,
401
401
  timeColumn: "calledAt",
402
- ttlMs: oe(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
402
+ ttlMs: se(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
403
403
  }), m.gen(function* () {
404
- let n = Ie(t.usage, {
404
+ let n = z(t.usage, {
405
405
  model: t.model,
406
406
  ...t.price === void 0 ? {} : { price: t.price },
407
407
  ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
@@ -460,7 +460,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
460
460
  provider: t.provider,
461
461
  model: t.model,
462
462
  operation: t.operation,
463
- ...z(t.usage) ? {
463
+ ...R(t.usage) ? {
464
464
  unit: t.usage.unit,
465
465
  input: t.usage.input ?? null,
466
466
  output: t.usage.output ?? null
@@ -498,7 +498,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
498
498
  model: e.model ?? e.name,
499
499
  operation: t
500
500
  }), 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)), Ze = (e, t) => {
501
- let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = Ie({
501
+ let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = z({
502
502
  inputTokens: n,
503
503
  outputTokens: r
504
504
  }, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
@@ -528,8 +528,8 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
528
528
  strictTuples: !1,
529
529
  strictRequired: !1,
530
530
  allowUnionTypes: !0
531
- }, r = t.$schema, i = r === "https://json-schema.org/draft/2020-12/schema" ? new le(n) : r === "https://json-schema.org/draft/2019-09/schema" ? new ce(n) : new se(n);
532
- ue(i);
531
+ }, 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);
532
+ de(i);
533
533
  let a = i.compile(t);
534
534
  if ("$async" in a && a.$async === !0) throw Error("asynchronous output schemas are not supported");
535
535
  return c(t, { validate: (e) => a(e) ? {
@@ -654,7 +654,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
654
654
  reason: "generation",
655
655
  message: "generateText: supply exactly one of prompt or messages"
656
656
  }));
657
- let i = e.tools === void 0 ? void 0 : yield* m.runtime(), a = e.tools === void 0 || i === void 0 ? void 0 : k(e.tools, {
657
+ let i = e.tools === void 0 ? void 0 : yield* m.runtime(), a = e.tools === void 0 || i === void 0 ? void 0 : O(e.tools, {
658
658
  store: void 0,
659
659
  ...e.toolContext,
660
660
  ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
@@ -759,7 +759,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
759
759
  ...e.toolContext,
760
760
  ...e.abortSignal === void 0 ? {} : { abortSignal: e.abortSignal },
761
761
  runtime: a
762
- }, d = k(e.tools, u);
762
+ }, d = O(e.tools, u);
763
763
  return yield* at(e.provider ?? n(), e.fallbacks, (n) => G(U(n, "generateObjectWithTools"), (e) => e.usage, m.gen(function* () {
764
764
  let a = rt(n.name, t(n)), u = a.model, f = yield* m.tryPromise({
765
765
  try: () => s({
@@ -863,7 +863,7 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
863
863
  },
864
864
  catch: (e) => J(e)
865
865
  }));
866
- }, _t = (e) => `sha256:${de("sha256").update(e).digest("hex").slice(0, 16)}`, vt = class extends _.TaggedError()("PromptRenderError", {
866
+ }, _t = (e) => `sha256:${fe("sha256").update(e).digest("hex").slice(0, 16)}`, vt = class extends _.TaggedError()("PromptRenderError", {
867
867
  promptId: _.String,
868
868
  missing: _.Array(_.String),
869
869
  message: _.String
@@ -898,23 +898,23 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
898
898
  });
899
899
  })
900
900
  };
901
- }, Ct = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", Y = "_voltro_prompts", X = E(Y, {
901
+ }, Ct = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", Y = "_voltro_prompts", X = T(Y, {
902
902
  id: x({ prefix: "prm" }),
903
- promptId: D().maxLength(191),
904
- digest: D().maxLength(191),
903
+ promptId: E().maxLength(191),
904
+ digest: E().maxLength(191),
905
905
  revision: S().default(1),
906
- label: D().nullable(),
907
- template: D().nullable(),
908
- system: D().nullable(),
906
+ label: E().nullable(),
907
+ template: E().nullable(),
908
+ system: E().nullable(),
909
909
  templateChars: S().default(0),
910
- firstSeenAt: O().default("now"),
911
- lastUsedAt: O().default("now")
910
+ firstSeenAt: D().default("now"),
911
+ lastUsedAt: D().default("now")
912
912
  }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), wt = 8760, Tt = () => {
913
- T({
913
+ oe({
914
914
  source: "framework",
915
915
  table: Y,
916
916
  timeColumn: "lastUsedAt",
917
- ttlMs: oe(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, wt),
917
+ ttlMs: se(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, wt),
918
918
  envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
919
919
  label: "ai prompt versions"
920
920
  });
@@ -959,32 +959,32 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
959
959
  }), Dt = (e, t) => m.promise(async () => {
960
960
  let n = (await e.query(w(X).where(y("digest", t)).descriptor))[0];
961
961
  return n === void 0 ? null : Z(n);
962
- }), Ot = (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)), kt = "_voltro_ai_inferences", At = E(kt, {
962
+ }), Ot = (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)), kt = "_voltro_ai_inferences", At = T(kt, {
963
963
  id: x({ prefix: "aiinf" }),
964
- tenantId: D().nullable(),
965
- executionId: D(),
966
- workflowName: D(),
967
- runId: D().nullable(),
968
- signalName: D(),
969
- stepName: D(),
970
- status: D().oneOf([
964
+ tenantId: E().nullable(),
965
+ executionId: E(),
966
+ workflowName: E(),
967
+ runId: E().nullable(),
968
+ signalName: E(),
969
+ stepName: E(),
970
+ status: E().oneOf([
971
971
  "pending",
972
972
  "running",
973
973
  "succeeded",
974
974
  "failed"
975
975
  ]).default("pending"),
976
- kind: D().oneOf([
976
+ kind: E().oneOf([
977
977
  "text",
978
978
  "object",
979
979
  "transcription",
980
980
  "media"
981
981
  ]).default("text"),
982
- provider: D(),
983
- model: D(),
984
- prompt: D(),
985
- system: D().nullable(),
986
- promptId: D().nullable(),
987
- promptDigest: D().nullable(),
982
+ provider: E(),
983
+ model: E(),
984
+ prompt: E(),
985
+ system: E().nullable(),
986
+ promptId: E().nullable(),
987
+ promptDigest: E().nullable(),
988
988
  promptRevision: S().nullable(),
989
989
  maxTokens: S().nullable(),
990
990
  providerOptions: C().nullable(),
@@ -992,16 +992,17 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
992
992
  transcription: C().nullable(),
993
993
  media: C().nullable(),
994
994
  taskHandle: C().nullable(),
995
- taskSubmittedAt: O().nullable(),
995
+ taskSubmittedAt: D().nullable(),
996
996
  result: C().nullable(),
997
- errorMessage: D().nullable(),
997
+ errorMessage: E().nullable(),
998
998
  attempts: S().default(0),
999
999
  fence: S().default(0),
1000
- leaseUntil: O().nullable(),
1001
- claimedBy: D().nullable(),
1002
- enqueuedAt: O().default("now"),
1003
- startedAt: O().nullable(),
1004
- completedAt: O().nullable(),
1000
+ leaseUntil: D().nullable(),
1001
+ claimedBy: E().nullable(),
1002
+ queuedAt: D().nullable(),
1003
+ enqueuedAt: D().default("now"),
1004
+ startedAt: D().nullable(),
1005
+ completedAt: D().nullable(),
1005
1006
  durationMs: S().nullable()
1006
1007
  }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), jt = 3e5, Mt = 4, Q = (e, t) => {
1007
1008
  let n = typeof e == "number" ? e : Number(e);
@@ -1048,6 +1049,6 @@ var fe = (e, t) => e(t), pe = Symbol.for("@voltro/ai/Tool"), me = (e) => ({
1048
1049
  attempts: t,
1049
1050
  delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
1050
1051
  };
1051
- }, It = (e) => `voltro.ai.infer:${e}`, Lt = (e, t) => `aiinf_${de("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
1052
+ }, It = (e) => `voltro.ai.infer:${e}`, Lt = (e, t) => `aiinf_${fe("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
1052
1053
  //#endregion
1053
- export { M as $, tt as A, Ie as B, J as C, dt as D, lt as E, Be as F, Pe as G, z as H, ze as I, Me as J, He as K, je as L, Qe as M, G as N, ot as O, B as P, j as Q, Ge as R, ft as S, ut as T, Ne as U, Re as V, Fe as W, N as X, P as Y, A as Z, Ot as _, Ft as a, me as at, gt as b, Pt as c, vt as d, Se as et, St as f, xt as g, Dt as h, At as i, k as it, U as j, ct as k, wt as l, _t as m, Mt as n, Ae as nt, It as o, he as ot, Ct as p, We as q, jt as r, ke as rt, Lt as s, ge as st, kt as t, F as tt, Y as u, X as v, pt as w, q as x, Et as y, Le as z };
1054
+ export { j as $, tt as A, z as B, J as C, dt as D, lt as E, Be as F, Fe as G, R as H, ze as I, Ne as J, He as K, Me as L, Qe as M, G as N, ot as O, B as P, A as Q, Ge as R, ft as S, ut as T, Pe as U, Re as V, Ie as W, M as X, N as Y, k as Z, Ot as _, Ft as a, he as at, gt as b, Pt as c, vt as d, Ce as et, St as f, xt as g, Dt as h, At as i, O as it, U as j, ct as k, wt as l, _t as m, Mt as n, je as nt, It as o, ge as ot, Ct as p, We as q, jt as r, Ae as rt, Lt as s, _e as st, kt as t, P as tt, Y as u, X as v, pt as w, q as x, Et as y, Le as z };
package/dist/workflow.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { r as e } from "./provider-BsyDya-H.js";
2
- import { D as t, O as n, T as r, V as i, b as a, k as o, m as s, o as c, p as l, q as u, rt as d, s as f, t as p, y as m } from "./inferenceQueue-t5ayqzjs.js";
2
+ import { D as t, O as n, T as r, V as i, b as a, k as o, m as s, o as c, p as l, q as u, rt as d, s as f, t as p, y as m } from "./inferenceQueue-ita1Kn2m.js";
3
3
  import { Effect as h, Schema as g } from "effect";
4
4
  import { eq as _ } from "@voltro/database";
5
5
  import { BudgetHoldExpired as v, CurrentWorkflowExecutionId as y, awaitSignalSuspending as b, step as x, suspendForBudget as S } from "@voltro/workflow";
@@ -89,7 +89,7 @@ var C = {
89
89
  take: 1,
90
90
  skip: void 0,
91
91
  projection: void 0
92
- })), v = String(g[0]?.tag ?? ""), b = g[0]?.id;
92
+ })), v = String(g[0]?.tag ?? ""), b = g[0]?.id, x = /* @__PURE__ */ new Date();
93
93
  return yield* h.promise(() => s.insertIgnore(p, {
94
94
  id: m,
95
95
  tenantId: e.tenantId ?? null,
@@ -114,7 +114,8 @@ var C = {
114
114
  ...o === void 0 ? {} : { media: o },
115
115
  attempts: 0,
116
116
  fence: 0,
117
- enqueuedAt: /* @__PURE__ */ new Date()
117
+ queuedAt: x,
118
+ enqueuedAt: x
118
119
  }, { conflictColumns: ["id"] })), m;
119
120
  }), I = (e, t, n, r, i, a, o, s) => h.gen(function* () {
120
121
  let l = yield* x({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/ai",
3
- "version": "0.80.0",
3
+ "version": "0.82.0",
4
4
  "description": "Effect-native AI primitives — generateText / generateObject / streamText, tools, agents, media generation, cost tracking + budgets, and provider fallback.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -55,10 +55,10 @@
55
55
  "dependencies": {
56
56
  "@ai-sdk/anthropic": "^4.0.56",
57
57
  "@ai-sdk/openai": "^4.0.69",
58
- "@voltro/cache": "0.80.0",
59
- "@voltro/database": "0.80.0",
60
- "@voltro/protocol": "0.80.0",
61
- "@voltro/workflow": "0.80.0",
58
+ "@voltro/cache": "0.82.0",
59
+ "@voltro/database": "0.82.0",
60
+ "@voltro/protocol": "0.82.0",
61
+ "@voltro/workflow": "0.82.0",
62
62
  "ajv": "^8.20.0",
63
63
  "ajv-formats": "^3.0.1",
64
64
  "ws": "^8.21.3"