@ztimson/ai-utils 0.6.4 → 0.6.6
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/dist/asr.d.ts +1 -0
- package/dist/asr.js +22 -0
- package/dist/asr.js.map +1 -0
- package/dist/asr.mjs +94 -0
- package/dist/asr.mjs.map +1 -0
- package/dist/audio.d.ts +3 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +18 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +237 -305
- package/dist/index.mjs.map +1 -1
- package/dist/llm.d.ts +0 -3
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,40 +1,38 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { objectMap as _, JSONAttemptParse as g, findByProp as
|
|
1
|
+
import * as S from "node:os";
|
|
2
|
+
import { objectMap as _, JSONAttemptParse as g, findByProp as k, JSONSanitize as b, clean as T, Http as q, consoleInterceptor as M, fn as P, ASet as $ } from "@ztimson/utils";
|
|
3
3
|
import { Anthropic as E } from "@anthropic-ai/sdk";
|
|
4
|
-
import { OpenAI as
|
|
5
|
-
import { Worker as
|
|
6
|
-
import { fileURLToPath as
|
|
7
|
-
import { join as
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import * as D from "node:fs";
|
|
11
|
-
import * as L from "wavefile";
|
|
4
|
+
import { OpenAI as A } from "openai";
|
|
5
|
+
import { Worker as x } from "worker_threads";
|
|
6
|
+
import { fileURLToPath as v } from "url";
|
|
7
|
+
import { join as O, dirname as U } from "path";
|
|
8
|
+
import R from "node:path";
|
|
9
|
+
import { canDiarization as L } from "./asr.mjs";
|
|
12
10
|
import { createWorker as N } from "tesseract.js";
|
|
13
11
|
import "./embedder.mjs";
|
|
14
|
-
import * as
|
|
15
|
-
import { $ as
|
|
16
|
-
class
|
|
12
|
+
import * as C from "cheerio";
|
|
13
|
+
import { $ as W, $Sync as D } from "@ztimson/node-utils";
|
|
14
|
+
class j {
|
|
17
15
|
}
|
|
18
|
-
class
|
|
16
|
+
class z extends j {
|
|
19
17
|
constructor(r, e, t) {
|
|
20
18
|
super(), this.ai = r, this.apiToken = e, this.model = t, this.client = new E({ apiKey: e });
|
|
21
19
|
}
|
|
22
20
|
client;
|
|
23
21
|
toStandard(r) {
|
|
24
22
|
const e = Date.now(), t = [];
|
|
25
|
-
for (let
|
|
26
|
-
if (typeof
|
|
27
|
-
t.push({ timestamp: e, ...
|
|
23
|
+
for (let o of r)
|
|
24
|
+
if (typeof o.content == "string")
|
|
25
|
+
t.push({ timestamp: e, ...o });
|
|
28
26
|
else {
|
|
29
|
-
const
|
|
27
|
+
const s = o.content?.filter((n) => n.type == "text").map((n) => n.text).join(`
|
|
30
28
|
|
|
31
29
|
`);
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
t.push({ timestamp: e, role: "tool", id:
|
|
35
|
-
else if (
|
|
36
|
-
const
|
|
37
|
-
|
|
30
|
+
s && t.push({ timestamp: e, role: o.role, content: s }), o.content.forEach((n) => {
|
|
31
|
+
if (n.type == "tool_use")
|
|
32
|
+
t.push({ timestamp: e, role: "tool", id: n.id, name: n.name, args: n.input, content: void 0 });
|
|
33
|
+
else if (n.type == "tool_result") {
|
|
34
|
+
const i = t.findLast((m) => m.id == n.tool_use_id);
|
|
35
|
+
i && (i[n.is_error ? "error" : "content"] = n.content);
|
|
38
36
|
}
|
|
39
37
|
});
|
|
40
38
|
}
|
|
@@ -55,78 +53,78 @@ class H extends S {
|
|
|
55
53
|
}
|
|
56
54
|
ask(r, e = {}) {
|
|
57
55
|
const t = new AbortController();
|
|
58
|
-
return Object.assign(new Promise(async (
|
|
59
|
-
let
|
|
60
|
-
const
|
|
56
|
+
return Object.assign(new Promise(async (o) => {
|
|
57
|
+
let s = this.fromStandard([...e.history || [], { role: "user", content: r, timestamp: Date.now() }]);
|
|
58
|
+
const n = e.tools || this.ai.options.llm?.tools || [], i = {
|
|
61
59
|
model: e.model || this.model,
|
|
62
60
|
max_tokens: e.max_tokens || this.ai.options.llm?.max_tokens || 4096,
|
|
63
61
|
system: e.system || this.ai.options.llm?.system || "",
|
|
64
62
|
temperature: e.temperature || this.ai.options.llm?.temperature || 0.7,
|
|
65
|
-
tools:
|
|
63
|
+
tools: n.map((d) => ({
|
|
66
64
|
name: d.name,
|
|
67
65
|
description: d.description,
|
|
68
66
|
input_schema: {
|
|
69
67
|
type: "object",
|
|
70
|
-
properties: d.args ? _(d.args, (c,
|
|
68
|
+
properties: d.args ? _(d.args, (c, l) => ({ ...l, required: void 0 })) : {},
|
|
71
69
|
required: d.args ? Object.entries(d.args).filter((c) => c[1].required).map((c) => c[0]) : []
|
|
72
70
|
},
|
|
73
71
|
fn: void 0
|
|
74
72
|
})),
|
|
75
|
-
messages:
|
|
73
|
+
messages: s,
|
|
76
74
|
stream: !!e.stream
|
|
77
75
|
};
|
|
78
|
-
let
|
|
76
|
+
let m, a = !0;
|
|
79
77
|
do {
|
|
80
|
-
if (
|
|
78
|
+
if (m = await this.client.messages.create(i).catch((c) => {
|
|
81
79
|
throw c.message += `
|
|
82
80
|
|
|
83
81
|
Messages:
|
|
84
|
-
${JSON.stringify(
|
|
82
|
+
${JSON.stringify(s, null, 2)}`, c;
|
|
85
83
|
}), e.stream) {
|
|
86
|
-
|
|
84
|
+
a ? a = !1 : e.stream({ text: `
|
|
87
85
|
|
|
88
|
-
` }),
|
|
89
|
-
for await (const c of
|
|
86
|
+
` }), m.content = [];
|
|
87
|
+
for await (const c of m) {
|
|
90
88
|
if (t.signal.aborted) break;
|
|
91
89
|
if (c.type === "content_block_start")
|
|
92
|
-
c.content_block.type === "text" ?
|
|
90
|
+
c.content_block.type === "text" ? m.content.push({ type: "text", text: "" }) : c.content_block.type === "tool_use" && m.content.push({ type: "tool_use", id: c.content_block.id, name: c.content_block.name, input: "" });
|
|
93
91
|
else if (c.type === "content_block_delta")
|
|
94
92
|
if (c.delta.type === "text_delta") {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
} else c.delta.type === "input_json_delta" && (
|
|
93
|
+
const l = c.delta.text;
|
|
94
|
+
m.content.at(-1).text += l, e.stream({ text: l });
|
|
95
|
+
} else c.delta.type === "input_json_delta" && (m.content.at(-1).input += c.delta.partial_json);
|
|
98
96
|
else if (c.type === "content_block_stop") {
|
|
99
|
-
const
|
|
100
|
-
|
|
97
|
+
const l = m.content.at(-1);
|
|
98
|
+
l.input != null && (l.input = l.input ? g(l.input, {}) : {});
|
|
101
99
|
} else if (c.type === "message_stop")
|
|
102
100
|
break;
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
|
-
const d =
|
|
103
|
+
const d = m.content.filter((c) => c.type === "tool_use");
|
|
106
104
|
if (d.length && !t.signal.aborted) {
|
|
107
|
-
|
|
108
|
-
const c = await Promise.all(d.map(async (
|
|
109
|
-
const
|
|
110
|
-
if (e.stream && e.stream({ tool:
|
|
105
|
+
s.push({ role: "assistant", content: m.content });
|
|
106
|
+
const c = await Promise.all(d.map(async (l) => {
|
|
107
|
+
const p = n.find(k("name", l.name));
|
|
108
|
+
if (e.stream && e.stream({ tool: l.name }), !p) return { tool_use_id: l.id, is_error: !0, content: "Tool not found" };
|
|
111
109
|
try {
|
|
112
|
-
const u = await
|
|
113
|
-
return { type: "tool_result", tool_use_id:
|
|
110
|
+
const u = await p.fn(l.input, e?.stream, this.ai);
|
|
111
|
+
return { type: "tool_result", tool_use_id: l.id, content: b(u) };
|
|
114
112
|
} catch (u) {
|
|
115
|
-
return { type: "tool_result", tool_use_id:
|
|
113
|
+
return { type: "tool_result", tool_use_id: l.id, is_error: !0, content: u?.message || u?.toString() || "Unknown" };
|
|
116
114
|
}
|
|
117
115
|
}));
|
|
118
|
-
|
|
116
|
+
s.push({ role: "user", content: c }), i.messages = s;
|
|
119
117
|
}
|
|
120
|
-
} while (!t.signal.aborted &&
|
|
121
|
-
|
|
118
|
+
} while (!t.signal.aborted && m.content.some((d) => d.type === "tool_use"));
|
|
119
|
+
s.push({ role: "assistant", content: m.content.filter((d) => d.type == "text").map((d) => d.text).join(`
|
|
122
120
|
|
|
123
|
-
`) }),
|
|
121
|
+
`) }), s = this.toStandard(s), e.stream && e.stream({ done: !0 }), e.history && e.history.splice(0, e.history.length, ...s), o(s.at(-1)?.content);
|
|
124
122
|
}), { abort: () => t.abort() });
|
|
125
123
|
}
|
|
126
124
|
}
|
|
127
|
-
class
|
|
128
|
-
constructor(r, e, t,
|
|
129
|
-
super(), this.ai = r, this.host = e, this.token = t, this.model =
|
|
125
|
+
class w extends j {
|
|
126
|
+
constructor(r, e, t, o) {
|
|
127
|
+
super(), this.ai = r, this.host = e, this.token = t, this.model = o, this.client = new A(T({
|
|
130
128
|
baseURL: e,
|
|
131
129
|
apiKey: t
|
|
132
130
|
}));
|
|
@@ -136,17 +134,17 @@ class k extends S {
|
|
|
136
134
|
for (let e = 0; e < r.length; e++) {
|
|
137
135
|
const t = r[e];
|
|
138
136
|
if (t.role === "assistant" && t.tool_calls) {
|
|
139
|
-
const
|
|
137
|
+
const o = t.tool_calls.map((s) => ({
|
|
140
138
|
role: "tool",
|
|
141
|
-
id:
|
|
142
|
-
name:
|
|
143
|
-
args: g(
|
|
139
|
+
id: s.id,
|
|
140
|
+
name: s.function.name,
|
|
141
|
+
args: g(s.function.arguments, {}),
|
|
144
142
|
timestamp: t.timestamp
|
|
145
143
|
}));
|
|
146
|
-
r.splice(e, 1, ...
|
|
144
|
+
r.splice(e, 1, ...o), e += o.length - 1;
|
|
147
145
|
} else if (t.role === "tool" && t.content) {
|
|
148
|
-
const
|
|
149
|
-
|
|
146
|
+
const o = r.find((s) => t.tool_call_id == s.id);
|
|
147
|
+
o && (t.content.includes('"error":') ? o.error = t.content : o.content = t.content), r.splice(e, 1), e--;
|
|
150
148
|
}
|
|
151
149
|
r[e]?.timestamp || (r[e].timestamp = Date.now());
|
|
152
150
|
}
|
|
@@ -167,84 +165,78 @@ class k extends S {
|
|
|
167
165
|
content: t.error || t.content
|
|
168
166
|
});
|
|
169
167
|
else {
|
|
170
|
-
const { timestamp:
|
|
171
|
-
e.push(
|
|
168
|
+
const { timestamp: o, ...s } = t;
|
|
169
|
+
e.push(s);
|
|
172
170
|
}
|
|
173
171
|
return e;
|
|
174
172
|
}, []);
|
|
175
173
|
}
|
|
176
174
|
ask(r, e = {}) {
|
|
177
175
|
const t = new AbortController();
|
|
178
|
-
return Object.assign(new Promise(async (
|
|
176
|
+
return Object.assign(new Promise(async (o, s) => {
|
|
179
177
|
e.system && e.history?.[0]?.role != "system" && e.history?.splice(0, 0, { role: "system", content: e.system, timestamp: Date.now() });
|
|
180
|
-
let
|
|
181
|
-
const
|
|
178
|
+
let n = this.fromStandard([...e.history || [], { role: "user", content: r, timestamp: Date.now() }]);
|
|
179
|
+
const i = e.tools || this.ai.options.llm?.tools || [], m = {
|
|
182
180
|
model: e.model || this.model,
|
|
183
|
-
messages:
|
|
181
|
+
messages: n,
|
|
184
182
|
stream: !!e.stream,
|
|
185
183
|
max_tokens: e.max_tokens || this.ai.options.llm?.max_tokens || 4096,
|
|
186
184
|
temperature: e.temperature || this.ai.options.llm?.temperature || 0.7,
|
|
187
|
-
tools:
|
|
185
|
+
tools: i.map((c) => ({
|
|
188
186
|
type: "function",
|
|
189
187
|
function: {
|
|
190
188
|
name: c.name,
|
|
191
189
|
description: c.description,
|
|
192
190
|
parameters: {
|
|
193
191
|
type: "object",
|
|
194
|
-
properties: c.args ? _(c.args, (
|
|
195
|
-
required: c.args ? Object.entries(c.args).filter((
|
|
192
|
+
properties: c.args ? _(c.args, (l, p) => ({ ...p, required: void 0 })) : {},
|
|
193
|
+
required: c.args ? Object.entries(c.args).filter((l) => l[1].required).map((l) => l[0]) : []
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
196
|
}))
|
|
199
197
|
};
|
|
200
|
-
let
|
|
198
|
+
let a, d = !0;
|
|
201
199
|
do {
|
|
202
|
-
if (
|
|
203
|
-
throw
|
|
200
|
+
if (a = await this.client.chat.completions.create(m).catch((l) => {
|
|
201
|
+
throw l.message += `
|
|
204
202
|
|
|
205
203
|
Messages:
|
|
206
|
-
${JSON.stringify(
|
|
204
|
+
${JSON.stringify(n, null, 2)}`, l;
|
|
207
205
|
}), e.stream) {
|
|
208
206
|
d ? d = !1 : e.stream({ text: `
|
|
209
207
|
|
|
210
|
-
` }),
|
|
211
|
-
for await (const
|
|
208
|
+
` }), a.choices = [{ message: { content: "", tool_calls: [] } }];
|
|
209
|
+
for await (const l of a) {
|
|
212
210
|
if (t.signal.aborted) break;
|
|
213
|
-
|
|
211
|
+
l.choices[0].delta.content && (a.choices[0].message.content += l.choices[0].delta.content, e.stream({ text: l.choices[0].delta.content })), l.choices[0].delta.tool_calls && (a.choices[0].message.tool_calls = l.choices[0].delta.tool_calls);
|
|
214
212
|
}
|
|
215
213
|
}
|
|
216
|
-
const c =
|
|
214
|
+
const c = a.choices[0].message.tool_calls || [];
|
|
217
215
|
if (c.length && !t.signal.aborted) {
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
const u =
|
|
221
|
-
if (e.stream && e.stream({ tool:
|
|
216
|
+
n.push(a.choices[0].message);
|
|
217
|
+
const l = await Promise.all(c.map(async (p) => {
|
|
218
|
+
const u = i?.find(k("name", p.function.name));
|
|
219
|
+
if (e.stream && e.stream({ tool: p.function.name }), !u) return { role: "tool", tool_call_id: p.id, content: '{"error": "Tool not found"}' };
|
|
222
220
|
try {
|
|
223
|
-
const f = g(
|
|
224
|
-
return { role: "tool", tool_call_id:
|
|
221
|
+
const f = g(p.function.arguments, {}), y = await u.fn(f, e.stream, this.ai);
|
|
222
|
+
return { role: "tool", tool_call_id: p.id, content: b(y) };
|
|
225
223
|
} catch (f) {
|
|
226
|
-
return { role: "tool", tool_call_id:
|
|
224
|
+
return { role: "tool", tool_call_id: p.id, content: b({ error: f?.message || f?.toString() || "Unknown" }) };
|
|
227
225
|
}
|
|
228
226
|
}));
|
|
229
|
-
|
|
227
|
+
n.push(...l), m.messages = n;
|
|
230
228
|
}
|
|
231
|
-
} while (!t.signal.aborted &&
|
|
232
|
-
|
|
229
|
+
} while (!t.signal.aborted && a.choices?.[0]?.message?.tool_calls?.length);
|
|
230
|
+
n.push({ role: "assistant", content: a.choices[0].message.content || "" }), n = this.toStandard(n), e.stream && e.stream({ done: !0 }), e.history && e.history.splice(0, e.history.length, ...n), o(n.at(-1)?.content);
|
|
233
231
|
}), { abort: () => t.abort() });
|
|
234
232
|
}
|
|
235
233
|
}
|
|
236
|
-
class
|
|
234
|
+
class H {
|
|
237
235
|
constructor(r) {
|
|
238
|
-
this.ai = r,
|
|
239
|
-
|
|
240
|
-
i && (i.resolve(t), this.embedQueue.delete(e));
|
|
241
|
-
}), r.options.llm?.models && Object.entries(r.options.llm.models).forEach(([e, t]) => {
|
|
242
|
-
this.defaultModel || (this.defaultModel = e), t.proto == "anthropic" ? this.models[e] = new H(this.ai, t.token, e) : t.proto == "ollama" ? this.models[e] = new k(this.ai, t.host, "not-needed", e) : t.proto == "openai" && (this.models[e] = new k(this.ai, t.host || null, t.token, e));
|
|
236
|
+
this.ai = r, r.options.llm?.models && Object.entries(r.options.llm.models).forEach(([e, t]) => {
|
|
237
|
+
this.defaultModel || (this.defaultModel = e), t.proto == "anthropic" ? this.models[e] = new z(this.ai, t.token, e) : t.proto == "ollama" ? this.models[e] = new w(this.ai, t.host, "not-needed", e) : t.proto == "openai" && (this.models[e] = new w(this.ai, t.host || null, t.token, e));
|
|
243
238
|
});
|
|
244
239
|
}
|
|
245
|
-
embedWorker = null;
|
|
246
|
-
embedQueue = /* @__PURE__ */ new Map();
|
|
247
|
-
embedId = 0;
|
|
248
240
|
models = {};
|
|
249
241
|
defaultModel;
|
|
250
242
|
/**
|
|
@@ -256,22 +248,22 @@ class J {
|
|
|
256
248
|
ask(r, e = {}) {
|
|
257
249
|
const t = e.model || this.defaultModel;
|
|
258
250
|
if (!this.models[t]) throw new Error(`Model does not exist: ${t}`);
|
|
259
|
-
let
|
|
251
|
+
let o = () => {
|
|
260
252
|
};
|
|
261
|
-
return Object.assign(new Promise(async (
|
|
253
|
+
return Object.assign(new Promise(async (s) => {
|
|
262
254
|
if (e.history || (e.history = []), e.memory) {
|
|
263
255
|
e.system = (e.system || "") + `
|
|
264
256
|
You have passive persistent memory never make any mention of your memory capabilities and what you can/cannot remember
|
|
265
257
|
`;
|
|
266
|
-
const
|
|
267
|
-
const [
|
|
258
|
+
const i = async (a, d, c = 50) => {
|
|
259
|
+
const [l, p] = await Promise.all([
|
|
268
260
|
d ? this.embedding(d) : Promise.resolve(null),
|
|
269
|
-
|
|
261
|
+
a ? this.embedding(a) : Promise.resolve(null)
|
|
270
262
|
]);
|
|
271
|
-
return (e.memory || []).map((u) => ({ ...u, score:
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
` +
|
|
263
|
+
return (e.memory || []).map((u) => ({ ...u, score: l ? this.cosineSimilarity(u.embeddings[0], l[0].embedding) : 1 })).filter((u) => u.score >= 0.8).map((u) => ({ ...u, score: p ? this.cosineSimilarity(u.embeddings[1], p[0].embedding) : u.score })).filter((u) => u.score >= 0.2).toSorted((u, f) => u.score - f.score).slice(0, c);
|
|
264
|
+
}, m = await i(r);
|
|
265
|
+
m.length && e.history.push({ role: "assistant", content: `Things I remembered:
|
|
266
|
+
` + m.map((a) => `${a.owner}: ${a.fact}`).join(`
|
|
275
267
|
`) }), e.tools = [...e.tools || [], {
|
|
276
268
|
name: "read_memory",
|
|
277
269
|
description: "Check your long-term memory for more information",
|
|
@@ -280,32 +272,32 @@ You have passive persistent memory never make any mention of your memory capabil
|
|
|
280
272
|
query: { type: "string", description: "Search memory based on a query, can be used with or without subject argument" },
|
|
281
273
|
limit: { type: "number", description: "Result limit, default 5" }
|
|
282
274
|
},
|
|
283
|
-
fn: (
|
|
284
|
-
if (!
|
|
285
|
-
return
|
|
275
|
+
fn: (a) => {
|
|
276
|
+
if (!a.subject && !a.query) throw new Error("Either a subject or query argument is required");
|
|
277
|
+
return i(a.query, a.subject, a.limit || 5);
|
|
286
278
|
}
|
|
287
279
|
}];
|
|
288
280
|
}
|
|
289
|
-
const
|
|
281
|
+
const n = await this.models[t].ask(r, e);
|
|
290
282
|
if (e.memory) {
|
|
291
|
-
const
|
|
292
|
-
|
|
283
|
+
const i = e.history?.findIndex((m) => m.role == "assistant" && m.content.startsWith("Things I remembered:"));
|
|
284
|
+
i != null && i >= 0 && e.history?.splice(i, 1);
|
|
293
285
|
}
|
|
294
286
|
if (e.compress || e.memory) {
|
|
295
|
-
let
|
|
287
|
+
let i = null;
|
|
296
288
|
if (e.compress)
|
|
297
|
-
|
|
289
|
+
i = await this.ai.language.compressHistory(e.history, e.compress.max, e.compress.min, e), e.history.splice(0, e.history.length, ...i.history);
|
|
298
290
|
else {
|
|
299
|
-
const
|
|
300
|
-
|
|
291
|
+
const m = e.history?.findLastIndex((a) => a.role == "user") ?? -1;
|
|
292
|
+
i = await this.ai.language.compressHistory(m != -1 ? e.history.slice(m) : e.history, 0, 0, e);
|
|
301
293
|
}
|
|
302
294
|
if (e.memory) {
|
|
303
|
-
const
|
|
304
|
-
e.memory.splice(0, e.memory.length, ...
|
|
295
|
+
const m = e.memory.filter((a) => !i.memory.some((d) => this.cosineSimilarity(a.embeddings[1], d.embeddings[1]) > 0.8)).concat(i.memory);
|
|
296
|
+
e.memory.splice(0, e.memory.length, ...m);
|
|
305
297
|
}
|
|
306
298
|
}
|
|
307
|
-
return n
|
|
308
|
-
}), { abort:
|
|
299
|
+
return s(n);
|
|
300
|
+
}), { abort: o });
|
|
309
301
|
}
|
|
310
302
|
/**
|
|
311
303
|
* Compress chat history to reduce context size
|
|
@@ -315,22 +307,22 @@ You have passive persistent memory never make any mention of your memory capabil
|
|
|
315
307
|
* @param {LLMRequest} options LLM options
|
|
316
308
|
* @returns {Promise<LLMMessage[]>} New chat history will summary at index 0
|
|
317
309
|
*/
|
|
318
|
-
async compressHistory(r, e, t,
|
|
310
|
+
async compressHistory(r, e, t, o) {
|
|
319
311
|
if (this.estimateTokens(r) < e) return { history: r, memory: [] };
|
|
320
|
-
let
|
|
312
|
+
let s = 0, n = 0;
|
|
321
313
|
for (let u of r.toReversed())
|
|
322
|
-
if (
|
|
314
|
+
if (n += this.estimateTokens(u.content), n < t) s++;
|
|
323
315
|
else break;
|
|
324
|
-
if (r.length <=
|
|
325
|
-
const
|
|
316
|
+
if (r.length <= s) return { history: r, memory: [] };
|
|
317
|
+
const i = r[0].role == "system" ? r[0] : null, m = s == 0 ? [] : r.slice(-s), a = (s == 0 ? r : r.slice(0, -s)).filter((u) => u.role === "assistant" || u.role === "user"), d = await this.json(`Create the smallest summary possible, no more than 500 tokens. Create a list of NEW facts (split by subject [pro]noun and fact) about what you learned from this conversation that you didn't already know or get from a tool call or system prompt. Focus only on new information about people, topics, or facts. Avoid generating facts about the AI. Match this format: {summary: string, facts: [[subject, fact]]}
|
|
326
318
|
|
|
327
|
-
${
|
|
319
|
+
${a.map((u) => `${u.role}: ${u.content}`).join(`
|
|
328
320
|
|
|
329
|
-
`)}`, { model:
|
|
321
|
+
`)}`, { model: o?.model, temperature: o?.temperature || 0.3 }), c = /* @__PURE__ */ new Date(), l = await Promise.all((d?.facts || [])?.map(async ([u, f]) => {
|
|
330
322
|
const y = await Promise.all([this.embedding(u), this.embedding(`${u}: ${f}`)]);
|
|
331
323
|
return { owner: u, fact: f, embeddings: [y[0][0].embedding, y[1][0].embedding], timestamp: c };
|
|
332
|
-
})),
|
|
333
|
-
return
|
|
324
|
+
})), p = [{ role: "assistant", content: `Conversation Summary: ${d?.summary}`, timestamp: Date.now() }, ...m];
|
|
325
|
+
return i && p.splice(0, 0, i), { history: p, memory: l };
|
|
334
326
|
}
|
|
335
327
|
/**
|
|
336
328
|
* Compare the difference between embeddings (calculates the angle between two vectors)
|
|
@@ -340,11 +332,11 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
340
332
|
*/
|
|
341
333
|
cosineSimilarity(r, e) {
|
|
342
334
|
if (r.length !== e.length) throw new Error("Vectors must be same length");
|
|
343
|
-
let t = 0,
|
|
344
|
-
for (let
|
|
345
|
-
t += r[
|
|
346
|
-
const
|
|
347
|
-
return
|
|
335
|
+
let t = 0, o = 0, s = 0;
|
|
336
|
+
for (let i = 0; i < r.length; i++)
|
|
337
|
+
t += r[i] * e[i], o += r[i] * r[i], s += e[i] * e[i];
|
|
338
|
+
const n = Math.sqrt(o) * Math.sqrt(s);
|
|
339
|
+
return n === 0 ? 0 : t / n;
|
|
348
340
|
}
|
|
349
341
|
/**
|
|
350
342
|
* Chunk text into parts for AI digestion
|
|
@@ -354,25 +346,25 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
354
346
|
* @returns {string[]} Chunked strings
|
|
355
347
|
*/
|
|
356
348
|
chunk(r, e = 500, t = 50) {
|
|
357
|
-
const
|
|
358
|
-
const
|
|
359
|
-
return typeof c == "object" && !Array.isArray(c) ?
|
|
360
|
-
}) : [],
|
|
361
|
-
`)).flatMap((
|
|
362
|
-
`]),
|
|
363
|
-
for (let
|
|
364
|
-
let
|
|
365
|
-
for (; d <
|
|
366
|
-
const
|
|
367
|
-
if (this.estimateTokens(
|
|
368
|
-
`)) > e &&
|
|
369
|
-
|
|
349
|
+
const o = (m, a = "") => m ? Object.entries(m).flatMap(([d, c]) => {
|
|
350
|
+
const l = a ? `${a}${isNaN(+d) ? `.${d}` : `[${d}]`}` : d;
|
|
351
|
+
return typeof c == "object" && !Array.isArray(c) ? o(c, l) : `${l}: ${Array.isArray(c) ? c.join(", ") : c}`;
|
|
352
|
+
}) : [], n = (typeof r == "object" ? o(r) : r.split(`
|
|
353
|
+
`)).flatMap((m) => [...m.split(/\s+/).filter(Boolean), `
|
|
354
|
+
`]), i = [];
|
|
355
|
+
for (let m = 0; m < n.length; ) {
|
|
356
|
+
let a = "", d = m;
|
|
357
|
+
for (; d < n.length; ) {
|
|
358
|
+
const l = a + (a ? " " : "") + n[d];
|
|
359
|
+
if (this.estimateTokens(l.replace(/\s*\n\s*/g, `
|
|
360
|
+
`)) > e && a) break;
|
|
361
|
+
a = l, d++;
|
|
370
362
|
}
|
|
371
|
-
const c =
|
|
363
|
+
const c = a.replace(/\s*\n\s*/g, `
|
|
372
364
|
`).trim();
|
|
373
|
-
c &&
|
|
365
|
+
c && i.push(c), m = Math.max(d - t, d === m ? m + 1 : d);
|
|
374
366
|
}
|
|
375
|
-
return
|
|
367
|
+
return i;
|
|
376
368
|
}
|
|
377
369
|
/**
|
|
378
370
|
* Create a vector representation of a string
|
|
@@ -382,20 +374,21 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
382
374
|
* @returns {Promise<Awaited<{index: number, embedding: number[], text: string, tokens: number}>[]>} Chunked embeddings
|
|
383
375
|
*/
|
|
384
376
|
embedding(r, e = 500, t = 50) {
|
|
385
|
-
const
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
377
|
+
const o = (n) => new Promise((i, m) => {
|
|
378
|
+
const a = new x(O(U(v(import.meta.url)), "embedder.js")), d = ({ embedding: l }) => {
|
|
379
|
+
a.terminate(), i(l);
|
|
380
|
+
}, c = (l) => {
|
|
381
|
+
a.terminate(), m(l);
|
|
382
|
+
};
|
|
383
|
+
a.on("message", d), a.on("error", c), a.on("exit", (l) => {
|
|
384
|
+
l !== 0 && m(new Error(`Worker exited with code ${l}`));
|
|
385
|
+
}), a.postMessage({ text: n, model: this.ai.options?.embedder || "bge-small-en-v1.5", path: this.ai.options.path });
|
|
386
|
+
}), s = this.chunk(r, e, t);
|
|
387
|
+
return Promise.all(s.map(async (n, i) => ({
|
|
388
|
+
index: i,
|
|
389
|
+
embedding: await o(n),
|
|
390
|
+
text: n,
|
|
391
|
+
tokens: this.estimateTokens(n)
|
|
399
392
|
})));
|
|
400
393
|
}
|
|
401
394
|
/**
|
|
@@ -415,8 +408,8 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
415
408
|
*/
|
|
416
409
|
fuzzyMatch(r, ...e) {
|
|
417
410
|
if (e.length < 2) throw new Error("Requires at least 2 strings to compare");
|
|
418
|
-
const t = (
|
|
419
|
-
return { avg:
|
|
411
|
+
const t = (n, i = 10) => n.toLowerCase().split("").map((m, a) => m.charCodeAt(0) * (a + 1) % i / i).slice(0, i), o = t(r), s = e.map((n) => t(n)).map((n) => this.cosineSimilarity(o, n));
|
|
412
|
+
return { avg: s.reduce((n, i) => n + i, 0) / s.length, max: Math.max(...s), similarities: s };
|
|
420
413
|
}
|
|
421
414
|
/**
|
|
422
415
|
* Ask a question with JSON response
|
|
@@ -427,8 +420,8 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
427
420
|
async json(r, e) {
|
|
428
421
|
let t = await this.ask(r, { system: "Respond using a JSON blob matching any provided examples", ...e });
|
|
429
422
|
if (!t) return {};
|
|
430
|
-
const
|
|
431
|
-
return g(
|
|
423
|
+
const o = /```(?:.+)?\s*([\s\S]*?)```/.exec(t), s = o ? o[1].trim() : t;
|
|
424
|
+
return g(s, {});
|
|
432
425
|
}
|
|
433
426
|
/**
|
|
434
427
|
* Create a summary of some text
|
|
@@ -441,92 +434,30 @@ ${l.map((u) => `${u.role}: ${u.content}`).join(`
|
|
|
441
434
|
return this.ask(r, { system: `Generate a brief summary <= ${e} tokens. Output nothing else`, temperature: 0.3, ...t });
|
|
442
435
|
}
|
|
443
436
|
}
|
|
444
|
-
class
|
|
437
|
+
class I {
|
|
445
438
|
constructor(r) {
|
|
446
439
|
this.ai = r;
|
|
447
440
|
}
|
|
448
|
-
whisperPipeline;
|
|
449
|
-
combineSpeakerTranscript(r, e) {
|
|
450
|
-
const t = /* @__PURE__ */ new Map();
|
|
451
|
-
let i = 0;
|
|
452
|
-
e.forEach((a) => {
|
|
453
|
-
t.has(a.speaker) || t.set(a.speaker, ++i);
|
|
454
|
-
});
|
|
455
|
-
const n = [];
|
|
456
|
-
let s = -1, o = "";
|
|
457
|
-
return r.forEach((a) => {
|
|
458
|
-
const l = a.timestamp[0], d = e.find((m) => l >= m.start && l <= m.end), c = d ? t.get(d.speaker) : 1;
|
|
459
|
-
c !== s ? (o && n.push(`[speaker ${s}]: ${o.trim()}`), s = c, o = a.text) : o += a.text;
|
|
460
|
-
}), o && n.push(`[speaker ${s}]: ${o.trim()}`), n.join(`
|
|
461
|
-
`);
|
|
462
|
-
}
|
|
463
|
-
async canDiarization() {
|
|
464
|
-
return new Promise((r) => {
|
|
465
|
-
const e = w("python3", ["-c", "import pyannote.audio"]);
|
|
466
|
-
e.on("close", (t) => r(t === 0)), e.on("error", () => r(!1));
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
async runDiarization(r) {
|
|
470
|
-
if (!await this.canDiarization()) throw new Error("Pyannote is not installed: pip install pyannote.audio");
|
|
471
|
-
const e = `
|
|
472
|
-
import sys
|
|
473
|
-
import json
|
|
474
|
-
from pyannote.audio import Pipeline
|
|
475
|
-
|
|
476
|
-
os.environ['TORCH_HOME'] = "${this.ai.options.path}"
|
|
477
|
-
pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization-3.1")
|
|
478
|
-
diarization = pipeline(sys.argv[1])
|
|
479
|
-
|
|
480
|
-
segments = []
|
|
481
|
-
for turn, _, speaker in diarization.itertracks(yield_label=True):
|
|
482
|
-
segments.append({
|
|
483
|
-
"start": turn.start,
|
|
484
|
-
"end": turn.end,
|
|
485
|
-
"speaker": speaker
|
|
486
|
-
})
|
|
487
|
-
|
|
488
|
-
print(json.dumps(segments))
|
|
489
|
-
`;
|
|
490
|
-
return new Promise((t, i) => {
|
|
491
|
-
let n = "";
|
|
492
|
-
const s = w("python3", ["-c", e, r]);
|
|
493
|
-
s.stdout.on("data", (o) => n += o.toString()), s.stderr.on("data", (o) => console.error(o.toString())), s.on("close", (o) => {
|
|
494
|
-
if (o === 0)
|
|
495
|
-
try {
|
|
496
|
-
t(JSON.parse(n));
|
|
497
|
-
} catch {
|
|
498
|
-
i(new Error("Failed to parse diarization output"));
|
|
499
|
-
}
|
|
500
|
-
else
|
|
501
|
-
i(new Error(`Python process exited with code ${o}`));
|
|
502
|
-
}), s.on("error", i);
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
441
|
asr(r, e = {}) {
|
|
506
|
-
const { model: t = this.ai.options.asr || "whisper-base", speaker:
|
|
507
|
-
let
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
},
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (n) return a(null);
|
|
520
|
-
const f = this.combineSpeakerTranscript(h.chunks || [], u);
|
|
521
|
-
a(f);
|
|
522
|
-
} catch (d) {
|
|
523
|
-
l(d);
|
|
524
|
-
}
|
|
442
|
+
const { model: t = this.ai.options.asr || "whisper-base", speaker: o = !1 } = e;
|
|
443
|
+
let s = !1;
|
|
444
|
+
const n = () => {
|
|
445
|
+
s = !0;
|
|
446
|
+
}, i = new Promise((m, a) => {
|
|
447
|
+
const d = new x(R.join(import.meta.dirname, "asr.js")), c = ({ text: p, warning: u, error: f }) => {
|
|
448
|
+
d.terminate(), !s && (f ? a(new Error(f)) : (u && console.warn(u), m(p)));
|
|
449
|
+
}, l = (p) => {
|
|
450
|
+
d.terminate(), s || a(p);
|
|
451
|
+
};
|
|
452
|
+
d.on("message", c), d.on("error", l), d.on("exit", (p) => {
|
|
453
|
+
p !== 0 && !s && a(new Error(`Worker exited with code ${p}`));
|
|
454
|
+
}), d.postMessage({ path: r, model: t, speaker: o, torchHome: this.ai.options.path });
|
|
525
455
|
});
|
|
526
|
-
return Object.assign(
|
|
456
|
+
return Object.assign(i, { abort: n });
|
|
527
457
|
}
|
|
458
|
+
canDiarization = L;
|
|
528
459
|
}
|
|
529
|
-
class
|
|
460
|
+
class J {
|
|
530
461
|
constructor(r) {
|
|
531
462
|
this.ai = r;
|
|
532
463
|
}
|
|
@@ -537,17 +468,17 @@ class B {
|
|
|
537
468
|
*/
|
|
538
469
|
ocr(r) {
|
|
539
470
|
let e;
|
|
540
|
-
const t = new Promise(async (
|
|
471
|
+
const t = new Promise(async (o) => {
|
|
541
472
|
e = await N(this.ai.options.ocr || "eng", 2, { cachePath: this.ai.options.path });
|
|
542
|
-
const { data:
|
|
543
|
-
await e.terminate(),
|
|
473
|
+
const { data: s } = await e.recognize(r);
|
|
474
|
+
await e.terminate(), o(s.text.trim() || null);
|
|
544
475
|
});
|
|
545
476
|
return Object.assign(t, { abort: () => e?.terminate() });
|
|
546
477
|
}
|
|
547
478
|
}
|
|
548
|
-
class
|
|
479
|
+
class oe {
|
|
549
480
|
constructor(r) {
|
|
550
|
-
this.options = r, r.path || (r.path =
|
|
481
|
+
this.options = r, r.path || (r.path = S.tmpdir()), process.env.TRANSFORMERS_CACHE = r.path, this.audio = new I(this), this.language = new H(this), this.vision = new J(this);
|
|
551
482
|
}
|
|
552
483
|
/** Audio processing AI */
|
|
553
484
|
audio;
|
|
@@ -556,38 +487,38 @@ class ae {
|
|
|
556
487
|
/** Vision processing AI */
|
|
557
488
|
vision;
|
|
558
489
|
}
|
|
559
|
-
const
|
|
490
|
+
const F = {
|
|
560
491
|
name: "cli",
|
|
561
492
|
description: "Use the command line interface, returns any output",
|
|
562
493
|
args: { command: { type: "string", description: "Command to run", required: !0 } },
|
|
563
|
-
fn: (
|
|
564
|
-
},
|
|
494
|
+
fn: (h) => W`${h.command}`
|
|
495
|
+
}, ie = {
|
|
565
496
|
name: "get_datetime",
|
|
566
497
|
description: "Get current UTC date / time",
|
|
567
498
|
args: {},
|
|
568
499
|
fn: async () => (/* @__PURE__ */ new Date()).toUTCString()
|
|
569
|
-
},
|
|
500
|
+
}, ae = {
|
|
570
501
|
name: "exec",
|
|
571
502
|
description: "Run code/scripts",
|
|
572
503
|
args: {
|
|
573
504
|
language: { type: "string", description: "Execution language", enum: ["cli", "node", "python"], required: !0 },
|
|
574
505
|
code: { type: "string", description: "Code to execute", required: !0 }
|
|
575
506
|
},
|
|
576
|
-
fn: async (
|
|
507
|
+
fn: async (h, r, e) => {
|
|
577
508
|
try {
|
|
578
|
-
switch (
|
|
509
|
+
switch (h.type) {
|
|
579
510
|
case "bash":
|
|
580
|
-
return await
|
|
511
|
+
return await F.fn({ command: h.code }, r, e);
|
|
581
512
|
case "node":
|
|
582
|
-
return await
|
|
513
|
+
return await G.fn({ code: h.code }, r, e);
|
|
583
514
|
case "python":
|
|
584
|
-
return await
|
|
515
|
+
return await B.fn({ code: h.code }, r, e);
|
|
585
516
|
}
|
|
586
517
|
} catch (t) {
|
|
587
518
|
return { error: t?.message || t.toString() };
|
|
588
519
|
}
|
|
589
520
|
}
|
|
590
|
-
},
|
|
521
|
+
}, ce = {
|
|
591
522
|
name: "fetch",
|
|
592
523
|
description: "Make HTTP request to URL",
|
|
593
524
|
args: {
|
|
@@ -596,85 +527,86 @@ const G = {
|
|
|
596
527
|
headers: { type: "object", description: "HTTP headers to send", default: {} },
|
|
597
528
|
body: { type: "object", description: "HTTP body to send" }
|
|
598
529
|
},
|
|
599
|
-
fn: (
|
|
600
|
-
},
|
|
530
|
+
fn: (h) => new q({ url: h.url, headers: h.headers }).request({ method: h.method || "GET", body: h.body })
|
|
531
|
+
}, G = {
|
|
601
532
|
name: "exec_javascript",
|
|
602
533
|
description: "Execute commonjs javascript",
|
|
603
534
|
args: {
|
|
604
535
|
code: { type: "string", description: "CommonJS javascript", required: !0 }
|
|
605
536
|
},
|
|
606
|
-
fn: async (
|
|
607
|
-
const r =
|
|
537
|
+
fn: async (h) => {
|
|
538
|
+
const r = M(null), e = await P({ console: r }, h.code, !0).catch((t) => r.output.error.push(t));
|
|
608
539
|
return { ...r.output, return: e, stdout: void 0, stderr: void 0 };
|
|
609
540
|
}
|
|
610
|
-
},
|
|
541
|
+
}, B = {
|
|
611
542
|
name: "exec_javascript",
|
|
612
543
|
description: "Execute commonjs javascript",
|
|
613
544
|
args: {
|
|
614
545
|
code: { type: "string", description: "CommonJS javascript", required: !0 }
|
|
615
546
|
},
|
|
616
|
-
fn: async (
|
|
617
|
-
},
|
|
547
|
+
fn: async (h) => ({ result: D`python -c "${h.code}"` })
|
|
548
|
+
}, le = {
|
|
618
549
|
name: "read_webpage",
|
|
619
550
|
description: "Extract clean, structured content from a webpage. Use after web_search to read specific URLs",
|
|
620
551
|
args: {
|
|
621
552
|
url: { type: "string", description: "URL to extract content from", required: !0 },
|
|
622
553
|
focus: { type: "string", description: 'Optional: What aspect to focus on (e.g., "pricing", "features", "contact info")' }
|
|
623
554
|
},
|
|
624
|
-
fn: async (
|
|
625
|
-
const r = await fetch(
|
|
626
|
-
throw new Error(`Failed to fetch: ${
|
|
627
|
-
}), e =
|
|
555
|
+
fn: async (h) => {
|
|
556
|
+
const r = await fetch(h.url, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" } }).then((n) => n.text()).catch((n) => {
|
|
557
|
+
throw new Error(`Failed to fetch: ${n.message}`);
|
|
558
|
+
}), e = C.load(r);
|
|
628
559
|
e('script, style, nav, footer, header, aside, iframe, noscript, [role="navigation"], [role="banner"], .ad, .ads, .cookie, .popup').remove();
|
|
629
560
|
const t = {
|
|
630
561
|
title: e('meta[property="og:title"]').attr("content") || e("title").text() || "",
|
|
631
562
|
description: e('meta[name="description"]').attr("content") || e('meta[property="og:description"]').attr("content") || ""
|
|
632
563
|
};
|
|
633
|
-
let
|
|
634
|
-
const
|
|
635
|
-
for (const
|
|
636
|
-
const
|
|
637
|
-
if (
|
|
638
|
-
|
|
564
|
+
let o = "";
|
|
565
|
+
const s = ["article", "main", '[role="main"]', ".content", ".post", ".entry", "body"];
|
|
566
|
+
for (const n of s) {
|
|
567
|
+
const i = e(n).first();
|
|
568
|
+
if (i.length && i.text().trim().length > 200) {
|
|
569
|
+
o = i.text();
|
|
639
570
|
break;
|
|
640
571
|
}
|
|
641
572
|
}
|
|
642
|
-
return
|
|
573
|
+
return o || (o = e("body").text()), o = o.replace(/\s+/g, " ").trim().slice(0, 8e3), { url: h.url, title: t.title.trim(), description: t.description.trim(), content: o, focus: h.focus };
|
|
643
574
|
}
|
|
644
|
-
},
|
|
575
|
+
}, me = {
|
|
645
576
|
name: "web_search",
|
|
646
577
|
description: "Use duckduckgo (anonymous) to find find relevant online resources. Returns a list of URLs that works great with the `read_webpage` tool",
|
|
647
578
|
args: {
|
|
648
579
|
query: { type: "string", description: "Search string", required: !0 },
|
|
649
580
|
length: { type: "string", description: "Number of results to return", default: 5 }
|
|
650
581
|
},
|
|
651
|
-
fn: async (
|
|
652
|
-
const r = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(
|
|
582
|
+
fn: async (h) => {
|
|
583
|
+
const r = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(h.query)}`, {
|
|
653
584
|
headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept-Language": "en-US,en;q=0.9" }
|
|
654
|
-
}).then((
|
|
585
|
+
}).then((s) => s.text());
|
|
655
586
|
let e, t = /<a .*?href="(.+?)".+?<\/a>/g;
|
|
656
|
-
const
|
|
587
|
+
const o = new $();
|
|
657
588
|
for (; (e = t.exec(r)) !== null; ) {
|
|
658
|
-
let
|
|
659
|
-
if (
|
|
589
|
+
let s = /uddg=(.+)&?/.exec(decodeURIComponent(e[1]))?.[1];
|
|
590
|
+
if (s && (s = decodeURIComponent(s)), s && o.add(s), o.size >= (h.length || 5)) break;
|
|
660
591
|
}
|
|
661
|
-
return
|
|
592
|
+
return o;
|
|
662
593
|
}
|
|
663
594
|
};
|
|
664
595
|
export {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
596
|
+
oe as Ai,
|
|
597
|
+
z as Anthropic,
|
|
598
|
+
I as Audio,
|
|
599
|
+
F as CliTool,
|
|
600
|
+
ie as DateTimeTool,
|
|
601
|
+
ae as ExecTool,
|
|
602
|
+
ce as FetchTool,
|
|
603
|
+
G as JSTool,
|
|
604
|
+
j as LLMProvider,
|
|
605
|
+
w as OpenAi,
|
|
606
|
+
B as PythonTool,
|
|
607
|
+
le as ReadWebpageTool,
|
|
608
|
+
J as Vision,
|
|
609
|
+
me as WebSearchTool,
|
|
610
|
+
L as canDiarization
|
|
679
611
|
};
|
|
680
612
|
//# sourceMappingURL=index.mjs.map
|