@voltro/ai 0.85.0 → 0.87.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/THIRD-PARTY-NOTICES.md +4723 -519
  3. package/dist/agent.js +64 -2
  4. package/dist/agentConstants.js +4 -0
  5. package/dist/agentExecutor.js +55 -0
  6. package/dist/aiSettings.js +11 -0
  7. package/dist/api.js +199 -0
  8. package/dist/appTools.js +80 -0
  9. package/dist/budget.js +201 -0
  10. package/dist/callEvidence.js +51 -0
  11. package/dist/copilot.js +126 -0
  12. package/dist/cost.js +242 -0
  13. package/dist/embed.js +41 -0
  14. package/dist/embeddingProvider.js +69 -0
  15. package/dist/eval.js +130 -0
  16. package/dist/events.d.ts +4 -0
  17. package/dist/events.js +81 -2
  18. package/dist/executableModalities.js +13 -0
  19. package/dist/gateway.js +58 -0
  20. package/dist/gatewayCatalog.js +47 -0
  21. package/dist/gatewayMedia.js +88 -0
  22. package/dist/index.d.ts +60 -2
  23. package/dist/index.js +42 -2750
  24. package/dist/inferenceDispatch.js +493 -0
  25. package/dist/inferenceQueue.js +96 -0
  26. package/dist/jsonOutputValidation.js +27 -0
  27. package/dist/mcpClient.js +332 -0
  28. package/dist/mcpTools.js +80 -0
  29. package/dist/media.js +182 -0
  30. package/dist/mediaBytes.js +19 -0
  31. package/dist/mediaCall.js +13 -0
  32. package/dist/mediaTaskProvider.js +16 -0
  33. package/dist/middleware.js +32 -0
  34. package/dist/observe.js +52 -0
  35. package/dist/prompts.js +103 -0
  36. package/dist/provider.js +319 -0
  37. package/dist/realtimeEvent.js +97 -0
  38. package/dist/realtimeSession.js +154 -0
  39. package/dist/rerank.js +61 -0
  40. package/dist/resumableStream.js +321 -0
  41. package/dist/retrieveReranked.js +16 -0
  42. package/dist/runAndPersist.js +147 -0
  43. package/dist/semanticCache.js +66 -0
  44. package/dist/speechProvider.js +16 -0
  45. package/dist/streamRegistry.js +14 -0
  46. package/dist/streamText.js +170 -0
  47. package/dist/streamTranscribe.js +74 -0
  48. package/dist/streamWakeups.js +44 -0
  49. package/dist/structuredEvidence.js +48 -0
  50. package/dist/test.js +1 -1
  51. package/dist/threads.js +92 -0
  52. package/dist/tools.js +68 -0
  53. package/dist/transcribe.js +64 -0
  54. package/dist/transcriptionEvent.js +46 -0
  55. package/dist/workflow.d.ts +2 -0
  56. package/dist/workflow.js +115 -110
  57. package/package.json +6 -5
  58. package/dist/agentDescriptor-DhoiXVqO.js +0 -63
  59. package/dist/agentEvent-Bl4egdM5.js +0 -211
  60. package/dist/inferenceQueue-DcEulZep.js +0 -1077
  61. package/dist/provider-BnemgE4D.js +0 -409
