@voltro/ai 0.33.0 → 0.34.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.
@@ -0,0 +1,568 @@
1
+ import { a as e, r as t } from "./provider-BOC5wBxx.js";
2
+ import { Output as n, generateObject as r, generateText as i, jsonSchema as a, stepCountIs as o, tool as s } from "ai";
3
+ import { Context as c, Effect as l, JSONSchema as u, Metric as d, MetricBoundaries as ee, Runtime as f, Schema as p, Stream as m } from "effect";
4
+ import { and as h, eq as g, generateId as _, gte as te, id as v, integer as y, json as b, queryFor as x, registerRetention as S, retentionTtlMsFromEnv as C, table as w, text as T, timestamp as E } from "@voltro/database";
5
+ import { createHash as D } from "node:crypto";
6
+ //#region src/tools.ts
7
+ var ne = (e, t) => e(t), re = Symbol.for("@voltro/ai/Tool"), ie = (e) => ({
8
+ ...e,
9
+ [re]: !0
10
+ }), ae = (e) => typeof e == "object" && !!e && e[re] === !0, oe = (e) => {
11
+ let t = e.default;
12
+ if (typeof t != "function") return 0;
13
+ let n = 0;
14
+ for (let r of Object.values(e)) ae(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
15
+ return n;
16
+ }, se = (e, t) => {
17
+ let n = t ?? f.defaultRuntime;
18
+ return f.runPromise(n)(e);
19
+ }, ce = (e, t, n) => n ? e.pipe(l.timeoutFail({
20
+ duration: `${n} millis`,
21
+ onTimeout: () => /* @__PURE__ */ Error(`tool '${t}' timed out`)
22
+ })) : e, le = (e, t, n) => {
23
+ if (e.execute) return se(ce(ne(e.execute, t), e.name, e.timeoutMs), n.runtime);
24
+ if (e.handler) {
25
+ let r = e.handler, i = r(t, n);
26
+ return l.isEffect(i) ? se(ce(i, e.name, e.timeoutMs), n.runtime) : i;
27
+ }
28
+ return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
29
+ }, ue = (e) => {
30
+ let t = u.make(e);
31
+ return t && t.type === "object" ? t : {
32
+ type: "object",
33
+ properties: {},
34
+ additionalProperties: !1
35
+ };
36
+ }, de = (e) => {
37
+ let t = e.inputJsonSchema;
38
+ return t === void 0 ? ue(e.input) : t.type === "object" ? t : {
39
+ type: "object",
40
+ properties: {},
41
+ additionalProperties: !0
42
+ };
43
+ }, fe = (e, t = { store: void 0 }) => {
44
+ let n = {};
45
+ for (let [r, i] of Object.entries(e)) n[i.name || r] = s({
46
+ description: i.description,
47
+ inputSchema: a(de(i)),
48
+ execute: async (e) => {
49
+ let n = await l.runPromise(p.decodeUnknown(i.input)(e)), r = await le(i, n, t);
50
+ return i.output ? l.runPromise(p.decodeUnknown(i.output)(r)) : r;
51
+ }
52
+ });
53
+ return n;
54
+ }, O = {
55
+ "claude-opus-4-8": {
56
+ inputPer1M: 15,
57
+ outputPer1M: 75
58
+ },
59
+ "claude-opus-4-6": {
60
+ inputPer1M: 15,
61
+ outputPer1M: 75
62
+ },
63
+ "claude-sonnet-4-6": {
64
+ inputPer1M: 3,
65
+ outputPer1M: 15
66
+ },
67
+ "claude-haiku-4-5": {
68
+ inputPer1M: 1,
69
+ outputPer1M: 5
70
+ },
71
+ "claude-haiku-4-5-20251001": {
72
+ inputPer1M: 1,
73
+ outputPer1M: 5
74
+ },
75
+ "gpt-5.5": {
76
+ inputPer1M: 5,
77
+ outputPer1M: 30
78
+ },
79
+ "gpt-4o": {
80
+ inputPer1M: 2.5,
81
+ outputPer1M: 10
82
+ },
83
+ "gpt-4o-mini": {
84
+ inputPer1M: .15,
85
+ outputPer1M: .6
86
+ },
87
+ "gemini-2.5-pro": {
88
+ inputPer1M: 1.25,
89
+ outputPer1M: 10
90
+ },
91
+ "gemini-2.5-flash": {
92
+ inputPer1M: .3,
93
+ outputPer1M: 2.5
94
+ },
95
+ "gemini-2.0-flash": {
96
+ inputPer1M: .1,
97
+ outputPer1M: .4
98
+ }
99
+ }, k = {}, pe = (e) => {
100
+ let t = k;
101
+ return k = { ...e }, t;
102
+ }, A = () => ({
103
+ ...O,
104
+ ...k
105
+ }), j = (e) => {
106
+ let t = A();
107
+ if (t[e] !== void 0) return t[e];
108
+ let n = e.indexOf("/");
109
+ if (n > 0) {
110
+ let r = e.slice(n + 1);
111
+ if (t[r] !== void 0) return t[r];
112
+ }
113
+ }, M = (e, t) => {
114
+ let n = e.inputTokens ?? 0, r = e.outputTokens ?? 0;
115
+ if (t.actualCostUsd !== void 0) {
116
+ let e = n + r, i = e > 0 ? n / e : 0;
117
+ return {
118
+ inputTokens: n,
119
+ outputTokens: r,
120
+ inputCostUsd: t.actualCostUsd * i,
121
+ outputCostUsd: t.actualCostUsd * (1 - i),
122
+ totalCostUsd: t.actualCostUsd,
123
+ costSource: "gateway"
124
+ };
125
+ }
126
+ let i = t.price ?? j(t.model) ?? {
127
+ inputPer1M: 0,
128
+ outputPer1M: 0
129
+ }, a = n / 1e6 * i.inputPer1M, o = r / 1e6 * i.outputPer1M;
130
+ return {
131
+ inputTokens: n,
132
+ outputTokens: r,
133
+ inputCostUsd: a,
134
+ outputCostUsd: o,
135
+ totalCostUsd: a + o,
136
+ costSource: "estimated"
137
+ };
138
+ }, N = "_voltro_ai_usage", P = w(N, {
139
+ id: v({ prefix: "aiu" }),
140
+ tenantId: T().nullable(),
141
+ provider: T(),
142
+ model: T(),
143
+ operation: T(),
144
+ agent: T().nullable(),
145
+ inputTokens: y().default(0),
146
+ outputTokens: y().default(0),
147
+ costMicroUsd: y().default(0),
148
+ costSource: T().default("estimated"),
149
+ promptId: T().nullable(),
150
+ promptDigest: T().nullable(),
151
+ promptRevision: y().nullable(),
152
+ calledAt: E().default("now")
153
+ }).index(["tenantId"]).index(["promptDigest"]), me = (e) => {
154
+ let t = e?.gateway?.cost, n = typeof t == "number" ? t : typeof t == "string" ? Number(t) : NaN;
155
+ return Number.isFinite(n) ? n : void 0;
156
+ }, he = (e, t) => (S({
157
+ source: "plugin",
158
+ table: N,
159
+ timeColumn: "calledAt",
160
+ ttlMs: C(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 24 * 365)
161
+ }), l.promise(async () => {
162
+ let n = M(t.usage, {
163
+ model: t.model,
164
+ ...t.price === void 0 ? {} : { price: t.price },
165
+ ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
166
+ });
167
+ return await e.insert(N, {
168
+ tenantId: t.tenantId ?? null,
169
+ provider: t.provider,
170
+ model: t.model,
171
+ operation: t.operation,
172
+ agent: t.agent ?? null,
173
+ inputTokens: n.inputTokens,
174
+ outputTokens: n.outputTokens,
175
+ costMicroUsd: Math.round(n.totalCostUsd * 1e6),
176
+ costSource: n.costSource,
177
+ promptId: t.prompt?.promptId ?? null,
178
+ promptDigest: t.prompt?.digest ?? null,
179
+ promptRevision: t.prompt?.revision ?? null,
180
+ calledAt: t.calledAt ?? /* @__PURE__ */ new Date()
181
+ }), n;
182
+ })), ge = (e, t = {}) => l.promise(async () => {
183
+ let n = [
184
+ ...t.tenantId === void 0 ? [] : [g("tenantId", t.tenantId)],
185
+ ...t.since === void 0 ? [] : [te("calledAt", t.since)],
186
+ ...t.promptDigest === void 0 ? [] : [g("promptDigest", t.promptDigest)]
187
+ ], r = x(P), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : h(...n));
188
+ return (await e.query(i.descriptor)).reduce((e, t) => e + (Number(t.costMicroUsd) || 0), 0) / 1e6;
189
+ }), F = class extends p.TaggedError()("AiBudgetExceeded", {
190
+ tenantId: p.NullOr(p.String),
191
+ limitUsd: p.Number,
192
+ spentUsd: p.Number,
193
+ attemptedUsd: p.Number
194
+ }) {}, I = "_voltro_ai_budget", L = w(I, {
195
+ id: v({ prefix: "aib" }),
196
+ bucket: T().maxLength(191),
197
+ tenantId: T().nullable(),
198
+ reservedMicroUsd: y().default(0),
199
+ updatedAt: E().default("now")
200
+ }).unique("byAiBudgetBucket", ["bucket"]), _e = (e, t) => `${e ?? "global"}::${t === void 0 ? "all" : String(t.getTime())}`, R = 32, ve = (e, t) => l.gen(function* () {
201
+ S({
202
+ source: "plugin",
203
+ table: I,
204
+ timeColumn: "updatedAt",
205
+ ttlMs: C(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 24 * 365)
206
+ });
207
+ let n = t.addUsd ?? 0, r = Math.round(n * 1e6), i = Math.round(t.limitUsd * 1e6), a = _e(t.tenantId, t.since), o = t.tenantId ?? null, s = (e) => new F({
208
+ tenantId: o,
209
+ limitUsd: t.limitUsd,
210
+ spentUsd: e / 1e6,
211
+ attemptedUsd: n
212
+ }), c = yield* l.promise(async () => {
213
+ for (let t = 0; t < R; t++) {
214
+ t > 0 && await new Promise((e) => setTimeout(e, t));
215
+ let n = (await e.query(x(L).where(g("bucket", a)).descriptor))[0], s = n && Number(n.reservedMicroUsd) || 0;
216
+ if (s + r > i) return {
217
+ ok: !1,
218
+ reservedMicro: s
219
+ };
220
+ if (r === 0) return { ok: !0 };
221
+ if (n) {
222
+ if (await e.updateMany("_voltro_ai_budget", {
223
+ reservedMicroUsd: s + r,
224
+ updatedAt: /* @__PURE__ */ new Date()
225
+ }, { where: h(g("id", String(n.id)), g("reservedMicroUsd", s)) }) === 1) return { ok: !0 };
226
+ } else {
227
+ let t = _({
228
+ kind: "typeid",
229
+ prefix: "aib"
230
+ }, I), n = await e.insertIgnore(I, {
231
+ id: t,
232
+ bucket: a,
233
+ tenantId: o,
234
+ reservedMicroUsd: r,
235
+ updatedAt: /* @__PURE__ */ new Date()
236
+ }, { conflictColumns: ["bucket"] });
237
+ if (String(n.id) === t) return { ok: !0 };
238
+ }
239
+ }
240
+ throw Error(`requireAiBudget: contention on bucket '${a}' exceeded ${R} attempts`);
241
+ });
242
+ if (!c.ok) return yield* l.fail(s(c.reservedMicro));
243
+ }), ye = ee.exponential({
244
+ start: .001,
245
+ factor: 2,
246
+ count: 16
247
+ }), z = d.counter("voltro_ai_calls_total", { description: "Total AI provider calls (generate + stream)." }), B = d.counter("voltro_ai_call_errors_total", { description: "AI provider calls that errored." }), V = d.histogram("voltro_ai_call_duration_seconds", ye, "AI provider call duration in seconds."), be = d.counter("voltro_ai_input_tokens_total", {
248
+ description: "Total prompt (input) tokens across AI calls.",
249
+ incremental: !0
250
+ }), xe = d.counter("voltro_ai_output_tokens_total", {
251
+ description: "Total completion (output) tokens across AI calls.",
252
+ incremental: !0
253
+ }), Se = d.counter("voltro_ai_cost_microusd_total", {
254
+ description: "Total estimated AI spend in micro-USD (USD × 1e6).",
255
+ incremental: !0
256
+ }), H = (e, t) => ({
257
+ provider: e.name,
258
+ model: e.model ?? e.name,
259
+ operation: t
260
+ }), U = (e, t, n) => e.pipe(l.tagMetrics("provider", t.provider), l.tagMetrics("model", t.model), l.tagMetrics("operation", t.operation), l.tagMetrics("status", n)), Ce = (e, t) => {
261
+ let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = M({
262
+ inputTokens: n,
263
+ outputTokens: r
264
+ }, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
265
+ return l.all([
266
+ U(d.incrementBy(be, n), e, "ok"),
267
+ U(d.incrementBy(xe, r), e, "ok"),
268
+ U(d.incrementBy(Se, a), e, "ok")
269
+ ], { discard: !0 });
270
+ }, W = (e, t, n) => l.gen(function* () {
271
+ let r = yield* l.clockWith((e) => e.currentTimeMillis);
272
+ return yield* n.pipe(l.tap((n) => Ce(e, t(n))), l.tap(() => U(d.increment(z), e, "ok").pipe(l.zipRight(l.clockWith((e) => e.currentTimeMillis).pipe(l.flatMap((t) => U(d.update(V, (t - r) / 1e3), e, "ok")))))), l.tapError(() => U(d.increment(z), e, "error").pipe(l.zipRight(U(d.increment(B), e, "error")), l.zipRight(l.clockWith((e) => e.currentTimeMillis).pipe(l.flatMap((t) => U(d.update(V, (t - r) / 1e3), e, "error")))))), l.withSpan("voltro.ai.call", { attributes: {
273
+ "ai.provider": e.provider,
274
+ "ai.model": e.model,
275
+ "ai.operation": e.operation
276
+ } }));
277
+ }), we = (e, t) => {
278
+ let n = Date.now();
279
+ return t.pipe(m.tap((t) => t._tag === "done" ? U(d.increment(z), e, "ok").pipe(l.zipRight(U(d.update(V, (Date.now() - n) / 1e3), e, "ok")), l.zipRight(Ce(e, t.usage ?? {}))) : t._tag === "error" ? U(d.increment(z), e, "error").pipe(l.zipRight(U(d.increment(B), e, "error")), l.zipRight(U(d.update(V, (Date.now() - n) / 1e3), e, "error"))) : l.void), m.withSpan("voltro.ai.call", { attributes: {
280
+ "ai.provider": e.provider,
281
+ "ai.model": e.model,
282
+ "ai.operation": e.operation
283
+ } }));
284
+ }, G = class extends p.TaggedError()("AiError", {
285
+ reason: p.Literal("generation", "decode"),
286
+ message: p.String
287
+ }) {}, K = (e, t, n) => {
288
+ let r = [e, ...t ?? []], i = (e) => n(r[e]).pipe(l.catchTag("AiError", (t) => t.reason === "generation" && e + 1 < r.length ? i(e + 1) : l.fail(t)));
289
+ return i(0);
290
+ }, Te = (n) => K(n.provider ?? t(), n.fallbacks, (t) => W(H(t, "generateText"), (e) => e.usage, l.tryPromise({
291
+ try: async () => {
292
+ let r = await i({
293
+ model: e(t),
294
+ prompt: n.prompt,
295
+ ...n.system === void 0 ? {} : { system: n.system },
296
+ ...n.maxTokens === void 0 ? {} : { maxOutputTokens: n.maxTokens },
297
+ ...n.providerOptions === void 0 ? {} : { providerOptions: n.providerOptions }
298
+ });
299
+ return {
300
+ text: r.text,
301
+ usage: {
302
+ inputTokens: r.usage.inputTokens,
303
+ outputTokens: r.usage.outputTokens,
304
+ totalTokens: r.usage.totalTokens
305
+ },
306
+ providerMetadata: r.providerMetadata
307
+ };
308
+ },
309
+ catch: (e) => new G({
310
+ reason: "generation",
311
+ message: String(e?.message ?? e)
312
+ })
313
+ }))), q = (e, t) => l.gen(function* () {
314
+ let n = u.make(e);
315
+ if (n?.type !== "object") {
316
+ let e = n?.anyOf === void 0 ? `type:${JSON.stringify(n?.type ?? null)}` : "anyOf (e.g. Schema.Struct({}) or a union)";
317
+ return yield* l.fail(new G({
318
+ reason: "generation",
319
+ 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(...) })).`
320
+ }));
321
+ }
322
+ return n;
323
+ }), Ee = (e, t) => q(e, t), De = (n) => K(n.provider ?? t(), n.fallbacks, (t) => W(H(t, "generateObject"), (e) => e.usage, l.gen(function* () {
324
+ let i = e(t), o = yield* l.tryPromise({
325
+ try: () => r({
326
+ model: i,
327
+ schema: a(n.jsonSchema),
328
+ prompt: n.prompt,
329
+ ...n.system === void 0 ? {} : { system: n.system },
330
+ ...n.maxTokens === void 0 ? {} : { maxOutputTokens: n.maxTokens },
331
+ ...n.providerOptions === void 0 ? {} : { providerOptions: n.providerOptions }
332
+ }),
333
+ catch: (e) => new G({
334
+ reason: "generation",
335
+ message: String(e?.message ?? e)
336
+ })
337
+ });
338
+ return {
339
+ object: o.object,
340
+ usage: {
341
+ inputTokens: o.usage.inputTokens,
342
+ outputTokens: o.usage.outputTokens,
343
+ totalTokens: o.usage.totalTokens
344
+ },
345
+ providerMetadata: o.providerMetadata
346
+ };
347
+ }))), Oe = (e) => l.gen(function* () {
348
+ let t = yield* De({
349
+ jsonSchema: yield* q(e.schema, "generateObject"),
350
+ prompt: e.prompt,
351
+ ...e.system === void 0 ? {} : { system: e.system },
352
+ ...e.provider === void 0 ? {} : { provider: e.provider },
353
+ ...e.fallbacks === void 0 ? {} : { fallbacks: e.fallbacks },
354
+ ...e.maxTokens === void 0 ? {} : { maxTokens: e.maxTokens },
355
+ ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
356
+ }), n = yield* p.decodeUnknown(e.schema)(t.object).pipe(l.mapError((e) => new G({
357
+ reason: "decode",
358
+ message: `model output failed schema decode: ${String(e)}`
359
+ })));
360
+ return {
361
+ ...t,
362
+ object: n
363
+ };
364
+ }), ke = (r) => l.gen(function* () {
365
+ let s = yield* l.runtime(), c = yield* q(r.schema, "generateObjectWithTools"), u = {
366
+ store: void 0,
367
+ ...r.toolContext,
368
+ runtime: s
369
+ }, d = fe(r.tools, u);
370
+ return yield* K(r.provider ?? t(), r.fallbacks, (t) => W(H(t, "generateObjectWithTools"), (e) => e.usage, l.gen(function* () {
371
+ let s = e(t), u = yield* l.tryPromise({
372
+ try: () => i({
373
+ model: s,
374
+ prompt: r.prompt,
375
+ tools: d,
376
+ stopWhen: o(r.maxSteps ?? 8),
377
+ output: n.object({ schema: a(c) }),
378
+ ...r.system === void 0 ? {} : { system: r.system },
379
+ ...r.maxTokens === void 0 ? {} : { maxOutputTokens: r.maxTokens },
380
+ ...r.providerOptions === void 0 ? {} : { providerOptions: r.providerOptions }
381
+ }),
382
+ catch: (e) => new G({
383
+ reason: "generation",
384
+ message: String(e?.message ?? e)
385
+ })
386
+ });
387
+ return {
388
+ object: yield* p.decodeUnknown(r.schema)(u.output).pipe(l.mapError((e) => new G({
389
+ reason: "decode",
390
+ message: `model output failed schema decode: ${String(e)}`
391
+ }))),
392
+ usage: {
393
+ inputTokens: u.usage.inputTokens,
394
+ outputTokens: u.usage.outputTokens,
395
+ totalTokens: u.usage.totalTokens
396
+ },
397
+ providerMetadata: u.providerMetadata
398
+ };
399
+ })));
400
+ }), Ae = class extends c.Tag("@voltro/AiService")() {}, je = {
401
+ generateText: (e) => Te(e),
402
+ generateObject: (e) => Oe(e)
403
+ }, Me = (e) => `sha256:${D("sha256").update(e).digest("hex").slice(0, 16)}`, Ne = class extends p.TaggedError()("PromptRenderError", {
404
+ promptId: p.String,
405
+ missing: p.Array(p.String),
406
+ message: p.String
407
+ }) {}, Pe = /\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, Fe = (e) => {
408
+ let t = /* @__PURE__ */ new Set();
409
+ for (let n of e.matchAll(Pe)) {
410
+ let e = n[1];
411
+ e !== void 0 && t.add(e);
412
+ }
413
+ return [...t];
414
+ }, Ie = (e, t) => Me(`${e.length}:${e}${(t ?? "").length}:${t ?? ""}`), Le = (e) => {
415
+ let t = Ie(e.template, e.system), n = Fe(e.template);
416
+ return {
417
+ ...e,
418
+ digest: t,
419
+ variables: n,
420
+ render: (r = {}) => l.suspend(() => {
421
+ let i = n.filter((e) => r[e] === void 0);
422
+ if (i.length > 0) return l.fail(new Ne({
423
+ promptId: e.id,
424
+ missing: i,
425
+ message: `prompt '${e.id}' needs ${i.map((e) => `{{${e}}}`).join(", ")}, which ${i.length === 1 ? "was" : "were"} not supplied.`
426
+ }));
427
+ let a = e.template.replace(Pe, (e, t) => String(r[t]));
428
+ return l.succeed({
429
+ promptId: e.id,
430
+ digest: t,
431
+ ...e.label === void 0 ? {} : { label: e.label },
432
+ prompt: a,
433
+ ...e.system === void 0 ? {} : { system: e.system },
434
+ definition: e
435
+ });
436
+ })
437
+ };
438
+ }, Re = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", J = "_voltro_prompts", Y = w(J, {
439
+ id: v({ prefix: "prm" }),
440
+ promptId: T().maxLength(191),
441
+ digest: T().maxLength(191),
442
+ revision: y().default(1),
443
+ label: T().nullable(),
444
+ template: T().nullable(),
445
+ system: T().nullable(),
446
+ templateChars: y().default(0),
447
+ firstSeenAt: E().default("now"),
448
+ lastUsedAt: E().default("now")
449
+ }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), ze = 24 * 365, Be = () => {
450
+ S({
451
+ source: "framework",
452
+ table: J,
453
+ timeColumn: "lastUsedAt",
454
+ ttlMs: C(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, ze),
455
+ envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
456
+ label: "ai prompt versions"
457
+ });
458
+ }, X = (e) => ({
459
+ promptId: String(e.promptId),
460
+ digest: String(e.digest),
461
+ revision: Number(e.revision) || 1,
462
+ label: e.label ?? null,
463
+ template: e.template ?? null,
464
+ system: e.system ?? null,
465
+ firstSeenAt: e.firstSeenAt ?? null,
466
+ lastUsedAt: e.lastUsedAt ?? null
467
+ }), Ve = (e, t) => l.gen(function* () {
468
+ Be();
469
+ let n = t.digest ?? Le(t).digest;
470
+ return yield* l.promise(async () => {
471
+ let r = (await e.query(x(Y).where(h(g("promptId", t.id), g("digest", n))).descriptor))[0];
472
+ if (r !== void 0) {
473
+ let t = /* @__PURE__ */ new Date();
474
+ return await e.updateMany(J, { lastUsedAt: t }, { where: g("id", String(r.id)) }), X({
475
+ ...r,
476
+ lastUsedAt: t
477
+ });
478
+ }
479
+ let i = (await e.query(x(Y).where(g("promptId", t.id)).descriptor)).reduce((e, t) => Math.max(e, Number(t.revision) || 0), 0) + 1, a = /* @__PURE__ */ new Date(), o = {
480
+ id: _({
481
+ kind: "typeid",
482
+ prefix: "prm"
483
+ }, J),
484
+ promptId: t.id,
485
+ digest: n,
486
+ revision: i,
487
+ label: t.label ?? null,
488
+ template: t.template,
489
+ system: t.system ?? null,
490
+ templateChars: t.template.length,
491
+ firstSeenAt: a,
492
+ lastUsedAt: a
493
+ };
494
+ return X(await e.insertIgnore(J, o, { conflictColumns: ["promptId", "digest"] }) ?? o);
495
+ });
496
+ }), He = (e, t) => l.promise(async () => {
497
+ let n = (await e.query(x(Y).where(g("digest", t)).descriptor))[0];
498
+ return n === void 0 ? null : X(n);
499
+ }), Ue = (e, t) => l.promise(async () => [...await e.query(x(Y).where(g("promptId", t)).orderBy("revision", "desc").descriptor)].sort((e, t) => (Number(t.revision) || 0) - (Number(e.revision) || 0)).map(X)), Z = "_voltro_ai_inferences", We = w(Z, {
500
+ id: v({ prefix: "aiinf" }),
501
+ tenantId: T().nullable(),
502
+ executionId: T(),
503
+ workflowName: T(),
504
+ runId: T().nullable(),
505
+ signalName: T(),
506
+ stepName: T(),
507
+ status: T().oneOf([
508
+ "pending",
509
+ "running",
510
+ "succeeded",
511
+ "failed"
512
+ ]).default("pending"),
513
+ kind: T().oneOf(["text", "object"]).default("text"),
514
+ provider: T(),
515
+ model: T(),
516
+ prompt: T(),
517
+ system: T().nullable(),
518
+ promptId: T().nullable(),
519
+ promptDigest: T().nullable(),
520
+ promptRevision: y().nullable(),
521
+ maxTokens: y().nullable(),
522
+ providerOptions: b().nullable(),
523
+ jsonSchema: b().nullable(),
524
+ result: b().nullable(),
525
+ errorMessage: T().nullable(),
526
+ attempts: y().default(0),
527
+ leaseUntil: E().nullable(),
528
+ claimedBy: T().nullable(),
529
+ enqueuedAt: E().default("now"),
530
+ startedAt: E().nullable(),
531
+ completedAt: E().nullable(),
532
+ durationMs: y().nullable()
533
+ }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), Ge = 5 * 6e4, Ke = 4, Q = (e, t) => {
534
+ let n = typeof e == "number" ? e : Number(e);
535
+ return Number.isFinite(n) ? Math.trunc(n) : t;
536
+ }, $ = (e) => e == null ? null : String(e), qe = (e) => ({
537
+ id: String(e.id),
538
+ tenantId: $(e.tenantId),
539
+ executionId: String(e.executionId),
540
+ workflowName: String(e.workflowName),
541
+ runId: $(e.runId),
542
+ signalName: String(e.signalName),
543
+ stepName: String(e.stepName),
544
+ kind: e.kind === "object" ? "object" : "text",
545
+ provider: String(e.provider),
546
+ model: String(e.model),
547
+ prompt: String(e.prompt ?? ""),
548
+ system: $(e.system),
549
+ promptId: $(e.promptId),
550
+ promptDigest: $(e.promptDigest),
551
+ promptRevision: e.promptRevision === null || e.promptRevision === void 0 ? null : Q(e.promptRevision, 0),
552
+ maxTokens: e.maxTokens === null || e.maxTokens === void 0 ? null : Q(e.maxTokens, 0),
553
+ providerOptions: e.providerOptions ?? null,
554
+ jsonSchema: e.jsonSchema ?? null,
555
+ attempts: Q(e.attempts, 0)
556
+ }), Je = (e) => {
557
+ let t = e.attempts + 1;
558
+ return t >= e.maxAttempts ? {
559
+ kind: "give-up",
560
+ attempts: t
561
+ } : {
562
+ kind: "retry",
563
+ attempts: t,
564
+ delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
565
+ };
566
+ }, Ye = (e) => `voltro.ai.infer:${e}`, Xe = (e, t) => `aiinf_${D("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
567
+ //#endregion
568
+ export { W as A, A as B, Oe as C, Ee as D, Te as E, L as F, fe as G, he as H, ge as I, oe as J, ie as K, P as L, N as M, F as N, H as O, O as P, M as R, je as S, ke as T, ve as U, j as V, pe as W, Ue as _, Je as a, G as b, qe as c, Ne as d, Le as f, Ie as g, He as h, We as i, I as j, we as k, ze as l, Me as m, Ke as n, Ye as o, Re as p, ae as q, Ge as r, Xe as s, Z as t, J as u, Y as v, De as w, Ae as x, Ve as y, me as z };