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