@@ -0,0 +1,147 @@
1
+ import { providerFromEnv as e } from "./provider.js";
2
+ import { recordAiUsageBestEffort as t } from "./cost.js";
3
+ import { streamText as n } from "./streamText.js";
4
+ import { AGENT_MESSAGES_TABLE as r, AGENT_THREADS_TABLE as i } from "./agentConstants.js";
5
+ import { Effect as a, Stream as o } from "effect";
6
+ //#region src/runAndPersist.ts
7
+ var s = (e) => [...e].sort((e, t) => e.order - t.order || e.stepOrder - t.stepOrder).filter((e) => !e.streaming && e.content.length > 0 && (e.role === "user" || e.role === "assistant")).map((e) => e.role === "user" ? {
8
+ role: "user",
9
+ content: e.content
10
+ } : {
11
+ role: "assistant",
12
+ content: e.content
13
+ }), c = (e, t) => a.promise(async () => {
14
+ let n = await e.insert(r, {
15
+ threadId: t.threadId,
16
+ tenantId: t.tenantId ?? null,
17
+ role: "assistant",
18
+ content: "",
19
+ streaming: !0,
20
+ order: t.order,
21
+ stepOrder: 0,
22
+ parts: [],
23
+ createdAt: /* @__PURE__ */ new Date()
24
+ });
25
+ return await e.update(i, t.threadId, { updatedAt: /* @__PURE__ */ new Date() }).catch(() => null), n.id;
26
+ }), l = (e, t, n) => a.promise(async () => {
27
+ await e.update(r, t, {
28
+ parts: n,
29
+ content: u(n)
30
+ });
31
+ }), u = (e) => e.filter((e) => e.type === "text").map((e) => e.text).join(""), d = (i, s) => a.gen(function* () {
32
+ let d = s.provider ?? (yield* a.try({
33
+ try: () => e(),
34
+ catch: (e) => e instanceof Error ? e : Error(String(e))
35
+ })), f = yield* c(i, {
36
+ threadId: s.threadId,
37
+ tenantId: s.tenantId ?? null,
38
+ order: s.order
39
+ }), p = "", m = "", h = /* @__PURE__ */ new Map(), g = [], _ = [], v = [], y = 0, b = null, x, S = s.throttleMs ?? 100, C = () => {
40
+ let e = [];
41
+ p.length > 0 && e.push({
42
+ type: "reasoning",
43
+ text: p
44
+ }), m.length > 0 && e.push({
45
+ type: "text",
46
+ text: m
47
+ });
48
+ for (let t of h.values()) e.push(t);
49
+ for (let t of g) e.push(t);
50
+ for (let t of _) e.push(t);
51
+ for (let t of v) e.push(t);
52
+ return e;
53
+ }, w = (e) => {
54
+ let t = Date.now();
55
+ return !e && t - y < S ? a.void : (y = t, l(i, f, C()));
56
+ };
57
+ yield* n({
58
+ prompt: s.prompt,
59
+ ...s.messages === void 0 ? {} : { messages: s.messages },
60
+ ...s.system === void 0 ? {} : { system: s.system },
61
+ ...s.tools === void 0 ? {} : { tools: s.tools },
62
+ provider: d,
63
+ ...s.maxSteps === void 0 ? {} : { maxSteps: s.maxSteps },
64
+ ...s.toolContext === void 0 ? {} : { toolContext: s.toolContext },
65
+ ...s.providerOptions === void 0 ? {} : { providerOptions: s.providerOptions }
66
+ }).pipe(o.runForEach((e) => a.gen(function* () {
67
+ switch (e._tag) {
68
+ case "token":
69
+ m += e.text, yield* w(!1);
70
+ break;
71
+ case "toolCall":
72
+ h.set(e.id, {
73
+ type: "tool",
74
+ toolCallId: e.id,
75
+ toolName: e.name,
76
+ state: "input-available",
77
+ input: e.input,
78
+ ...e.execution === void 0 ? {} : { execution: e.execution }
79
+ }), yield* w(!0);
80
+ break;
81
+ case "toolResult": {
82
+ let t = h.get(e.id);
83
+ h.set(e.id, {
84
+ type: "tool",
85
+ toolCallId: e.id,
86
+ toolName: e.name,
87
+ state: e.error ? "output-error" : "output-available",
88
+ input: t?.input,
89
+ output: e.output,
90
+ ...e.error ? { errorText: e.error } : {}
91
+ }), yield* w(!0);
92
+ break;
93
+ }
94
+ case "reasoning":
95
+ p += e.text, yield* w(!1);
96
+ break;
97
+ case "source": {
98
+ let { _tag: t, ...n } = e;
99
+ g.push({
100
+ type: t,
101
+ ...n
102
+ }), yield* w(!0);
103
+ break;
104
+ }
105
+ case "file": {
106
+ let { _tag: t, ...n } = e;
107
+ _.push({
108
+ type: t,
109
+ ...n
110
+ }), yield* w(!0);
111
+ break;
112
+ }
113
+ case "stepMetadata": {
114
+ let { _tag: t, ...n } = e;
115
+ v.push({
116
+ type: t,
117
+ ...n
118
+ }), yield* w(!0);
119
+ break;
120
+ }
121
+ case "error":
122
+ b = e.message;
123
+ break;
124
+ case "done": x = e.usage;
125
+ }
126
+ })));
127
+ let T = C();
128
+ return yield* a.promise(() => i.update(r, f, {
129
+ parts: T,
130
+ content: u(T),
131
+ streaming: !1
132
+ })), s.recordUsage !== !1 && x !== void 0 && (yield* t(i, {
133
+ tenantId: s.tenantId ?? null,
134
+ provider: d.name,
135
+ model: d.model ?? "unknown",
136
+ operation: "agent.turn",
137
+ agent: s.agent ?? null,
138
+ requestId: f,
139
+ usage: {
140
+ inputTokens: x.inputTokens,
141
+ outputTokens: x.outputTokens,
142
+ ...x.totalTokens === void 0 ? {} : { totalTokens: x.totalTokens }
143
+ }
144
+ })), b ? yield* a.fail(Error(b)) : u(T);
145
+ });
146
+ //#endregion
147
+ export { c as appendStreamingMessage, s as historyToModelMessages, l as patchStreamingMessage, d as runAssistant };
@@ -0,0 +1,66 @@
1
+ import { generateObject as e, generateText as t } from "./api.js";
2
+ import { embed as n } from "./embed.js";
3
+ import { Effect as r, Option as i } from "effect";
4
+ import { rowDep as a, tableDep as o } from "@voltro/cache";
5
+ //#region src/semanticCache.ts
6
+ var s = {
7
+ inputTokens: 0,
8
+ outputTokens: 0,
9
+ totalTokens: 0
10
+ }, c = .95, l = (e, t) => t === void 0 ? e : `${t}\n\n${e}`, u = (e, t, n) => e.lookup(t, { threshold: n }).pipe(r.catchTag("CacheError", () => r.succeed(i.none()))), d = (e, t, n, i) => e.put(t, n, {
11
+ deps: i.deps,
12
+ ...i.ttlMs === void 0 ? {} : { ttlMs: i.ttlMs }
13
+ }).pipe(r.catchTag("CacheError", () => r.void)), f = (e, a, o) => r.gen(function* () {
14
+ if (e.messages !== void 0 || e.prompt === void 0) {
15
+ let n = yield* t(e);
16
+ return {
17
+ value: n.text,
18
+ cached: !1,
19
+ usage: n.usage
20
+ };
21
+ }
22
+ let r = o.embed ?? n, f = a.threshold ?? c, p = yield* r(l(e.prompt, e.system)), m = yield* u(o.cache, p, f);
23
+ if (i.isSome(m)) return {
24
+ value: m.value,
25
+ cached: !0,
26
+ usage: s
27
+ };
28
+ let h = yield* t(e);
29
+ return yield* d(o.cache, p, h.text, a), {
30
+ value: h.text,
31
+ cached: !1,
32
+ usage: h.usage
33
+ };
34
+ }), p = (t, a, o) => r.gen(function* () {
35
+ let r = o.embed ?? n, f = a.threshold ?? c, p = yield* r(l(t.prompt, t.system)), m = yield* u(o.cache, p, f);
36
+ if (i.isSome(m)) return {
37
+ value: m.value,
38
+ cached: !0,
39
+ usage: s
40
+ };
41
+ let h = yield* e(t);
42
+ return yield* d(o.cache, p, h.object, a), {
43
+ value: h.object,
44
+ cached: !1,
45
+ usage: h.usage
46
+ };
47
+ }), m = (e) => {
48
+ let t = /* @__PURE__ */ new Set(), n = async (n) => {
49
+ let r = await e.query(n);
50
+ t.add(o(n.table));
51
+ for (let e of r) {
52
+ let r = e.id;
53
+ r != null && t.add(a(n.table, String(r)));
54
+ }
55
+ return r;
56
+ };
57
+ return {
58
+ store: new Proxy(e, { get(e, t, r) {
59
+ return t === "query" ? n : Reflect.get(e, t, r);
60
+ } }),
61
+ deps: () => [...t],
62
+ reset: () => t.clear()
63
+ };
64
+ };
65
+ //#endregion
66
+ export { m as recordReads, p as semanticGenerateObject, f as semanticGenerateText };
@@ -0,0 +1,16 @@
1
+ //#region src/speechProvider.ts
2
+ var e = Symbol.for("@voltro/ai/speechProviders"), t = globalThis, n = () => t[e] ?? (t[e] = /* @__PURE__ */ new Map()), r = [
3
+ "mock",
4
+ "openai",
5
+ "gateway",
6
+ "anthropic"
7
+ ], i = (e, t, i = {}) => {
8
+ if (r.includes(e) && i.replaceBuiltin !== !0) throw Error(`registerSpeechProvider: '${e}' is a built-in provider name.\n Shadowing one by accident would make the same config mean different things depending on which module loaded first.
9
+ → if you meant it, say so: registerSpeechProvider('${e}', provider, { replaceBuiltin: true }). That is the right call when the name is not yours to choose — a gateway model id's provider segment, say, that your stored rows already carry.
10
+ → otherwise pick another name.`);
11
+ n().set(e, t);
12
+ }, a = (e) => r.includes(e) && n().has(e), o = (e) => n().get(e), s = () => [...n().keys()].sort(), c = () => {
13
+ n().clear();
14
+ };
15
+ //#endregion
16
+ export { r as BUILTIN_SPEECH_PROVIDERS, c as clearSpeechProviders, i as registerSpeechProvider, s as registeredSpeechProviders, a as replacesBuiltinSpeechProvider, o as speechProvider };
@@ -0,0 +1,14 @@
1
+ //#region src/streamRegistry.ts
2
+ var e = /* @__PURE__ */ new Map(), t = (t) => {
3
+ let n = e.get(t);
4
+ if (n) return n;
5
+ let r = new AbortController();
6
+ return e.set(t, r), r;
7
+ }, n = (t) => {
8
+ let n = e.get(t);
9
+ return n ? (e.delete(t), n.abort(), !0) : !1;
10
+ }, r = (t) => e.has(t), i = (t) => {
11
+ e.delete(t);
12
+ }, a = () => e.size;
13
+ //#endregion
14
+ export { a as activeStreamCount, n as cancelStream, r as isStreamActive, t as registerStream, i as unregisterStream };
@@ -0,0 +1,170 @@
1
+ import { providerFromEnv as e, resolveModel as t } from "./provider.js";
2
+ import { buildSdkTools as n } from "./tools.js";
3
+ import { aiCallAttributes as r, observeStream as i } from "./observe.js";
4
+ import { registerStream as a, unregisterStream as o } from "./streamRegistry.js";
5
+ import { smoothStream as s, stepCountIs as c, streamText as l } from "ai";
6
+ import { Duration as u, Effect as d, Stream as f } from "effect";
7
+ //#region src/streamText.ts
8
+ var p = (e) => {
9
+ let t = e?.name, n = String(e?.message ?? e ?? "");
10
+ return t === "AbortError" || t === "TimeoutError" || /\babort(ed)?\b/i.test(n);
11
+ }, m = (e, t) => e === null ? Promise.resolve() : t.aborted ? Promise.reject(t.reason ?? new DOMException("stream aborted", "AbortError")) : new Promise((n, r) => {
12
+ let i = setTimeout(() => {
13
+ t.removeEventListener("abort", a), n();
14
+ }, e), a = () => {
15
+ clearTimeout(i), t.removeEventListener("abort", a), r(t.reason ?? new DOMException("stream aborted", "AbortError"));
16
+ };
17
+ t.addEventListener("abort", a, { once: !0 });
18
+ }), h = (e, t) => () => {
19
+ let n;
20
+ return new TransformStream({ async transform(r, i) {
21
+ r.type !== "text-delta" && r.type !== "reasoning-delta" ? (n = void 0, i.enqueue(r)) : (n?.type === r.type && n.id === r.id && await m(e, t), i.enqueue(r), n = {
22
+ type: r.type,
23
+ id: r.id
24
+ });
25
+ } });
26
+ }, g = (e, t) => {
27
+ switch (e?.type) {
28
+ case "text-delta": return {
29
+ _tag: "token",
30
+ text: e.text ?? e.delta ?? ""
31
+ };
32
+ case "reasoning-delta":
33
+ case "reasoning": return {
34
+ _tag: "reasoning",
35
+ text: e.text ?? e.delta ?? ""
36
+ };
37
+ case "tool-call": return {
38
+ _tag: "toolCall",
39
+ id: e.toolCallId ?? "",
40
+ name: e.toolName ?? "",
41
+ input: e.input
42
+ };
43
+ case "tool-result": return {
44
+ _tag: "toolResult",
45
+ id: e.toolCallId ?? "",
46
+ name: e.toolName ?? "",
47
+ output: e.output
48
+ };
49
+ case "tool-error": return {
50
+ _tag: "toolResult",
51
+ id: e.toolCallId ?? "",
52
+ name: e.toolName ?? "",
53
+ error: String(e.error?.message ?? e.error ?? "tool error")
54
+ };
55
+ case "source": return {
56
+ _tag: "source",
57
+ sourceType: e.sourceType === "document" ? "document" : "url",
58
+ id: e.id ?? "",
59
+ ...e.url === void 0 ? {} : { url: e.url },
60
+ ...e.title === void 0 ? {} : { title: e.title },
61
+ ...e.mediaType === void 0 ? {} : { mediaType: e.mediaType },
62
+ ...e.filename === void 0 ? {} : { filename: e.filename },
63
+ ...e.providerMetadata === void 0 ? {} : { providerMetadata: e.providerMetadata }
64
+ };
65
+ case "file": return e.file ? {
66
+ _tag: "file",
67
+ mediaType: e.file.mediaType,
68
+ data: e.file.base64,
69
+ ...e.providerMetadata === void 0 ? {} : { providerMetadata: e.providerMetadata }
70
+ } : null;
71
+ case "finish-step": return e.providerMetadata === void 0 ? null : {
72
+ _tag: "stepMetadata",
73
+ step: t,
74
+ providerMetadata: e.providerMetadata
75
+ };
76
+ case "abort": return {
77
+ _tag: "error",
78
+ code: "cancelled",
79
+ message: "stream aborted",
80
+ retryable: !1
81
+ };
82
+ case "finish": return {
83
+ _tag: "done",
84
+ finishReason: String(e.finishReason ?? "stop"),
85
+ usage: {
86
+ inputTokens: e.totalUsage?.inputTokens,
87
+ outputTokens: e.totalUsage?.outputTokens,
88
+ totalTokens: e.totalUsage?.totalTokens
89
+ }
90
+ };
91
+ case "error": return {
92
+ _tag: "error",
93
+ code: "provider",
94
+ message: String(e.error),
95
+ retryable: !0
96
+ };
97
+ default: return null;
98
+ }
99
+ }, _ = (u) => f.unwrap(d.gen(function* () {
100
+ let m = yield* d.context(), _ = u.provider ?? e(), v = t(_), y = u.tools ? {
101
+ store: void 0,
102
+ ...u.toolContext,
103
+ runtime: m
104
+ } : u.toolContext, b = u.tools ? n(u.tools, y) : void 0, x = new Set(Object.entries(b ?? {}).filter(([, e]) => e.execute === void 0).map(([e]) => e)), S = u.streamId === void 0 ? new AbortController() : a(u.streamId);
105
+ u.signal !== void 0 && (u.signal.aborted ? S.abort() : u.signal.addEventListener("abort", () => S.abort(), { once: !0 }));
106
+ let C = S.signal, w = u.smooth === !1 ? void 0 : u.smooth, T = l({
107
+ model: v,
108
+ ...u.messages === void 0 ? { prompt: u.prompt } : { messages: [...u.messages] },
109
+ ...u.system === void 0 ? {} : { system: u.system },
110
+ ...u.maxTokens === void 0 ? {} : { maxOutputTokens: u.maxTokens },
111
+ ...u.temperature === void 0 ? {} : { temperature: u.temperature },
112
+ ...u.providerOptions === void 0 ? {} : { providerOptions: u.providerOptions },
113
+ ...u.maxRetries === void 0 ? {} : { maxRetries: u.maxRetries },
114
+ abortSignal: C,
115
+ ...w === void 0 ? {} : { experimental_transform: [s({
116
+ ...w.chunking === void 0 ? {} : { chunking: w.chunking },
117
+ delayInMs: null
118
+ }), h(w.delayMs === void 0 ? 10 : w.delayMs, C)] },
119
+ ...b ? {
120
+ tools: b,
121
+ stopWhen: c(u.maxSteps ?? 8)
122
+ } : {}
123
+ }), E = 0;
124
+ return i(r(_, "streamText"), f.fromAsyncIterable(T.fullStream, (e) => e).pipe(f.map((e) => {
125
+ let t = g(e, E), n = t?._tag === "toolCall" && x.has(t.name) ? {
126
+ ...t,
127
+ execution: "client"
128
+ } : t;
129
+ return e.type === "finish-step" && (E += 1), n;
130
+ }), f.filter((e) => e !== null), f.catch((e) => {
131
+ let t = C.aborted || p(e);
132
+ return f.make({
133
+ _tag: "error",
134
+ code: t ? "cancelled" : "provider",
135
+ message: t ? "stream aborted" : String(e),
136
+ retryable: !t
137
+ });
138
+ }), f.ensuring(d.sync(() => {
139
+ S.abort(), u.streamId !== void 0 && o(u.streamId);
140
+ }))));
141
+ })), v = (e) => e._tag === "token" || e._tag === "reasoning" || e._tag === "toolCall" || e._tag === "toolResult" || e._tag === "source" || e._tag === "file" || e._tag === "message" || e._tag === "stepMetadata", y = (e) => e._tag === "done" || e._tag === "error", b = (e, t = {}) => {
142
+ let n = Math.max(1, t.maxAttempts ?? 3), r = t.backoffMs ?? 250, i = t.maxBackoffMs ?? 5e3, a = [e.provider, ...e.fallbacks ?? []], o = (t, s) => {
143
+ let c = !1, l = a[t];
144
+ return _(l === void 0 ? e : {
145
+ ...e,
146
+ provider: l
147
+ }).pipe(f.takeUntil(y), f.flatMap((e) => {
148
+ if (e._tag === "error" && e.retryable && !c) {
149
+ if (s + 1 < n) {
150
+ let e = Math.min(i, r * 2 ** s);
151
+ return f.unwrap(d.as(d.sleep(u.millis(e)), o(t, s + 1)));
152
+ }
153
+ if (t + 1 < a.length) return o(t + 1, 0);
154
+ }
155
+ return v(e) && (c = !0), f.make(e);
156
+ }, { concurrency: 1 }));
157
+ };
158
+ return o(0, 0);
159
+ }, x = (e) => {
160
+ let t = [e.provider, ...e.fallbacks ?? []], n = (r) => {
161
+ let i = !1, a = t[r];
162
+ return _(a === void 0 ? e : {
163
+ ...e,
164
+ provider: a
165
+ }).pipe(f.takeUntil(y), f.flatMap((e) => e._tag === "error" && e.retryable && !i && r + 1 < t.length ? n(r + 1) : (v(e) && (i = !0), f.make(e)), { concurrency: 1 }));
166
+ };
167
+ return n(0);
168
+ };
169
+ //#endregion
170
+ export { _ as streamText, x as streamTextWithFallback, b as streamTextWithRetry };
@@ -0,0 +1,74 @@
1
+ import { providerFromEnv as e, resolveTranscriptionModel as t } from "./provider.js";
2
+ import { TranscriptionStreamError as n, TranscriptionStreamEvent as r } from "./transcriptionEvent.js";
3
+ import { experimental_streamTranscribe as i } from "ai";
4
+ import { Effect as a, Schema as o, Stream as s } from "effect";
5
+ //#region src/streamTranscribe.ts
6
+ var c = (c) => s.unwrap(a.gen(function* () {
7
+ let l = yield* a.acquireRelease(a.sync(() => new AbortController()), (e) => a.promise(async () => {
8
+ e.abort(), c.audio.locked || await c.audio.cancel().catch(() => {});
9
+ })), u = c.signal === void 0 ? l.signal : AbortSignal.any([l.signal, c.signal]), d = (e) => {
10
+ let t = new n({
11
+ reason: u.aborted ? "cancelled" : "provider",
12
+ message: u.aborted ? "Transcription cancelled." : "Streaming transcription failed."
13
+ });
14
+ return Object.defineProperty(t, "cause", {
15
+ value: e,
16
+ enumerable: !1
17
+ }), t;
18
+ };
19
+ if (u.aborted) return s.fail(d(u.reason));
20
+ let f = c.inputAudioFormat;
21
+ if (![
22
+ "audio/pcm",
23
+ "audio/pcmu",
24
+ "audio/pcma"
25
+ ].includes(f.type) || f.type === "audio/pcm" && f.rate === void 0 || f.rate !== void 0 && (!Number.isSafeInteger(f.rate) || f.rate <= 0)) return s.fail(new n({
26
+ reason: "input",
27
+ message: "streamTranscribe requires raw PCM (with a positive integer rate), PCMU or PCMA audio; decode container files first."
28
+ }));
29
+ let p = yield* a.try({
30
+ try: () => t(c.provider ?? e()),
31
+ catch: d
32
+ });
33
+ if (p.doStream === void 0) return s.fail(new n({
34
+ reason: "unsupported",
35
+ message: "The selected transcription provider/model does not support streaming."
36
+ }));
37
+ let m = yield* a.try({
38
+ try: () => i({
39
+ model: p,
40
+ audio: c.audio,
41
+ inputAudioFormat: f,
42
+ ...c.providerOptions === void 0 ? {} : { providerOptions: c.providerOptions },
43
+ abortSignal: u
44
+ }),
45
+ catch: d
46
+ }), h = s.fromReadableStream({
47
+ evaluate: () => m.fullStream,
48
+ onError: d
49
+ }).pipe(s.filter((e) => e.type !== "raw"), s.mapEffect((e) => e.type === "error" ? a.fail(d(e.error)) : o.decodeUnknownEffect(r)(e).pipe(a.mapError(d)))), g = s.fromEffect(a.tryPromise({
50
+ try: async () => {
51
+ let [e, t, n, i] = await Promise.all([
52
+ m.text,
53
+ m.segments,
54
+ m.language,
55
+ m.durationInSeconds
56
+ ]);
57
+ return o.decodeUnknownSync(r)({
58
+ type: "finish",
59
+ text: e,
60
+ segments: t.map((e) => ({
61
+ text: e.text,
62
+ start: e.startSecond,
63
+ end: e.endSecond
64
+ })),
65
+ ...n === void 0 ? {} : { language: n },
66
+ ...i === void 0 ? {} : { durationSec: i }
67
+ });
68
+ },
69
+ catch: d
70
+ }));
71
+ return s.concat(h, g);
72
+ }));
73
+ //#endregion
74
+ export { n as TranscriptionStreamError, r as TranscriptionStreamEvent, c as streamTranscribe };
@@ -0,0 +1,44 @@
1
+ import { Effect as e } from "effect";
2
+ //#region src/streamWakeups.ts
3
+ var t = /* @__PURE__ */ new WeakMap(), n = (e, n) => (t.get(e)?.get(n)?.readers ?? 0) > 0, r = (n, r) => e.acquireRelease(e.sync(() => {
4
+ let e = t.get(n);
5
+ e === void 0 && (e = /* @__PURE__ */ new Map(), t.set(n, e));
6
+ let i = e.get(r);
7
+ return i === void 0 && (i = {
8
+ version: 0,
9
+ readers: 0,
10
+ waiters: /* @__PURE__ */ new Set()
11
+ }, e.set(r, i)), i.readers++, i;
12
+ }), (i) => e.sync(() => {
13
+ if (i.readers--, i.readers === 0) {
14
+ let e = t.get(n);
15
+ e?.delete(r), e?.size === 0 && t.delete(n);
16
+ }
17
+ })), i = (t, n) => e.callback((r) => {
18
+ if (t.version !== n) {
19
+ r(e.void);
20
+ return;
21
+ }
22
+ let i = () => {
23
+ t.waiters.delete(i), r(e.void);
24
+ };
25
+ return t.waiters.add(i), e.sync(() => {
26
+ t.waiters.delete(i);
27
+ });
28
+ }), a = (n) => {
29
+ let r = (e) => {
30
+ let n = t.get(i)?.get(e);
31
+ if (n === void 0) return;
32
+ n.version++;
33
+ let r = [...n.waiters];
34
+ for (let e of r) n.waiters.has(e) && e();
35
+ }, i = {
36
+ ...n,
37
+ append: (t, i) => n.append(t, i).pipe(e.tap(() => e.sync(() => r(t)))),
38
+ ...n.appendMany === void 0 ? {} : { appendMany: (t, i) => n.appendMany(t, i).pipe(e.tap(() => e.sync(() => r(t)))) },
39
+ markDone: (t) => n.markDone(t).pipe(e.tap(() => e.sync(() => r(t))))
40
+ };
41
+ return i;
42
+ };
43
+ //#endregion
44
+ export { i as awaitStreamChange, n as hasStreamReaders, r as watchStream, a as withStreamWakeups };
@@ -0,0 +1,48 @@
1
+ import { normalizeAiCallEvidence as e } from "./callEvidence.js";
2
+ import { wrapLanguageModel as t } from "ai";
3
+ //#region src/structuredEvidence.ts
4
+ var n = (n, r) => {
5
+ let i = [];
6
+ return {
7
+ model: t({
8
+ model: r,
9
+ middleware: {
10
+ specificationVersion: "v4",
11
+ wrapGenerate: async ({ doGenerate: t }) => {
12
+ let a = await t(), o = a.usage.inputTokens.total, s = a.usage.outputTokens.total;
13
+ return i.push(e(n, r.modelId, {
14
+ inputTokens: o,
15
+ outputTokens: s,
16
+ totalTokens: o !== void 0 && s !== void 0 ? o + s : void 0
17
+ }, a.providerMetadata)), a;
18
+ }
19
+ }
20
+ }),
21
+ evidence: (t) => {
22
+ if (i.length === 0) return e(n, r.modelId, t);
23
+ let a = (e) => {
24
+ let t = 0;
25
+ for (let n of i) {
26
+ let r = n.usage[e];
27
+ if (r === void 0) return;
28
+ t += r;
29
+ }
30
+ return t;
31
+ }, o = 0;
32
+ for (let e of i) {
33
+ if (e.cost.status !== "actual") {
34
+ o = void 0;
35
+ break;
36
+ }
37
+ o += e.cost.usd;
38
+ }
39
+ return e(n, r.modelId, {
40
+ inputTokens: a("inputTokens"),
41
+ outputTokens: a("outputTokens"),
42
+ totalTokens: a("totalTokens")
43
+ }, o === void 0 ? void 0 : { gateway: { cost: o } });
44
+ }
45
+ };
46
+ };
47
+ //#endregion
48
+ export { n as captureStructuredEvidence };
package/dist/test.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e, u as t } from "./provider-BnemgE4D.js";
1
+ import { MockScript as e, setProviderOverride as t } from "./provider.js";
2
2
  //#region src/test/index.ts
