@ztimson/ai-utils 0.6.5 → 0.6.7
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/embedder.js +1 -1
- package/dist/embedder.js.map +1 -1
- package/dist/embedder.mjs +2 -5
- package/dist/embedder.mjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +18 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -277
- 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
|
|
3
|
-
import { Anthropic as
|
|
4
|
-
import { OpenAI as
|
|
5
|
-
import { Worker as
|
|
6
|
-
import { fileURLToPath as
|
|
7
|
-
import { join as
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import C from "wavefile";
|
|
12
|
-
import { createWorker as D } from "tesseract.js";
|
|
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 P, fn as M, ASet as $ } from "@ztimson/utils";
|
|
3
|
+
import { Anthropic as E } from "@anthropic-ai/sdk";
|
|
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";
|
|
10
|
+
import { createWorker as N } from "tesseract.js";
|
|
13
11
|
import "./embedder.mjs";
|
|
14
|
-
import * as
|
|
15
|
-
import { $ as
|
|
12
|
+
import * as C from "cheerio";
|
|
13
|
+
import { $ as D, $Sync as W } from "@ztimson/node-utils";
|
|
16
14
|
class j {
|
|
17
15
|
}
|
|
18
|
-
class
|
|
16
|
+
class z extends j {
|
|
19
17
|
constructor(r, e, t) {
|
|
20
|
-
super(), this.ai = r, this.apiToken = e, this.model = t, this.client = new
|
|
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 s =
|
|
27
|
+
const s = o.content?.filter((n) => n.type == "text").map((n) => n.text).join(`
|
|
30
28
|
|
|
31
29
|
`);
|
|
32
|
-
s && t.push({ timestamp: e, role:
|
|
30
|
+
s && t.push({ timestamp: e, role: o.role, content: s }), o.content.forEach((n) => {
|
|
33
31
|
if (n.type == "tool_use")
|
|
34
32
|
t.push({ timestamp: e, role: "tool", id: n.id, name: n.name, args: n.input, content: void 0 });
|
|
35
33
|
else if (n.type == "tool_result") {
|
|
36
|
-
const
|
|
37
|
-
|
|
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,9 +53,9 @@ class J extends j {
|
|
|
55
53
|
}
|
|
56
54
|
ask(r, e = {}) {
|
|
57
55
|
const t = new AbortController();
|
|
58
|
-
return Object.assign(new Promise(async (
|
|
56
|
+
return Object.assign(new Promise(async (o) => {
|
|
59
57
|
let s = this.fromStandard([...e.history || [], { role: "user", content: r, timestamp: Date.now() }]);
|
|
60
|
-
const n = e.tools || this.ai.options.llm?.tools || [],
|
|
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 || "",
|
|
@@ -67,7 +65,7 @@ class J extends j {
|
|
|
67
65
|
description: d.description,
|
|
68
66
|
input_schema: {
|
|
69
67
|
type: "object",
|
|
70
|
-
properties: d.args ?
|
|
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
|
|
@@ -75,58 +73,58 @@ class J extends j {
|
|
|
75
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
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
93
|
const l = c.delta.text;
|
|
96
|
-
|
|
97
|
-
} else c.delta.type === "input_json_delta" && (
|
|
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 l =
|
|
100
|
-
l.input != null && (l.input = l.input ?
|
|
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
|
-
s.push({ role: "assistant", content:
|
|
105
|
+
s.push({ role: "assistant", content: m.content });
|
|
108
106
|
const c = await Promise.all(d.map(async (l) => {
|
|
109
|
-
const
|
|
110
|
-
if (e.stream && e.stream({ tool: l.name }), !
|
|
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: l.id, content:
|
|
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
113
|
return { type: "tool_result", tool_use_id: l.id, is_error: !0, content: u?.message || u?.toString() || "Unknown" };
|
|
116
114
|
}
|
|
117
115
|
}));
|
|
118
|
-
s.push({ role: "user", content: c }),
|
|
116
|
+
s.push({ role: "user", content: c }), i.messages = s;
|
|
119
117
|
}
|
|
120
|
-
} while (!t.signal.aborted &&
|
|
121
|
-
s.push({ role: "assistant", content:
|
|
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
|
-
`) }), s = this.toStandard(s), e.stream && e.stream({ done: !0 }), e.history && e.history.splice(0, e.history.length, ...s),
|
|
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 _ extends j {
|
|
|
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
139
|
id: s.id,
|
|
142
140
|
name: s.function.name,
|
|
143
|
-
args:
|
|
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,7 +165,7 @@ class _ extends j {
|
|
|
167
165
|
content: t.error || t.content
|
|
168
166
|
});
|
|
169
167
|
else {
|
|
170
|
-
const { timestamp:
|
|
168
|
+
const { timestamp: o, ...s } = t;
|
|
171
169
|
e.push(s);
|
|
172
170
|
}
|
|
173
171
|
return e;
|
|
@@ -175,31 +173,31 @@ class _ extends j {
|
|
|
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
178
|
let n = this.fromStandard([...e.history || [], { role: "user", content: r, timestamp: Date.now() }]);
|
|
181
|
-
const
|
|
179
|
+
const i = e.tools || this.ai.options.llm?.tools || [], m = {
|
|
182
180
|
model: e.model || this.model,
|
|
183
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 ?
|
|
192
|
+
properties: c.args ? _(c.args, (l, p) => ({ ...p, required: void 0 })) : {},
|
|
195
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 (
|
|
200
|
+
if (a = await this.client.chat.completions.create(m).catch((l) => {
|
|
203
201
|
throw l.message += `
|
|
204
202
|
|
|
205
203
|
Messages:
|
|
@@ -207,44 +205,38 @@ ${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 l of
|
|
208
|
+
` }), a.choices = [{ message: { content: "", tool_calls: [] } }];
|
|
209
|
+
for await (const l of a) {
|
|
212
210
|
if (t.signal.aborted) break;
|
|
213
|
-
l.choices[0].delta.content && (
|
|
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
|
-
n.push(
|
|
219
|
-
const l = await Promise.all(c.map(async (
|
|
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 =
|
|
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
|
-
n.push(...l),
|
|
227
|
+
n.push(...l), m.messages = n;
|
|
230
228
|
}
|
|
231
|
-
} while (!t.signal.aborted &&
|
|
232
|
-
n.push({ role: "assistant", content:
|
|
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 I {
|
|
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 J(this.ai, t.token, e) : t.proto == "ollama" ? this.models[e] = new _(this.ai, t.host, "not-needed", e) : t.proto == "openai" && (this.models[e] = new _(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 B {
|
|
|
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
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 [l,
|
|
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: l ? this.cosineSimilarity(u.embeddings[0], l[0].embedding) : 1 })).filter((u) => u.score >= 0.8).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
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
299
|
return s(n);
|
|
308
|
-
}), { abort:
|
|
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
312
|
let s = 0, n = 0;
|
|
321
313
|
for (let u of r.toReversed())
|
|
322
314
|
if (n += this.estimateTokens(u.content), n < t) s++;
|
|
323
315
|
else break;
|
|
324
316
|
if (r.length <= s) return { history: r, memory: [] };
|
|
325
|
-
const
|
|
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,10 +332,10 @@ ${m.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 n = Math.sqrt(
|
|
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);
|
|
347
339
|
return n === 0 ? 0 : t / n;
|
|
348
340
|
}
|
|
349
341
|
/**
|
|
@@ -354,25 +346,25 @@ ${m.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 l =
|
|
359
|
-
return typeof c == "object" && !Array.isArray(c) ?
|
|
360
|
-
}) : [], n = (typeof r == "object" ?
|
|
361
|
-
`)).flatMap((
|
|
362
|
-
`]),
|
|
363
|
-
for (let
|
|
364
|
-
let
|
|
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;
|
|
365
357
|
for (; d < n.length; ) {
|
|
366
|
-
const l =
|
|
358
|
+
const l = a + (a ? " " : "") + n[d];
|
|
367
359
|
if (this.estimateTokens(l.replace(/\s*\n\s*/g, `
|
|
368
|
-
`)) > e &&
|
|
369
|
-
|
|
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,18 +374,19 @@ ${m.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
|
-
|
|
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 });
|
|
393
386
|
}), s = this.chunk(r, e, t);
|
|
394
|
-
return Promise.all(s.map(async (n,
|
|
395
|
-
index:
|
|
396
|
-
embedding: await
|
|
387
|
+
return Promise.all(s.map(async (n, i) => ({
|
|
388
|
+
index: i,
|
|
389
|
+
embedding: await o(n),
|
|
397
390
|
text: n,
|
|
398
391
|
tokens: this.estimateTokens(n)
|
|
399
392
|
})));
|
|
@@ -415,8 +408,8 @@ ${m.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 = (n,
|
|
419
|
-
return { avg: s.reduce((n,
|
|
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 @@ ${m.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
|
|
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,101 +434,30 @@ ${m.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 J {
|
|
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 s = [];
|
|
456
|
-
let n = -1, o = "";
|
|
457
|
-
return r.forEach((a) => {
|
|
458
|
-
const m = a.timestamp[0], d = e.find((l) => m >= l.start && m <= l.end), c = d ? t.get(d.speaker) : 1;
|
|
459
|
-
c !== n ? (o && s.push(`[speaker ${n}]: ${o.trim()}`), n = c, o = a.text) : o += a.text;
|
|
460
|
-
}), o && s.push(`[speaker ${n}]: ${o.trim()}`), s.join(`
|
|
461
|
-
`);
|
|
462
|
-
}
|
|
463
|
-
async canDiarization() {
|
|
464
|
-
return new Promise((r) => {
|
|
465
|
-
const e = k("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 s = "";
|
|
492
|
-
const n = k("python3", ["-c", e, r]);
|
|
493
|
-
n.stdout.on("data", (o) => s += o.toString()), n.stderr.on("data", (o) => console.error(o.toString())), n.on("close", (o) => {
|
|
494
|
-
if (o === 0)
|
|
495
|
-
try {
|
|
496
|
-
t(JSON.parse(s));
|
|
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
|
-
}), n.on("error", i);
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
441
|
asr(r, e = {}) {
|
|
506
|
-
const { model: t = this.ai.options.asr || "whisper-base", speaker:
|
|
442
|
+
const { model: t = this.ai.options.asr || "whisper-base", speaker: o = !1 } = e;
|
|
507
443
|
let s = !1;
|
|
508
444
|
const n = () => {
|
|
509
445
|
s = !0;
|
|
510
|
-
},
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
d.
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
l = new Float32Array(y.length);
|
|
520
|
-
for (let g = 0; g < y.length; g++) l[g] = (y[g] + T[g]) / 2;
|
|
521
|
-
} else
|
|
522
|
-
l = c;
|
|
523
|
-
if (s) return a(null);
|
|
524
|
-
const h = await this.whisperPipeline(l, { return_timestamps: i ? "word" : !1 });
|
|
525
|
-
if (!i) return a(h.text?.trim() || null);
|
|
526
|
-
if (s) return a(null);
|
|
527
|
-
const u = await this.runDiarization(r);
|
|
528
|
-
if (s) return a(null);
|
|
529
|
-
const f = this.combineSpeakerTranscript(h.chunks || [], u);
|
|
530
|
-
a(f);
|
|
531
|
-
} catch (d) {
|
|
532
|
-
m(d);
|
|
533
|
-
}
|
|
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({ file: r, model: t, speaker: o, modelDir: this.ai.options.path });
|
|
534
455
|
});
|
|
535
|
-
return Object.assign(
|
|
456
|
+
return Object.assign(i, { abort: n });
|
|
536
457
|
}
|
|
458
|
+
canDiarization = L;
|
|
537
459
|
}
|
|
538
|
-
class
|
|
460
|
+
class H {
|
|
539
461
|
constructor(r) {
|
|
540
462
|
this.ai = r;
|
|
541
463
|
}
|
|
@@ -546,17 +468,17 @@ class Q {
|
|
|
546
468
|
*/
|
|
547
469
|
ocr(r) {
|
|
548
470
|
let e;
|
|
549
|
-
const t = new Promise(async (
|
|
550
|
-
e = await
|
|
471
|
+
const t = new Promise(async (o) => {
|
|
472
|
+
e = await N(this.ai.options.ocr || "eng", 2, { cachePath: this.ai.options.path });
|
|
551
473
|
const { data: s } = await e.recognize(r);
|
|
552
|
-
await e.terminate(),
|
|
474
|
+
await e.terminate(), o(s.text.trim() || null);
|
|
553
475
|
});
|
|
554
476
|
return Object.assign(t, { abort: () => e?.terminate() });
|
|
555
477
|
}
|
|
556
478
|
}
|
|
557
|
-
class
|
|
479
|
+
class oe {
|
|
558
480
|
constructor(r) {
|
|
559
|
-
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 J(this), this.language = new I(this), this.vision = new H(this);
|
|
560
482
|
}
|
|
561
483
|
/** Audio processing AI */
|
|
562
484
|
audio;
|
|
@@ -565,38 +487,38 @@ class me {
|
|
|
565
487
|
/** Vision processing AI */
|
|
566
488
|
vision;
|
|
567
489
|
}
|
|
568
|
-
const
|
|
490
|
+
const F = {
|
|
569
491
|
name: "cli",
|
|
570
492
|
description: "Use the command line interface, returns any output",
|
|
571
493
|
args: { command: { type: "string", description: "Command to run", required: !0 } },
|
|
572
|
-
fn: (
|
|
573
|
-
},
|
|
494
|
+
fn: (h) => D`${h.command}`
|
|
495
|
+
}, ie = {
|
|
574
496
|
name: "get_datetime",
|
|
575
497
|
description: "Get current UTC date / time",
|
|
576
498
|
args: {},
|
|
577
499
|
fn: async () => (/* @__PURE__ */ new Date()).toUTCString()
|
|
578
|
-
},
|
|
500
|
+
}, ae = {
|
|
579
501
|
name: "exec",
|
|
580
502
|
description: "Run code/scripts",
|
|
581
503
|
args: {
|
|
582
504
|
language: { type: "string", description: "Execution language", enum: ["cli", "node", "python"], required: !0 },
|
|
583
505
|
code: { type: "string", description: "Code to execute", required: !0 }
|
|
584
506
|
},
|
|
585
|
-
fn: async (
|
|
507
|
+
fn: async (h, r, e) => {
|
|
586
508
|
try {
|
|
587
|
-
switch (
|
|
509
|
+
switch (h.type) {
|
|
588
510
|
case "bash":
|
|
589
|
-
return await
|
|
511
|
+
return await F.fn({ command: h.code }, r, e);
|
|
590
512
|
case "node":
|
|
591
|
-
return await
|
|
513
|
+
return await G.fn({ code: h.code }, r, e);
|
|
592
514
|
case "python":
|
|
593
|
-
return await
|
|
515
|
+
return await B.fn({ code: h.code }, r, e);
|
|
594
516
|
}
|
|
595
517
|
} catch (t) {
|
|
596
518
|
return { error: t?.message || t.toString() };
|
|
597
519
|
}
|
|
598
520
|
}
|
|
599
|
-
},
|
|
521
|
+
}, ce = {
|
|
600
522
|
name: "fetch",
|
|
601
523
|
description: "Make HTTP request to URL",
|
|
602
524
|
args: {
|
|
@@ -605,85 +527,86 @@ const K = {
|
|
|
605
527
|
headers: { type: "object", description: "HTTP headers to send", default: {} },
|
|
606
528
|
body: { type: "object", description: "HTTP body to send" }
|
|
607
529
|
},
|
|
608
|
-
fn: (
|
|
609
|
-
},
|
|
530
|
+
fn: (h) => new q({ url: h.url, headers: h.headers }).request({ method: h.method || "GET", body: h.body })
|
|
531
|
+
}, G = {
|
|
610
532
|
name: "exec_javascript",
|
|
611
533
|
description: "Execute commonjs javascript",
|
|
612
534
|
args: {
|
|
613
535
|
code: { type: "string", description: "CommonJS javascript", required: !0 }
|
|
614
536
|
},
|
|
615
|
-
fn: async (
|
|
616
|
-
const r =
|
|
537
|
+
fn: async (h) => {
|
|
538
|
+
const r = P(null), e = await M({ console: r }, h.code, !0).catch((t) => r.output.error.push(t));
|
|
617
539
|
return { ...r.output, return: e, stdout: void 0, stderr: void 0 };
|
|
618
540
|
}
|
|
619
|
-
},
|
|
541
|
+
}, B = {
|
|
620
542
|
name: "exec_javascript",
|
|
621
543
|
description: "Execute commonjs javascript",
|
|
622
544
|
args: {
|
|
623
545
|
code: { type: "string", description: "CommonJS javascript", required: !0 }
|
|
624
546
|
},
|
|
625
|
-
fn: async (
|
|
626
|
-
},
|
|
547
|
+
fn: async (h) => ({ result: W`python -c "${h.code}"` })
|
|
548
|
+
}, le = {
|
|
627
549
|
name: "read_webpage",
|
|
628
550
|
description: "Extract clean, structured content from a webpage. Use after web_search to read specific URLs",
|
|
629
551
|
args: {
|
|
630
552
|
url: { type: "string", description: "URL to extract content from", required: !0 },
|
|
631
553
|
focus: { type: "string", description: 'Optional: What aspect to focus on (e.g., "pricing", "features", "contact info")' }
|
|
632
554
|
},
|
|
633
|
-
fn: async (
|
|
634
|
-
const r = await fetch(
|
|
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) => {
|
|
635
557
|
throw new Error(`Failed to fetch: ${n.message}`);
|
|
636
|
-
}), e =
|
|
558
|
+
}), e = C.load(r);
|
|
637
559
|
e('script, style, nav, footer, header, aside, iframe, noscript, [role="navigation"], [role="banner"], .ad, .ads, .cookie, .popup').remove();
|
|
638
560
|
const t = {
|
|
639
561
|
title: e('meta[property="og:title"]').attr("content") || e("title").text() || "",
|
|
640
562
|
description: e('meta[name="description"]').attr("content") || e('meta[property="og:description"]').attr("content") || ""
|
|
641
563
|
};
|
|
642
|
-
let
|
|
564
|
+
let o = "";
|
|
643
565
|
const s = ["article", "main", '[role="main"]', ".content", ".post", ".entry", "body"];
|
|
644
566
|
for (const n of s) {
|
|
645
|
-
const
|
|
646
|
-
if (
|
|
647
|
-
|
|
567
|
+
const i = e(n).first();
|
|
568
|
+
if (i.length && i.text().trim().length > 200) {
|
|
569
|
+
o = i.text();
|
|
648
570
|
break;
|
|
649
571
|
}
|
|
650
572
|
}
|
|
651
|
-
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 };
|
|
652
574
|
}
|
|
653
|
-
},
|
|
575
|
+
}, me = {
|
|
654
576
|
name: "web_search",
|
|
655
577
|
description: "Use duckduckgo (anonymous) to find find relevant online resources. Returns a list of URLs that works great with the `read_webpage` tool",
|
|
656
578
|
args: {
|
|
657
579
|
query: { type: "string", description: "Search string", required: !0 },
|
|
658
580
|
length: { type: "string", description: "Number of results to return", default: 5 }
|
|
659
581
|
},
|
|
660
|
-
fn: async (
|
|
661
|
-
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)}`, {
|
|
662
584
|
headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept-Language": "en-US,en;q=0.9" }
|
|
663
585
|
}).then((s) => s.text());
|
|
664
586
|
let e, t = /<a .*?href="(.+?)".+?<\/a>/g;
|
|
665
|
-
const
|
|
587
|
+
const o = new $();
|
|
666
588
|
for (; (e = t.exec(r)) !== null; ) {
|
|
667
589
|
let s = /uddg=(.+)&?/.exec(decodeURIComponent(e[1]))?.[1];
|
|
668
|
-
if (s && (s = decodeURIComponent(s)), s &&
|
|
590
|
+
if (s && (s = decodeURIComponent(s)), s && o.add(s), o.size >= (h.length || 5)) break;
|
|
669
591
|
}
|
|
670
|
-
return
|
|
592
|
+
return o;
|
|
671
593
|
}
|
|
672
594
|
};
|
|
673
595
|
export {
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
596
|
+
oe as Ai,
|
|
597
|
+
z as Anthropic,
|
|
598
|
+
J as Audio,
|
|
599
|
+
F as CliTool,
|
|
600
|
+
ie as DateTimeTool,
|
|
601
|
+
ae as ExecTool,
|
|
602
|
+
ce as FetchTool,
|
|
603
|
+
G as JSTool,
|
|
682
604
|
j as LLMProvider,
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
605
|
+
w as OpenAi,
|
|
606
|
+
B as PythonTool,
|
|
607
|
+
le as ReadWebpageTool,
|
|
608
|
+
H as Vision,
|
|
609
|
+
me as WebSearchTool,
|
|
610
|
+
L as canDiarization
|
|
688
611
|
};
|
|
689
612
|
//# sourceMappingURL=index.mjs.map
|