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