3
3
  var n = (e) => e.turns && e.turns.length > 0 ? e.turns : e.stream && e.stream.length > 0 ? [{ text: e.stream.join("") }] : e.generate ? [{ text: e.generate.text }] : [{ text: "" }], r = (t) => {
4
4
  let r = new e(n(t));
@@ -0,0 +1,92 @@
1
+ import { AGENT_MESSAGES_TABLE as e, AGENT_THREADS_TABLE as t } from "./agentConstants.js";
2
+ import { AgentThreadAccessDenied as n } from "./agent.js";
3
+ import { Effect as r } from "effect";
4
+ import { boolean as i, id as a, integer as o, json as s, table as c, text as l, timestamp as u } from "@voltro/database";
5
+ //#region src/threads.ts
6
+ var d = c(t, {
7
+ id: a({ prefix: "thread" }),
8
+ tenantId: l().nullable(),
9
+ subjectId: l().nullable(),
10
+ title: l().nullable(),
11
+ createdAt: u(),
12
+ updatedAt: u()
13
+ }).renamedFrom("agent_threads").index(["tenantId"]), f = c(e, {
14
+ id: a({ prefix: "msg" }),
15
+ threadId: l(),
16
+ tenantId: l().nullable(),
17
+ role: l(),
18
+ content: l(),
19
+ streaming: i(),
20
+ order: o(),
21
+ stepOrder: o(),
22
+ parts: s(),
23
+ createdAt: u()
24
+ }).renamedFrom("agent_messages").index(["threadId"]), p = (e, n = {}) => r.promise(async () => {
25
+ let r = /* @__PURE__ */ new Date();
26
+ return await e.insert(t, {
27
+ tenantId: n.tenantId ?? null,
28
+ subjectId: n.subjectId ?? null,
29
+ title: n.title ?? null,
30
+ createdAt: r,
31
+ updatedAt: r
32
+ });
33
+ }), m = (e, i) => r.gen(function* () {
34
+ let a = yield* _(e, i.threadId);
35
+ if (a === null) {
36
+ let n = /* @__PURE__ */ new Date();
37
+ return yield* r.promise(() => e.insert(t, {
38
+ id: i.threadId,
39
+ tenantId: i.tenantId ?? null,
40
+ subjectId: i.subjectId,
41
+ title: null,
42
+ createdAt: n,
43
+ updatedAt: n
44
+ }));
45
+ }
46
+ return a.subjectId !== null && a.subjectId !== i.subjectId ? yield* r.fail(new n({ threadId: i.threadId })) : a;
47
+ }), h = (n, i) => r.promise(async () => {
48
+ let r = i.parts ?? (i.content ? [{
49
+ type: "text",
50
+ text: i.content
51
+ }] : []), a = await n.insert(e, {
52
+ threadId: i.threadId,
53
+ tenantId: i.tenantId ?? null,
54
+ role: i.role,
55
+ content: i.content,
56
+ streaming: i.streaming ?? !1,
57
+ order: i.order ?? 0,
58
+ stepOrder: i.stepOrder ?? 0,
59
+ parts: r,
60
+ createdAt: /* @__PURE__ */ new Date()
61
+ });
62
+ return await n.update(t, i.threadId, { updatedAt: /* @__PURE__ */ new Date() }).catch(() => null), a;
63
+ }), g = (t, n) => r.promise(async () => await t.query({
64
+ table: e,
65
+ predicate: {
66
+ _tag: "leaf",
67
+ column: "threadId",
68
+ op: "eq",
69
+ value: n
70
+ },
71
+ order: [{
72
+ column: "createdAt",
73
+ direction: "asc"
74
+ }],
75
+ take: void 0,
76
+ skip: void 0,
77
+ projection: void 0
78
+ })), _ = (e, t) => r.promise(async () => (await e.query({
79
+ table: "_voltro_agent_threads",
80
+ predicate: {
81
+ _tag: "leaf",
82
+ column: "id",
83
+ op: "eq",
84
+ value: t
85
+ },
86
+ order: [],
87
+ take: 1,
88
+ skip: void 0,
89
+ projection: void 0
90
+ }))[0] ?? null);
91
+ //#endregion
92
+ export { e as AGENT_MESSAGES_TABLE, t as AGENT_THREADS_TABLE, f as agentMessagesTable, d as agentThreadsTable, h as appendMessage, p as createThread, m as ensureThreadOwned, g as getMessages, _ as getThread };