@voltro/ai 0.70.0 → 0.71.1

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,664 +0,0 @@
1
- import { c as e, o as t, r as n } from "./provider-RA0getTL.js";
2
- import { Output as r, experimental_transcribe as i, generateObject as a, generateText as o, jsonSchema as s, stepCountIs as c, tool as l } from "ai";
3
- import { Context as u, Effect as d, JSONSchema as ee, Metric as f, MetricBoundaries as te, Runtime as p, Schema as m, Stream as ne } from "effect";
4
- import { and as h, eq as g, generateId as _, gte as re, 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 ie } from "node:crypto";
6
- //#region src/tools.ts
7
- var ae = (e, t) => e(t), oe = Symbol.for("@voltro/ai/Tool"), se = (e) => ({
8
- ...e,
9
- [oe]: !0
10
- }), ce = (e) => typeof e == "object" && !!e && e[oe] === !0, le = (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)) ce(r) && r.execute === void 0 && r.handler === void 0 && (r.handler = t, n += 1);
15
- return n;
16
- }, ue = (e, t) => {
17
- let n = t ?? p.defaultRuntime;
18
- return p.runPromise(n)(e);
19
- }, de = (e, t, n) => n ? e.pipe(d.timeoutFail({
20
- duration: `${n} millis`,
21
- onTimeout: () => /* @__PURE__ */ Error(`tool '${t}' timed out`)
22
- })) : e, fe = (e, t, n) => {
23
- if (e.execute) return ue(de(ae(e.execute, t), e.name, e.timeoutMs), n.runtime);
24
- if (e.handler) {
25
- let r = e.handler, i = r(t, n);
26
- return d.isEffect(i) ? ue(de(i, e.name, e.timeoutMs), n.runtime) : i;
27
- }
28
- return Promise.reject(/* @__PURE__ */ Error(`tool '${e.name}' has neither execute nor handler`));
29
- }, pe = (e) => {
30
- let t = ee.make(e);
31
- return t && t.type === "object" ? t : {
32
- type: "object",
33
- properties: {},
34
- additionalProperties: !1
35
- };
36
- }, me = (e) => {
37
- let t = e.inputJsonSchema;
38
- return t === void 0 ? pe(e.input) : t.type === "object" ? t : {
39
- type: "object",
40
- properties: {},
41
- additionalProperties: !0
42
- };
43
- }, D = (e, t = { store: void 0 }) => {
44
- let n = {};
45
- for (let [r, i] of Object.entries(e)) n[i.name || r] = l({
46
- description: i.description,
47
- inputSchema: s(me(i)),
48
- execute: async (e) => {
49
- let n = await d.runPromise(m.decodeUnknown(i.input)(e)), r = await fe(i, n, t);
50
- return i.output ? d.runPromise(m.decodeUnknown(i.output)(r)) : r;
51
- }
52
- });
53
- return n;
54
- }, he = {
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
- }, O = {}, ge = (e) => {
100
- let t = O;
101
- return O = { ...e }, t;
102
- }, k = () => ({
103
- ...he,
104
- ...O
105
- }), A = (e) => {
106
- let t = k();
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
- }, j = (e) => typeof e.unit == "string", M = (e) => j(e) ? {
114
- unit: e.unit,
115
- input: e.input ?? 0,
116
- output: e.output ?? 0
117
- } : {
118
- unit: "tokens",
119
- input: e.inputTokens ?? 0,
120
- output: e.outputTokens ?? 0
121
- }, N = (e, t) => {
122
- let { unit: n, input: r, output: i } = M(e);
123
- if (t.actualCostUsd !== void 0) {
124
- let e = r + i, a = e > 0 ? r / e : 0;
125
- return {
126
- inputTokens: r,
127
- outputTokens: i,
128
- inputCostUsd: t.actualCostUsd * a,
129
- outputCostUsd: t.actualCostUsd * (1 - a),
130
- totalCostUsd: t.actualCostUsd,
131
- costSource: "gateway",
132
- unit: n
133
- };
134
- }
135
- if (n !== "tokens" && t.price === void 0) return {
136
- inputTokens: r,
137
- outputTokens: i,
138
- inputCostUsd: 0,
139
- outputCostUsd: 0,
140
- totalCostUsd: 0,
141
- costSource: "unpriced",
142
- unit: n
143
- };
144
- let a = t.price ?? A(t.model) ?? {
145
- inputPer1M: 0,
146
- outputPer1M: 0
147
- }, o = r / 1e6 * a.inputPer1M, s = i / 1e6 * a.outputPer1M;
148
- return {
149
- inputTokens: r,
150
- outputTokens: i,
151
- inputCostUsd: o,
152
- outputCostUsd: s,
153
- totalCostUsd: o + s,
154
- costSource: "estimated",
155
- unit: n
156
- };
157
- }, P = "_voltro_ai_usage", F = w(P, {
158
- id: v({ prefix: "aiu" }),
159
- tenantId: T().nullable(),
160
- provider: T(),
161
- model: T(),
162
- operation: T(),
163
- agent: T().nullable(),
164
- inputTokens: y().default(0),
165
- outputTokens: y().default(0),
166
- costMicroUsd: y().default(0),
167
- costSource: T().default("estimated"),
168
- unit: T().default("tokens"),
169
- promptId: T().nullable(),
170
- promptDigest: T().nullable(),
171
- promptRevision: y().nullable(),
172
- calledAt: E().default("now")
173
- }).index(["tenantId"]).index(["promptDigest"]), _e = (e) => {
174
- let t = e?.gateway?.cost, n = typeof t == "number" ? t : typeof t == "string" ? Number(t) : NaN;
175
- return Number.isFinite(n) ? n : void 0;
176
- }, ve = (e, t) => (S({
177
- source: "plugin",
178
- table: P,
179
- timeColumn: "calledAt",
180
- ttlMs: C(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
181
- }), d.promise(async () => {
182
- let n = N(t.usage, {
183
- model: t.model,
184
- ...t.price === void 0 ? {} : { price: t.price },
185
- ...t.actualCostUsd === void 0 ? {} : { actualCostUsd: t.actualCostUsd }
186
- });
187
- return await e.insert(P, {
188
- tenantId: t.tenantId ?? null,
189
- provider: t.provider,
190
- model: t.model,
191
- operation: t.operation,
192
- agent: t.agent ?? null,
193
- inputTokens: n.inputTokens,
194
- outputTokens: n.outputTokens,
195
- costMicroUsd: Math.round(n.totalCostUsd * 1e6),
196
- costSource: n.costSource,
197
- unit: n.unit,
198
- promptId: t.prompt?.promptId ?? null,
199
- promptDigest: t.prompt?.digest ?? null,
200
- promptRevision: t.prompt?.revision ?? null,
201
- calledAt: t.calledAt ?? /* @__PURE__ */ new Date()
202
- }), n;
203
- })), ye = (e, t = {}) => d.promise(async () => {
204
- let n = [
205
- ...t.tenantId === void 0 ? [] : [g("tenantId", t.tenantId)],
206
- ...t.since === void 0 ? [] : [re("calledAt", t.since)],
207
- ...t.promptDigest === void 0 ? [] : [g("promptDigest", t.promptDigest)]
208
- ], r = x(F), i = n.length === 0 ? r : r.where(n.length === 1 ? n[0] : h(...n));
209
- return (await e.query(i.descriptor)).reduce((e, t) => e + (Number(t.costMicroUsd) || 0), 0) / 1e6;
210
- }), I = class extends m.TaggedError()("AiBudgetExceeded", {
211
- tenantId: m.NullOr(m.String),
212
- limitUsd: m.Number,
213
- spentUsd: m.Number,
214
- attemptedUsd: m.Number
215
- }) {}, L = "_voltro_ai_budget", R = w(L, {
216
- id: v({ prefix: "aib" }),
217
- bucket: T().maxLength(191),
218
- tenantId: T().nullable(),
219
- reservedMicroUsd: y().default(0),
220
- updatedAt: E().default("now")
221
- }).unique("byAiBudgetBucket", ["bucket"]), be = (e, t) => `${e ?? "global"}::${t === void 0 ? "all" : String(t.getTime())}`, z = 32, xe = (e, t) => d.gen(function* () {
222
- S({
223
- source: "plugin",
224
- table: L,
225
- timeColumn: "updatedAt",
226
- ttlMs: C(process.env.VOLTRO_AI_USAGE_TTL_HOURS, 8760)
227
- });
228
- let n = t.addUsd ?? 0, r = Math.round(n * 1e6), i = Math.round(t.limitUsd * 1e6), a = be(t.tenantId, t.since), o = t.tenantId ?? null, s = (e) => new I({
229
- tenantId: o,
230
- limitUsd: t.limitUsd,
231
- spentUsd: e / 1e6,
232
- attemptedUsd: n
233
- }), c = yield* d.promise(async () => {
234
- for (let t = 0; t < z; t++) {
235
- t > 0 && await new Promise((e) => setTimeout(e, t));
236
- let n = (await e.query(x(R).where(g("bucket", a)).descriptor))[0], s = n && Number(n.reservedMicroUsd) || 0;
237
- if (s + r > i) return {
238
- ok: !1,
239
- reservedMicro: s
240
- };
241
- if (r === 0) return { ok: !0 };
242
- if (n) {
243
- if (await e.updateMany("_voltro_ai_budget", {
244
- reservedMicroUsd: s + r,
245
- updatedAt: /* @__PURE__ */ new Date()
246
- }, { where: h(g("id", String(n.id)), g("reservedMicroUsd", s)) }) === 1) return { ok: !0 };
247
- } else {
248
- let t = _({
249
- kind: "typeid",
250
- prefix: "aib"
251
- }, L), n = await e.insertIgnore(L, {
252
- id: t,
253
- bucket: a,
254
- tenantId: o,
255
- reservedMicroUsd: r,
256
- updatedAt: /* @__PURE__ */ new Date()
257
- }, { conflictColumns: ["bucket"] });
258
- if (String(n.id) === t) return { ok: !0 };
259
- }
260
- }
261
- throw Error(`requireAiBudget: contention on bucket '${a}' exceeded ${z} attempts`);
262
- });
263
- if (!c.ok) return yield* d.fail(s(c.reservedMicro));
264
- }), Se = te.exponential({
265
- start: .001,
266
- factor: 2,
267
- count: 16
268
- }), B = f.counter("voltro_ai_calls_total", { description: "Total AI provider calls (generate + stream)." }), Ce = f.counter("voltro_ai_call_errors_total", { description: "AI provider calls that errored." }), V = f.histogram("voltro_ai_call_duration_seconds", Se, "AI provider call duration in seconds."), we = f.counter("voltro_ai_input_tokens_total", {
269
- description: "Total prompt (input) tokens across AI calls.",
270
- incremental: !0
271
- }), Te = f.counter("voltro_ai_output_tokens_total", {
272
- description: "Total completion (output) tokens across AI calls.",
273
- incremental: !0
274
- }), Ee = f.counter("voltro_ai_cost_microusd_total", {
275
- description: "Total estimated AI spend in micro-USD (USD × 1e6).",
276
- incremental: !0
277
- }), H = (e, t) => ({
278
- provider: e.name,
279
- model: e.model ?? e.name,
280
- operation: t
281
- }), U = (e, t, n) => e.pipe(d.tagMetrics("provider", t.provider), d.tagMetrics("model", t.model), d.tagMetrics("operation", t.operation), d.tagMetrics("status", n)), De = (e, t) => {
282
- let n = t.inputTokens ?? 0, r = t.outputTokens ?? 0, i = N({
283
- inputTokens: n,
284
- outputTokens: r
285
- }, { model: e.model }), a = Math.round(i.totalCostUsd * 1e6);
286
- return d.all([
287
- U(f.incrementBy(we, n), e, "ok"),
288
- U(f.incrementBy(Te, r), e, "ok"),
289
- U(f.incrementBy(Ee, a), e, "ok")
290
- ], { discard: !0 });
291
- }, W = (e, t, n) => d.gen(function* () {
292
- let r = yield* d.clockWith((e) => e.currentTimeMillis);
293
- return yield* n.pipe(d.tap((n) => De(e, t(n))), d.tap(() => U(f.increment(B), e, "ok").pipe(d.zipRight(d.clockWith((e) => e.currentTimeMillis).pipe(d.flatMap((t) => U(f.update(V, (t - r) / 1e3), e, "ok")))))), d.tapError(() => U(f.increment(B), e, "error").pipe(d.zipRight(U(f.increment(Ce), e, "error")), d.zipRight(d.clockWith((e) => e.currentTimeMillis).pipe(d.flatMap((t) => U(f.update(V, (t - r) / 1e3), e, "error")))))), d.withSpan("voltro.ai.call", { attributes: {
294
- "ai.provider": e.provider,
295
- "ai.model": e.model,
296
- "ai.operation": e.operation
297
- } }));
298
- }), Oe = (e, t) => {
299
- let n = Date.now();
300
- return t.pipe(ne.tap((t) => t._tag === "done" ? U(f.increment(B), e, "ok").pipe(d.zipRight(U(f.update(V, (Date.now() - n) / 1e3), e, "ok")), d.zipRight(De(e, t.usage ?? {}))) : t._tag === "error" ? U(f.increment(B), e, "error").pipe(d.zipRight(U(f.increment(Ce), e, "error")), d.zipRight(U(f.update(V, (Date.now() - n) / 1e3), e, "error"))) : d.void), ne.withSpan("voltro.ai.call", { attributes: {
301
- "ai.provider": e.provider,
302
- "ai.model": e.model,
303
- "ai.operation": e.operation
304
- } }));
305
- }, G = class extends m.TaggedError()("AiError", {
306
- reason: m.Literal("generation", "decode"),
307
- message: m.String
308
- }) {}, K = (e, t, n) => {
309
- let r = [e, ...t ?? []], i = (e) => n(r[e]).pipe(d.catchTag("AiError", (t) => t.reason === "generation" && e + 1 < r.length ? i(e + 1) : d.fail(t)));
310
- return i(0);
311
- }, ke = (e) => d.gen(function* () {
312
- let r = e.tools === void 0 ? void 0 : yield* d.runtime(), i = e.tools === void 0 || r === void 0 ? void 0 : D(e.tools, {
313
- store: void 0,
314
- ...e.toolContext,
315
- runtime: r
316
- });
317
- return yield* K(e.provider ?? n(), e.fallbacks, (n) => W(H(n, "generateText"), (e) => e.usage, d.tryPromise({
318
- try: async () => {
319
- let r = t(n), a = await o({
320
- model: r,
321
- prompt: e.prompt,
322
- ...i === void 0 ? {} : {
323
- tools: i,
324
- stopWhen: c(e.maxSteps ?? 8)
325
- },
326
- ...e.system === void 0 ? {} : { system: e.system },
327
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
328
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
329
- }), s = i !== void 0 && a.totalUsage !== void 0 ? a.totalUsage : a.usage;
330
- return {
331
- text: a.text,
332
- usage: {
333
- inputTokens: s.inputTokens,
334
- outputTokens: s.outputTokens,
335
- totalTokens: s.totalTokens
336
- },
337
- providerMetadata: a.providerMetadata
338
- };
339
- },
340
- catch: (e) => new G({
341
- reason: "generation",
342
- message: String(e?.message ?? e)
343
- })
344
- })));
345
- }), q = (e, t) => d.gen(function* () {
346
- let n = ee.make(e);
347
- if (n?.type !== "object") {
348
- let e = n?.anyOf === void 0 ? `type:${JSON.stringify(n?.type ?? null)}` : "anyOf (e.g. Schema.Struct({}) or a union)";
349
- return yield* d.fail(new G({
350
- reason: "generation",
351
- 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(...) })).`
352
- }));
353
- }
354
- return n;
355
- }), Ae = (e, t) => q(e, t), je = (e) => K(e.provider ?? n(), e.fallbacks, (n) => W(H(n, "generateObject"), (e) => e.usage, d.gen(function* () {
356
- let r = t(n), i = yield* d.tryPromise({
357
- try: () => a({
358
- model: r,
359
- schema: s(e.jsonSchema),
360
- prompt: e.prompt,
361
- ...e.system === void 0 ? {} : { system: e.system },
362
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
363
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
364
- }),
365
- catch: (e) => new G({
366
- reason: "generation",
367
- message: String(e?.message ?? e)
368
- })
369
- });
370
- return {
371
- object: i.object,
372
- usage: {
373
- inputTokens: i.usage.inputTokens,
374
- outputTokens: i.usage.outputTokens,
375
- totalTokens: i.usage.totalTokens
376
- },
377
- providerMetadata: i.providerMetadata
378
- };
379
- }))), Me = (e) => d.gen(function* () {
380
- let t = yield* je({
381
- jsonSchema: yield* q(e.schema, "generateObject"),
382
- prompt: e.prompt,
383
- ...e.system === void 0 ? {} : { system: e.system },
384
- ...e.provider === void 0 ? {} : { provider: e.provider },
385
- ...e.fallbacks === void 0 ? {} : { fallbacks: e.fallbacks },
386
- ...e.maxTokens === void 0 ? {} : { maxTokens: e.maxTokens },
387
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
388
- }), n = yield* m.decodeUnknown(e.schema)(t.object).pipe(d.mapError((e) => new G({
389
- reason: "decode",
390
- message: `model output failed schema decode: ${String(e)}`
391
- })));
392
- return {
393
- ...t,
394
- object: n
395
- };
396
- }), Ne = (e) => d.gen(function* () {
397
- let i = yield* d.runtime(), a = yield* q(e.schema, "generateObjectWithTools"), l = {
398
- store: void 0,
399
- ...e.toolContext,
400
- runtime: i
401
- }, u = D(e.tools, l);
402
- return yield* K(e.provider ?? n(), e.fallbacks, (n) => W(H(n, "generateObjectWithTools"), (e) => e.usage, d.gen(function* () {
403
- let i = t(n), l = yield* d.tryPromise({
404
- try: () => o({
405
- model: i,
406
- prompt: e.prompt,
407
- tools: u,
408
- stopWhen: c(e.maxSteps ?? 8),
409
- output: r.object({ schema: s(a) }),
410
- ...e.system === void 0 ? {} : { system: e.system },
411
- ...e.maxTokens === void 0 ? {} : { maxOutputTokens: e.maxTokens },
412
- ...e.providerOptions === void 0 ? {} : { providerOptions: e.providerOptions }
413
- }),
414
- catch: (e) => new G({
415
- reason: "generation",
416
- message: String(e?.message ?? e)
417
- })
418
- });
419
- return {
420
- object: yield* m.decodeUnknown(e.schema)(l.output).pipe(d.mapError((e) => new G({
421
- reason: "decode",
422
- message: `model output failed schema decode: ${String(e)}`
423
- }))),
424
- usage: {
425
- inputTokens: l.usage.inputTokens,
426
- outputTokens: l.usage.outputTokens,
427
- totalTokens: l.usage.totalTokens
428
- },
429
- providerMetadata: l.providerMetadata
430
- };
431
- })));
432
- }), Pe = class extends u.Tag("@voltro/AiService")() {}, Fe = {
433
- generateText: (e) => ke(e),
434
- generateObject: (e) => Me(e)
435
- }, Ie = async (e, t) => {
436
- if ("bytes" in e) return {
437
- audio: e.bytes,
438
- mediaType: e.mediaType
439
- };
440
- if ("url" in e) {
441
- let t = await fetch(e.url);
442
- if (!t.ok) throw Error(`transcribe: GET ${e.url} answered ${t.status}.`);
443
- let n = t.headers.get("content-type") ?? void 0;
444
- return {
445
- audio: new Uint8Array(await t.arrayBuffer()),
446
- ...n === void 0 ? {} : { mediaType: n }
447
- };
448
- }
449
- if (t === void 0) throw Error("transcribe: `source.storageRef` needs a `resolveRef` to turn the reference into bytes.\n → pass `resolveRef: (ref) => storage.read(ref)`. It is injected rather than imported so @voltro/ai does not depend on storage; the app owns tenancy and signing for that read.");
450
- let { bytes: n, mediaType: r } = await t(e.storageRef);
451
- return {
452
- audio: n,
453
- mediaType: r
454
- };
455
- }, Le = (e) => {
456
- if (!Array.isArray(e) || e.length === 0) return;
457
- let t = [];
458
- for (let n of e) {
459
- let e = typeof n.startSecond == "number" ? n.startSecond : typeof n.start == "number" ? n.start : void 0, r = typeof n.endSecond == "number" ? n.endSecond : typeof n.end == "number" ? n.end : void 0, i = typeof n.text == "string" ? n.text : void 0;
460
- if (e === void 0 || r === void 0 || i === void 0) continue;
461
- let a = typeof n.speaker == "string" ? n.speaker : void 0;
462
- t.push({
463
- start: e,
464
- end: r,
465
- text: i,
466
- ...a === void 0 ? {} : { speaker: a }
467
- });
468
- }
469
- return t.length > 0 ? t : void 0;
470
- }, Re = (t) => {
471
- let r = t.provider ?? n();
472
- return W(H(r, "transcribe"), () => ({}), d.tryPromise({
473
- try: async () => {
474
- let { audio: n, mediaType: a } = await Ie(t.source, t.resolveRef), o = await i({
475
- model: e(r),
476
- audio: n,
477
- ...a === void 0 ? {} : { mediaType: a },
478
- ...t.providerOptions === void 0 ? {} : { providerOptions: t.providerOptions }
479
- }), s = t.timestamps === "none" ? void 0 : Le(o.segments);
480
- return {
481
- text: o.text,
482
- ...o.language === void 0 ? {} : { language: o.language },
483
- ...o.durationInSeconds === void 0 ? {} : { durationSec: o.durationInSeconds },
484
- ...s === void 0 ? {} : { segments: s },
485
- ...o.providerMetadata === void 0 ? {} : { providerMetadata: o.providerMetadata }
486
- };
487
- },
488
- catch: (e) => new G({
489
- reason: "generation",
490
- message: String(e?.message ?? e)
491
- })
492
- }));
493
- }, ze = (e) => `sha256:${ie("sha256").update(e).digest("hex").slice(0, 16)}`, Be = class extends m.TaggedError()("PromptRenderError", {
494
- promptId: m.String,
495
- missing: m.Array(m.String),
496
- message: m.String
497
- }) {}, Ve = /\{\{\s*([A-Za-z0-9_.]+)\s*\}\}/g, He = (e) => {
498
- let t = /* @__PURE__ */ new Set();
499
- for (let n of e.matchAll(Ve)) {
500
- let e = n[1];
501
- e !== void 0 && t.add(e);
502
- }
503
- return [...t];
504
- }, Ue = (e, t) => ze(`${e.length}:${e}${(t ?? "").length}:${t ?? ""}`), We = (e) => {
505
- let t = Ue(e.template, e.system), n = He(e.template);
506
- return {
507
- ...e,
508
- digest: t,
509
- variables: n,
510
- render: (r = {}) => d.suspend(() => {
511
- let i = n.filter((e) => r[e] === void 0);
512
- if (i.length > 0) return d.fail(new Be({
513
- promptId: e.id,
514
- missing: i,
515
- message: `prompt '${e.id}' needs ${i.map((e) => `{{${e}}}`).join(", ")}, which ${i.length === 1 ? "was" : "were"} not supplied.`
516
- }));
517
- let a = e.template.replace(Ve, (e, t) => String(r[t]));
518
- return d.succeed({
519
- promptId: e.id,
520
- digest: t,
521
- ...e.label === void 0 ? {} : { label: e.label },
522
- prompt: a,
523
- ...e.system === void 0 ? {} : { system: e.system },
524
- definition: e
525
- });
526
- })
527
- };
528
- }, Ge = (e) => typeof e == "object" && !!e && typeof e.prompt == "string" && typeof e.digest == "string" && typeof e.promptId == "string", J = "_voltro_prompts", Y = w(J, {
529
- id: v({ prefix: "prm" }),
530
- promptId: T().maxLength(191),
531
- digest: T().maxLength(191),
532
- revision: y().default(1),
533
- label: T().nullable(),
534
- template: T().nullable(),
535
- system: T().nullable(),
536
- templateChars: y().default(0),
537
- firstSeenAt: E().default("now"),
538
- lastUsedAt: E().default("now")
539
- }).unique("byPromptsVersion", ["promptId", "digest"]).index(["promptId"]), Ke = 8760, qe = () => {
540
- S({
541
- source: "framework",
542
- table: J,
543
- timeColumn: "lastUsedAt",
544
- ttlMs: C(process.env.VOLTRO_AI_PROMPTS_TTL_HOURS, Ke),
545
- envVar: "VOLTRO_AI_PROMPTS_TTL_HOURS",
546
- label: "ai prompt versions"
547
- });
548
- }, X = (e) => ({
549
- promptId: String(e.promptId),
550
- digest: String(e.digest),
551
- revision: Number(e.revision) || 1,
552
- label: e.label ?? null,
553
- template: e.template ?? null,
554
- system: e.system ?? null,
555
- firstSeenAt: e.firstSeenAt ?? null,
556
- lastUsedAt: e.lastUsedAt ?? null
557
- }), Je = (e, t) => d.gen(function* () {
558
- qe();
559
- let n = t.digest ?? We(t).digest;
560
- return yield* d.promise(async () => {
561
- let r = (await e.query(x(Y).where(h(g("promptId", t.id), g("digest", n))).descriptor))[0];
562
- if (r !== void 0) {
563
- let t = /* @__PURE__ */ new Date();
564
- return await e.updateMany(J, { lastUsedAt: t }, { where: g("id", String(r.id)) }), X({
565
- ...r,
566
- lastUsedAt: t
567
- });
568
- }
569
- 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 = {
570
- id: _({
571
- kind: "typeid",
572
- prefix: "prm"
573
- }, J),
574
- promptId: t.id,
575
- digest: n,
576
- revision: i,
577
- label: t.label ?? null,
578
- template: t.template,
579
- system: t.system ?? null,
580
- templateChars: t.template.length,
581
- firstSeenAt: a,
582
- lastUsedAt: a
583
- };
584
- return X(await e.insertIgnore(J, o, { conflictColumns: ["promptId", "digest"] }) ?? o);
585
- });
586
- }), Ye = (e, t) => d.promise(async () => {
587
- let n = (await e.query(x(Y).where(g("digest", t)).descriptor))[0];
588
- return n === void 0 ? null : X(n);
589
- }), Xe = (e, t) => d.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", Ze = w(Z, {
590
- id: v({ prefix: "aiinf" }),
591
- tenantId: T().nullable(),
592
- executionId: T(),
593
- workflowName: T(),
594
- runId: T().nullable(),
595
- signalName: T(),
596
- stepName: T(),
597
- status: T().oneOf([
598
- "pending",
599
- "running",
600
- "succeeded",
601
- "failed"
602
- ]).default("pending"),
603
- kind: T().oneOf([
604
- "text",
605
- "object",
606
- "transcription"
607
- ]).default("text"),
608
- provider: T(),
609
- model: T(),
610
- prompt: T(),
611
- system: T().nullable(),
612
- promptId: T().nullable(),
613
- promptDigest: T().nullable(),
614
- promptRevision: y().nullable(),
615
- maxTokens: y().nullable(),
616
- providerOptions: b().nullable(),
617
- jsonSchema: b().nullable(),
618
- transcription: b().nullable(),
619
- result: b().nullable(),
620
- errorMessage: T().nullable(),
621
- attempts: y().default(0),
622
- leaseUntil: E().nullable(),
623
- claimedBy: T().nullable(),
624
- enqueuedAt: E().default("now"),
625
- startedAt: E().nullable(),
626
- completedAt: E().nullable(),
627
- durationMs: y().nullable()
628
- }).index(["status", "enqueuedAt"]).index(["status", "leaseUntil"]).index(["executionId"]).index(["tenantId"]), Qe = 3e5, $e = 4, Q = (e, t) => {
629
- let n = typeof e == "number" ? e : Number(e);
630
- return Number.isFinite(n) ? Math.trunc(n) : t;
631
- }, $ = (e) => e == null ? null : String(e), et = (e) => ({
632
- id: String(e.id),
633
- tenantId: $(e.tenantId),
634
- executionId: String(e.executionId),
635
- workflowName: String(e.workflowName),
636
- runId: $(e.runId),
637
- signalName: String(e.signalName),
638
- stepName: String(e.stepName),
639
- kind: e.kind === "object" ? "object" : e.kind === "transcription" ? "transcription" : "text",
640
- provider: String(e.provider),
641
- model: String(e.model),
642
- prompt: String(e.prompt ?? ""),
643
- system: $(e.system),
644
- promptId: $(e.promptId),
645
- promptDigest: $(e.promptDigest),
646
- promptRevision: e.promptRevision === null || e.promptRevision === void 0 ? null : Q(e.promptRevision, 0),
647
- maxTokens: e.maxTokens === null || e.maxTokens === void 0 ? null : Q(e.maxTokens, 0),
648
- providerOptions: e.providerOptions ?? null,
649
- jsonSchema: e.jsonSchema ?? null,
650
- transcription: e.transcription ?? null,
651
- attempts: Q(e.attempts, 0)
652
- }), tt = (e) => {
653
- let t = e.attempts + 1;
654
- return t >= e.maxAttempts ? {
655
- kind: "give-up",
656
- attempts: t
657
- } : {
658
- kind: "retry",
659
- attempts: t,
660
- delayMs: e.retryAfterMs !== void 0 && e.retryAfterMs > 0 ? e.retryAfterMs : Math.min(e.baseDelayMs * 2 ** (t - 1), e.maxDelayMs)
661
- };
662
- }, nt = (e) => `voltro.ai.infer:${e}`, rt = (e, t) => `aiinf_${ie("sha256").update(`${e}\u0000${t}`).digest("hex").slice(0, 40)}`;
663
- //#endregion
664
- export { Oe as A, _e as B, Fe as C, ke as D, Ne as E, he as F, ve as G, k as H, R as I, D as J, xe as K, ye as L, L as M, P as N, Ae as O, I as P, F as R, Pe as S, je as T, M as U, j as V, A as W, ce as X, se as Y, le as Z, Xe as _, tt as a, Re as b, et as c, Be as d, We as f, Ue as g, Ye as h, Ze as i, W as j, H as k, Ke as l, ze as m, $e as n, nt as o, Ge as p, ge as q, Qe as r, rt as s, Z as t, J as u, Y as v, Me as w, G as x, Je as y, N as z };