@ztimson/ai-utils 0.1.20 → 0.1.22

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,16 +1,16 @@
1
- import { createWorker as T } from "tesseract.js";
2
- import { objectMap as k, JSONAttemptParse as y, findByProp as x, JSONSanitize as b, Http as q, consoleInterceptor as v, fn as P, ASet as A } from "@ztimson/utils";
1
+ import { createWorker as j } from "tesseract.js";
2
+ import { deepCopy as T, objectMap as b, JSONAttemptParse as _, findByProp as k, JSONSanitize as y, Http as q, consoleInterceptor as v, fn as P, ASet as A } from "@ztimson/utils";
3
3
  import { Anthropic as E } from "@anthropic-ai/sdk";
4
4
  import { Ollama as M } from "ollama";
5
5
  import { OpenAI as O } from "openai";
6
- import j from "node:fs/promises";
7
- import D from "node:path";
8
- import * as _ from "@tensorflow/tfjs";
9
- import { spawn as U } from "node:child_process";
10
- import { $, $Sync as L } from "@ztimson/node-utils";
11
- class S {
6
+ import S from "node:fs/promises";
7
+ import U from "node:path";
8
+ import * as w from "@tensorflow/tfjs";
9
+ import { spawn as $ } from "node:child_process";
10
+ import { $ as L, $Sync as R } from "@ztimson/node-utils";
11
+ class x {
12
12
  }
13
- class R extends S {
13
+ class D extends x {
14
14
  constructor(t, e, n) {
15
15
  super(), this.ai = t, this.apiToken = e, this.model = n, this.client = new E({ apiKey: e });
16
16
  }
@@ -18,12 +18,12 @@ class R extends S {
18
18
  toStandard(t) {
19
19
  for (let e = 0; e < t.length; e++) {
20
20
  const n = e;
21
- typeof t[n].content != "string" && (t[n].role == "assistant" ? t[n].content.filter((o) => o.type == "tool_use").forEach((o) => {
22
- e++, t.splice(e, 0, { role: "tool", id: o.id, name: o.name, args: o.input, timestamp: Date.now() });
23
- }) : t[n].role == "user" && t[n].content.filter((o) => o.type == "tool_result").forEach((o) => {
24
- const c = t.find((f) => f.id == o.tool_use_id);
25
- c[o.is_error ? "error" : "content"] = o.content;
26
- }), t[n].content = t[n].content.filter((o) => o.type == "text").map((o) => o.text).join(`
21
+ typeof t[n].content != "string" && (t[n].role == "assistant" ? t[n].content.filter((a) => a.type == "tool_use").forEach((a) => {
22
+ e++, t.splice(e, 0, { role: "tool", id: a.id, name: a.name, args: a.input, timestamp: Date.now() });
23
+ }) : t[n].role == "user" && t[n].content.filter((a) => a.type == "tool_result").forEach((a) => {
24
+ const c = t.find((f) => f.id == a.tool_use_id);
25
+ c[a.is_error ? "error" : "content"] = a.content;
26
+ }), t[n].content = t[n].content.filter((a) => a.type == "text").map((a) => a.text).join(`
27
27
 
28
28
  `)), t[n].timestamp || (t[n].timestamp = Date.now());
29
29
  }
@@ -43,78 +43,74 @@ class R extends S {
43
43
  return t.map(({ timestamp: e, ...n }) => n);
44
44
  }
45
45
  ask(t, e = {}) {
46
- const n = new AbortController(), o = new Promise(async (c, f) => {
47
- let l = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
48
- e.compress && (l = await this.ai.llm.compress(l, e.compress.max, e.compress.min, e));
46
+ const n = new AbortController(), a = new Promise(async (c, f) => {
47
+ let i = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
48
+ const l = T(i);
49
+ e.compress && (i = await this.ai.llm.compress(i, e.compress.max, e.compress.min, e));
49
50
  const m = {
50
51
  model: e.model || this.model,
51
52
  max_tokens: e.max_tokens || this.ai.options.max_tokens || 4096,
52
53
  system: e.system || this.ai.options.system || "",
53
54
  temperature: e.temperature || this.ai.options.temperature || 0.7,
54
- tools: (e.tools || this.ai.options.tools || []).map((p) => ({
55
- name: p.name,
56
- description: p.description,
55
+ tools: (e.tools || this.ai.options.tools || []).map((o) => ({
56
+ name: o.name,
57
+ description: o.description,
57
58
  input_schema: {
58
59
  type: "object",
59
- properties: p.args ? k(p.args, (d, s) => ({ ...s, required: void 0 })) : {},
60
- required: p.args ? Object.entries(p.args).filter((d) => d[1].required).map((d) => d[0]) : []
60
+ properties: o.args ? b(o.args, (r, u) => ({ ...u, required: void 0 })) : {},
61
+ required: o.args ? Object.entries(o.args).filter((r) => r[1].required).map((r) => r[0]) : []
61
62
  },
62
63
  fn: void 0
63
64
  })),
64
- messages: l,
65
+ messages: i,
65
66
  stream: !!e.stream
66
67
  };
67
- let i;
68
- const r = [];
68
+ let s, p = !0;
69
69
  do {
70
- if (i = await this.client.messages.create(m), e.stream) {
71
- r.length && e.stream({ text: `
70
+ if (s = await this.client.messages.create(m), e.stream) {
71
+ p ? p = !1 : e.stream({ text: `
72
72
 
73
- ` }), i.content = [];
74
- for await (const s of i) {
73
+ ` }), s.content = [];
74
+ for await (const r of s) {
75
75
  if (n.signal.aborted) break;
76
- if (s.type === "content_block_start")
77
- s.content_block.type === "text" ? i.content.push({ type: "text", text: "" }) : s.content_block.type === "tool_use" && i.content.push({ type: "tool_use", id: s.content_block.id, name: s.content_block.name, input: "" });
78
- else if (s.type === "content_block_delta")
79
- if (s.delta.type === "text_delta") {
80
- const a = s.delta.text;
81
- i.content.at(-1).text += a, e.stream({ text: a });
82
- } else s.delta.type === "input_json_delta" && (i.content.at(-1).input += s.delta.partial_json);
83
- else if (s.type === "content_block_stop") {
84
- const a = i.content.at(-1);
85
- a.input != null && (a.input = a.input ? y(a.input, {}) : {});
86
- } else if (s.type === "message_stop")
76
+ if (r.type === "content_block_start")
77
+ r.content_block.type === "text" ? s.content.push({ type: "text", text: "" }) : r.content_block.type === "tool_use" && s.content.push({ type: "tool_use", id: r.content_block.id, name: r.content_block.name, input: "" });
78
+ else if (r.type === "content_block_delta")
79
+ if (r.delta.type === "text_delta") {
80
+ const u = r.delta.text;
81
+ s.content.at(-1).text += u, e.stream({ text: u });
82
+ } else r.delta.type === "input_json_delta" && (s.content.at(-1).input += r.delta.partial_json);
83
+ else if (r.type === "content_block_stop") {
84
+ const u = s.content.at(-1);
85
+ u.input != null && (u.input = u.input ? _(u.input, {}) : {});
86
+ } else if (r.type === "message_stop")
87
87
  break;
88
88
  }
89
89
  }
90
- const p = i.content.filter((s) => s.type == "text").map((s) => s.text).join(`
91
-
92
- `);
93
- p && r.push(p);
94
- const d = i.content.filter((s) => s.type === "tool_use");
95
- if (d.length && !n.signal.aborted) {
96
- l.push({ role: "assistant", content: i.content });
97
- const s = await Promise.all(d.map(async (a) => {
98
- const g = e.tools?.find(x("name", a.name));
99
- if (!g) return { tool_use_id: a.id, is_error: !0, content: "Tool not found" };
90
+ const o = s.content.filter((r) => r.type === "tool_use");
91
+ if (o.length && !n.signal.aborted) {
92
+ i.push({ role: "assistant", content: s.content }), l.push({ role: "assistant", content: s.content });
93
+ const r = await Promise.all(o.map(async (u) => {
94
+ const h = e.tools?.find(k("name", u.name));
95
+ if (!h) return { tool_use_id: u.id, is_error: !0, content: "Tool not found" };
100
96
  try {
101
- const h = await g.fn(a.input, this.ai);
102
- return { type: "tool_result", tool_use_id: a.id, content: b(h) };
103
- } catch (h) {
104
- return { type: "tool_result", tool_use_id: a.id, is_error: !0, content: h?.message || h?.toString() || "Unknown" };
97
+ const g = await h.fn(u.input, this.ai);
98
+ return { type: "tool_result", tool_use_id: u.id, content: y(g) };
99
+ } catch (g) {
100
+ return { type: "tool_result", tool_use_id: u.id, is_error: !0, content: g?.message || g?.toString() || "Unknown" };
105
101
  }
106
102
  }));
107
- l.push({ role: "user", content: s }), m.messages = l;
103
+ i.push({ role: "user", content: r }), m.messages = i;
108
104
  }
109
- } while (!n.signal.aborted && i.content.some((p) => p.type === "tool_use"));
110
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...l, { role: "assistant", content: r.join(`
105
+ } while (!n.signal.aborted && s.content.some((o) => o.type === "tool_use"));
106
+ e.stream && e.stream({ done: !0 }), c(this.toStandard([...i, { role: "assistant", content: s.content.filter((o) => o.type == "text").map((o) => o.text).join(`
111
107
 
112
- `), timestamp: Date.now() }]));
108
+ `) }]));
113
109
  });
114
- return Object.assign(o, { abort: () => n.abort() });
110
+ return Object.assign(a, { abort: () => n.abort() });
115
111
  }
116
112
  }
117
- class I extends S {
113
+ class I extends x {
118
114
  constructor(t, e, n) {
119
115
  super(), this.ai = t, this.host = e, this.model = n, this.client = new M({ host: e });
120
116
  }
@@ -133,71 +129,67 @@ class I extends S {
133
129
  }
134
130
  fromStandard(t) {
135
131
  return t.map((e) => {
136
- const { timestamp: n, ...o } = e;
137
- return e.role != "tool" ? o : { role: "tool", tool_name: e.name, content: e.error || e.content };
132
+ const { timestamp: n, ...a } = e;
133
+ return e.role != "tool" ? a : { role: "tool", tool_name: e.name, content: e.error || e.content };
138
134
  });
139
135
  }
140
136
  ask(t, e = {}) {
141
- const n = new AbortController(), o = new Promise(async (c, f) => {
142
- let l = e.system || this.ai.options.system, m = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
143
- m[0].roll == "system" && (l ? m.shift() : l = m.shift()), e.compress && (m = await this.ai.llm.compress(m, e.compress.max, e.compress.min)), e.system && m.unshift({ role: "system", content: l });
144
- const i = {
137
+ const n = new AbortController(), a = new Promise(async (c, f) => {
138
+ let i = e.system || this.ai.options.system, l = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
139
+ l[0].roll == "system" && (i ? l.shift() : i = l.shift()), e.compress && (l = await this.ai.llm.compress(l, e.compress.max, e.compress.min)), e.system && l.unshift({ role: "system", content: i });
140
+ const m = {
145
141
  model: e.model || this.model,
146
- messages: m,
142
+ messages: l,
147
143
  stream: !!e.stream,
148
144
  signal: n.signal,
149
145
  options: {
150
146
  temperature: e.temperature || this.ai.options.temperature || 0.7,
151
147
  num_predict: e.max_tokens || this.ai.options.max_tokens || 4096
152
148
  },
153
- tools: (e.tools || this.ai.options.tools || []).map((s) => ({
149
+ tools: (e.tools || this.ai.options.tools || []).map((o) => ({
154
150
  type: "function",
155
151
  function: {
156
- name: s.name,
157
- description: s.description,
152
+ name: o.name,
153
+ description: o.description,
158
154
  parameters: {
159
155
  type: "object",
160
- properties: s.args ? k(s.args, (a, g) => ({ ...g, required: void 0 })) : {},
161
- required: s.args ? Object.entries(s.args).filter((a) => a[1].required).map((a) => a[0]) : []
156
+ properties: o.args ? b(o.args, (r, u) => ({ ...u, required: void 0 })) : {},
157
+ required: o.args ? Object.entries(o.args).filter((r) => r[1].required).map((r) => r[0]) : []
162
158
  }
163
159
  }
164
160
  }))
165
161
  };
166
- let r;
167
- const p = [];
162
+ let s, p = !0;
168
163
  do {
169
- if (r = await this.client.chat(i), e.stream) {
170
- p.length && e.stream({ text: `
164
+ if (s = await this.client.chat(m), e.stream) {
165
+ p ? p = !1 : e.stream({ text: `
171
166
 
172
- ` }), r.message = { role: "assistant", content: "", tool_calls: [] };
173
- for await (const s of r)
174
- if (n.signal.aborted || (s.message?.content && (r.message.content += s.message.content, e.stream({ text: s.message.content })), s.message?.tool_calls && (r.message.tool_calls = s.message.tool_calls), s.done)) break;
167
+ ` }), s.message = { role: "assistant", content: "", tool_calls: [] };
168
+ for await (const o of s)
169
+ if (n.signal.aborted || (o.message?.content && (s.message.content += o.message.content, e.stream({ text: o.message.content })), o.message?.tool_calls && (s.message.tool_calls = o.message.tool_calls), o.done)) break;
175
170
  }
176
- if (p.push({ role: "assistant", content: r.message?.content, timestamp: Date.now() }), r.message?.tool_calls?.length && !n.signal.aborted) {
177
- m.push(r.message);
178
- const s = await Promise.all(r.message.tool_calls.map(async (a) => {
179
- const g = (e.tools || this.ai.options.tools)?.find(x("name", a.function.name));
180
- if (!g) return { role: "tool", tool_name: a.function.name, content: '{"error": "Tool not found"}' };
181
- const h = typeof a.function.arguments == "string" ? y(a.function.arguments, {}) : a.function.arguments;
171
+ if (s.message?.tool_calls?.length && !n.signal.aborted) {
172
+ l.push(s.message);
173
+ const o = await Promise.all(s.message.tool_calls.map(async (r) => {
174
+ const u = (e.tools || this.ai.options.tools)?.find(k("name", r.function.name));
175
+ if (!u) return { role: "tool", tool_name: r.function.name, content: '{"error": "Tool not found"}' };
176
+ const h = typeof r.function.arguments == "string" ? _(r.function.arguments, {}) : r.function.arguments;
182
177
  try {
183
- const w = await g.fn(h, this.ai);
184
- return { role: "tool", tool_name: a.function.name, args: h, content: b(w) };
185
- } catch (w) {
186
- return { role: "tool", tool_name: a.function.name, args: h, content: b({ error: w?.message || w?.toString() || "Unknown" }) };
178
+ const g = await u.fn(h, this.ai);
179
+ return { role: "tool", tool_name: r.function.name, args: h, content: y(g) };
180
+ } catch (g) {
181
+ return { role: "tool", tool_name: r.function.name, args: h, content: y({ error: g?.message || g?.toString() || "Unknown" }) };
187
182
  }
188
183
  }));
189
- m.push(...s), p.push(...s.map((a) => ({ ...a, timestamp: Date.now() }))), i.messages = m;
184
+ l.push(...o), m.messages = l;
190
185
  }
191
- } while (!n.signal.aborted && r.message?.tool_calls?.length);
192
- const d = p.filter((s) => s.role === "assistant").map((s) => s.content).filter((s) => s).join(`
193
-
194
- `);
195
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...m, { role: "assistant", content: d, timestamp: Date.now() }]));
186
+ } while (!n.signal.aborted && s.message?.tool_calls?.length);
187
+ e.stream && e.stream({ done: !0 }), c(this.toStandard([...l, { role: "assistant", content: s.message?.content }]));
196
188
  });
197
- return Object.assign(o, { abort: () => n.abort() });
189
+ return Object.assign(a, { abort: () => n.abort() });
198
190
  }
199
191
  }
200
- class J extends S {
192
+ class J extends x {
201
193
  constructor(t, e, n) {
202
194
  super(), this.ai = t, this.apiToken = e, this.model = n, this.client = new O({ apiKey: e });
203
195
  }
@@ -206,17 +198,17 @@ class J extends S {
206
198
  for (let e = 0; e < t.length; e++) {
207
199
  const n = t[e];
208
200
  if (n.role === "assistant" && n.tool_calls) {
209
- const o = n.tool_calls.map((c) => ({
201
+ const a = n.tool_calls.map((c) => ({
210
202
  role: "tool",
211
203
  id: c.id,
212
204
  name: c.function.name,
213
- args: y(c.function.arguments, {}),
205
+ args: _(c.function.arguments, {}),
214
206
  timestamp: n.timestamp
215
207
  }));
216
- t.splice(e, 1, ...o), e += o.length - 1;
208
+ t.splice(e, 1, ...a), e += a.length - 1;
217
209
  } else if (n.role === "tool" && n.content) {
218
- const o = t.find((c) => n.tool_call_id == c.id);
219
- o && (n.content.includes('"error":') ? o.error = n.content : o.content = n.content), t.splice(e, 1), e--;
210
+ const a = t.find((c) => n.tool_call_id == c.id);
211
+ a && (n.content.includes('"error":') ? a.error = n.content : a.content = n.content), t.splice(e, 1), e--;
220
212
  }
221
213
  t[e]?.timestamp || (t[e].timestamp = Date.now());
222
214
  }
@@ -237,75 +229,70 @@ class J extends S {
237
229
  content: n.error || n.content
238
230
  });
239
231
  else {
240
- const { timestamp: o, ...c } = n;
232
+ const { timestamp: a, ...c } = n;
241
233
  e.push(c);
242
234
  }
243
235
  return e;
244
236
  }, []);
245
237
  }
246
238
  ask(t, e = {}) {
247
- const n = new AbortController(), o = new Promise(async (c, f) => {
248
- let l = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
249
- e.compress && (l = await this.ai.llm.compress(l, e.compress.max, e.compress.min, e));
250
- const m = {
239
+ const n = new AbortController(), a = new Promise(async (c, f) => {
240
+ let i = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
241
+ e.compress && (i = await this.ai.llm.compress(i, e.compress.max, e.compress.min, e));
242
+ const l = {
251
243
  model: e.model || this.model,
252
- messages: l,
244
+ messages: i,
253
245
  stream: !!e.stream,
254
246
  max_tokens: e.max_tokens || this.ai.options.max_tokens || 4096,
255
247
  temperature: e.temperature || this.ai.options.temperature || 0.7,
256
- tools: (e.tools || this.ai.options.tools || []).map((d) => ({
248
+ tools: (e.tools || this.ai.options.tools || []).map((p) => ({
257
249
  type: "function",
258
250
  function: {
259
- name: d.name,
260
- description: d.description,
251
+ name: p.name,
252
+ description: p.description,
261
253
  parameters: {
262
254
  type: "object",
263
- properties: d.args ? k(d.args, (s, a) => ({ ...a, required: void 0 })) : {},
264
- required: d.args ? Object.entries(d.args).filter((s) => s[1].required).map((s) => s[0]) : []
255
+ properties: p.args ? b(p.args, (o, r) => ({ ...r, required: void 0 })) : {},
256
+ required: p.args ? Object.entries(p.args).filter((o) => o[1].required).map((o) => o[0]) : []
265
257
  }
266
258
  }
267
259
  }))
268
260
  };
269
- let i;
270
- const r = [];
261
+ let m, s = !0;
271
262
  do {
272
- if (i = await this.client.chat.completions.create(m), e.stream) {
273
- r.length && e.stream({ text: `
263
+ if (m = await this.client.chat.completions.create(l), e.stream) {
264
+ s ? s = !1 : e.stream({ text: `
274
265
 
275
- ` }), i.choices = [{ message: { content: "", tool_calls: [] } }];
276
- for await (const s of i) {
266
+ ` }), m.choices = [{ message: { content: "", tool_calls: [] } }];
267
+ for await (const o of m) {
277
268
  if (n.signal.aborted) break;
278
- s.choices[0].delta.content && (i.choices[0].message.content += s.choices[0].delta.content, e.stream({ text: s.choices[0].delta.content })), s.choices[0].delta.tool_calls && (i.choices[0].message.tool_calls = s.choices[0].delta.tool_calls);
269
+ o.choices[0].delta.content && (m.choices[0].message.content += o.choices[0].delta.content, e.stream({ text: o.choices[0].delta.content })), o.choices[0].delta.tool_calls && (m.choices[0].message.tool_calls = o.choices[0].delta.tool_calls);
279
270
  }
280
271
  }
281
- r.push({ role: "assistant", content: i.choices[0].message.content || "", timestamp: Date.now() });
282
- const d = i.choices[0].message.tool_calls || [];
283
- if (d.length && !n.signal.aborted) {
284
- l.push(i.choices[0].message);
285
- const s = await Promise.all(d.map(async (a) => {
286
- const g = e.tools?.find(x("name", a.function.name));
287
- if (!g) return { role: "tool", tool_call_id: a.id, content: '{"error": "Tool not found"}' };
272
+ const p = m.choices[0].message.tool_calls || [];
273
+ if (p.length && !n.signal.aborted) {
274
+ i.push(m.choices[0].message);
275
+ const o = await Promise.all(p.map(async (r) => {
276
+ const u = e.tools?.find(k("name", r.function.name));
277
+ if (!u) return { role: "tool", tool_call_id: r.id, content: '{"error": "Tool not found"}' };
288
278
  try {
289
- const h = y(a.function.arguments, {}), w = await g.fn(h, this.ai);
290
- return { role: "tool", tool_call_id: a.id, content: b(w) };
279
+ const h = _(r.function.arguments, {}), g = await u.fn(h, this.ai);
280
+ return { role: "tool", tool_call_id: r.id, content: y(g) };
291
281
  } catch (h) {
292
- return { role: "tool", tool_call_id: a.id, content: b({ error: h?.message || h?.toString() || "Unknown" }) };
282
+ return { role: "tool", tool_call_id: r.id, content: y({ error: h?.message || h?.toString() || "Unknown" }) };
293
283
  }
294
284
  }));
295
- l.push(...s), r.push(...s.map((a) => ({ ...a, timestamp: Date.now() }))), m.messages = l;
285
+ i.push(...o), l.messages = i;
296
286
  }
297
- } while (!n.signal.aborted && i.choices?.[0]?.message?.tool_calls?.length);
298
- const p = r.filter((d) => d.role === "assistant").map((d) => d.content).filter((d) => d).join(`
299
-
300
- `);
301
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...l, { role: "assistant", content: p, timestamp: Date.now() }]));
287
+ } while (!n.signal.aborted && m.choices?.[0]?.message?.tool_calls?.length);
288
+ e.stream && e.stream({ done: !0 }), c(this.toStandard([...i, { role: "assistant", content: m.choices[0].message.content || "" }]));
302
289
  });
303
- return Object.assign(o, { abort: () => n.abort() });
290
+ return Object.assign(a, { abort: () => n.abort() });
304
291
  }
305
292
  }
306
293
  class W {
307
294
  constructor(t, e) {
308
- this.ai = t, this.options = e, e.anthropic?.token && (this.providers.anthropic = new R(this.ai, e.anthropic.token, e.anthropic.model)), e.ollama?.host && (this.providers.ollama = new I(this.ai, e.ollama.host, e.ollama.model)), e.openAi?.token && (this.providers.openAi = new J(this.ai, e.openAi.token, e.openAi.model));
295
+ this.ai = t, this.options = e, e.anthropic?.token && (this.providers.anthropic = new D(this.ai, e.anthropic.token, e.anthropic.model)), e.ollama?.host && (this.providers.ollama = new I(this.ai, e.ollama.host, e.ollama.model)), e.openAi?.token && (this.providers.openAi = new J(this.ai, e.openAi.token, e.openAi.model));
309
296
  }
310
297
  providers = {};
311
298
  /**
@@ -327,17 +314,17 @@ class W {
327
314
  * @param {LLMRequest} options LLM options
328
315
  * @returns {Promise<LLMMessage[]>} New chat history will summary at index 0
329
316
  */
330
- async compress(t, e, n, o) {
317
+ async compress(t, e, n, a) {
331
318
  if (this.estimateTokens(t) < e) return t;
332
319
  let c = 0, f = 0;
333
- for (let r of t.toReversed())
334
- if (f += this.estimateTokens(r.content), f < n) c++;
320
+ for (let s of t.toReversed())
321
+ if (f += this.estimateTokens(s.content), f < n) c++;
335
322
  else break;
336
323
  if (t.length <= c) return t;
337
- const l = c == 0 ? [] : t.slice(-c), m = (c == 0 ? t : t.slice(0, -c)).filter((r) => r.role === "assistant" || r.role === "user");
338
- return [{ role: "assistant", content: `Conversation Summary: ${await this.summarize(m.map((r) => `${r.role}: ${r.content}`).join(`
324
+ const i = c == 0 ? [] : t.slice(-c), l = (c == 0 ? t : t.slice(0, -c)).filter((s) => s.role === "assistant" || s.role === "user");
325
+ return [{ role: "assistant", content: `Conversation Summary: ${await this.summarize(l.map((s) => `${s.role}: ${s.content}`).join(`
339
326
 
340
- `), 250, o)}`, timestamp: Date.now() }, ...l];
327
+ `), 250, a)}`, timestamp: Date.now() }, ...i];
341
328
  }
342
329
  /**
343
330
  * Estimate variable as tokens
@@ -359,7 +346,7 @@ class W {
359
346
  system: "Respond using a JSON blob",
360
347
  ...e
361
348
  });
362
- return n?.[0]?.content ? y(new RegExp("{[sS]*}").exec(n[0].content), {}) : {};
349
+ return n?.[0]?.content ? _(new RegExp("{[sS]*}").exec(n[0].content), {}) : {};
363
350
  }
364
351
  /**
365
352
  * Create a summary of some text
@@ -369,7 +356,7 @@ class W {
369
356
  * @returns {Promise<string>} Summary
370
357
  */
371
358
  summarize(t, e, n) {
372
- return this.ask(t, { system: `Generate a brief summary <= ${e} tokens. Output nothing else`, temperature: 0.3, ...n }).then((o) => o.pop()?.content || null);
359
+ return this.ask(t, { system: `Generate a brief summary <= ${e} tokens. Output nothing else`, temperature: 0.3, ...n }).then((a) => a.pop()?.content || null);
373
360
  }
374
361
  }
375
362
  class Z {
@@ -391,11 +378,11 @@ class Z {
391
378
  let n = () => {
392
379
  };
393
380
  return { response: new Promise((c, f) => {
394
- this.downloadAsrModel(e).then((l) => {
395
- let m = "";
396
- const i = U(this.options.whisper?.binary, ["-nt", "-np", "-m", l, "-f", t], { stdio: ["ignore", "pipe", "ignore"] });
397
- n = () => i.kill("SIGTERM"), i.on("error", (r) => f(r)), i.stdout.on("data", (r) => m += r.toString()), i.on("close", (r) => {
398
- r === 0 ? c(m.trim() || null) : f(new Error(`Exit code ${r}`));
381
+ this.downloadAsrModel(e).then((i) => {
382
+ let l = "";
383
+ const m = $(this.options.whisper?.binary, ["-nt", "-np", "-m", i, "-f", t], { stdio: ["ignore", "pipe", "ignore"] });
384
+ n = () => m.kill("SIGTERM"), m.on("error", (s) => f(s)), m.stdout.on("data", (s) => l += s.toString()), m.on("close", (s) => {
385
+ s === 0 ? c(l.trim() || null) : f(new Error(`Exit code ${s}`));
399
386
  });
400
387
  });
401
388
  }), abort: n };
@@ -409,8 +396,8 @@ class Z {
409
396
  async downloadAsrModel(t = this.whisperModel) {
410
397
  if (!this.options.whisper?.binary) throw new Error("Whisper not configured");
411
398
  t.endsWith(".bin") || (t += ".bin");
412
- const e = D.join(this.options.whisper.path, t);
413
- return await j.stat(e).then(() => !0).catch(() => !1) ? e : this.downloads[t] ? this.downloads[t] : (this.downloads[t] = fetch(`https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${t}`).then((n) => n.arrayBuffer()).then((n) => Buffer.from(n)).then(async (n) => (await j.writeFile(e, n), delete this.downloads[t], e)), this.downloads[t]);
399
+ const e = U.join(this.options.whisper.path, t);
400
+ return await S.stat(e).then(() => !0).catch(() => !1) ? e : this.downloads[t] ? this.downloads[t] : (this.downloads[t] = fetch(`https://huggingface.co/ggerganov/whisper.cpp/resolve/main/${t}`).then((n) => n.arrayBuffer()).then((n) => Buffer.from(n)).then(async (n) => (await S.writeFile(e, n), delete this.downloads[t], e)), this.downloads[t]);
414
401
  }
415
402
  /**
416
403
  * Convert image to text using Optical Character Recognition
@@ -424,9 +411,9 @@ class Z {
424
411
  e?.terminate();
425
412
  },
426
413
  response: new Promise(async (n) => {
427
- e = await T("eng");
428
- const { data: o } = await e.recognize(t);
429
- await e.terminate(), n(o.text.trim() || null);
414
+ e = await j("eng");
415
+ const { data: a } = await e.recognize(t);
416
+ await e.terminate(), n(a.text.trim() || null);
430
417
  })
431
418
  };
432
419
  }
@@ -438,19 +425,19 @@ class Z {
438
425
  */
439
426
  semanticSimilarity(t, ...e) {
440
427
  if (e.length < 2) throw new Error("Requires at least 2 strings to compare");
441
- const n = (l, m = 10) => l.toLowerCase().split("").map((i, r) => i.charCodeAt(0) * (r + 1) % m / m).slice(0, m), o = (l, m) => {
442
- if (l.length !== m.length) throw new Error("Vectors must be same length");
443
- const i = _.tensor1d(l), r = _.tensor1d(m), p = _.dot(i, r), d = _.norm(i), s = _.norm(r);
444
- return d.dataSync()[0] === 0 || s.dataSync()[0] === 0 ? 0 : p.dataSync()[0] / (d.dataSync()[0] * s.dataSync()[0]);
445
- }, c = n(t), f = e.map((l) => n(l)).map((l) => o(c, l));
446
- return { avg: f.reduce((l, m) => l + m, 0) / f.length, max: Math.max(...f), similarities: f };
428
+ const n = (i, l = 10) => i.toLowerCase().split("").map((m, s) => m.charCodeAt(0) * (s + 1) % l / l).slice(0, l), a = (i, l) => {
429
+ if (i.length !== l.length) throw new Error("Vectors must be same length");
430
+ const m = w.tensor1d(i), s = w.tensor1d(l), p = w.dot(m, s), o = w.norm(m), r = w.norm(s);
431
+ return o.dataSync()[0] === 0 || r.dataSync()[0] === 0 ? 0 : p.dataSync()[0] / (o.dataSync()[0] * r.dataSync()[0]);
432
+ }, c = n(t), f = e.map((i) => n(i)).map((i) => a(c, i));
433
+ return { avg: f.reduce((i, l) => i + l, 0) / f.length, max: Math.max(...f), similarities: f };
447
434
  }
448
435
  }
449
436
  const N = {
450
437
  name: "cli",
451
438
  description: "Use the command line interface, returns any output",
452
439
  args: { command: { type: "string", description: "Command to run", required: !0 } },
453
- fn: (u) => $`${u.command}`
440
+ fn: (d) => L`${d.command}`
454
441
  }, ee = {
455
442
  name: "get_datetime",
456
443
  description: "Get current date and time",
@@ -463,15 +450,15 @@ const N = {
463
450
  language: { type: "string", description: "Execution language", enum: ["cli", "node", "python"], required: !0 },
464
451
  code: { type: "string", description: "Code to execute", required: !0 }
465
452
  },
466
- fn: async (u, t) => {
453
+ fn: async (d, t) => {
467
454
  try {
468
- switch (u.type) {
455
+ switch (d.type) {
469
456
  case "bash":
470
- return await N.fn({ command: u.code }, t);
457
+ return await N.fn({ command: d.code }, t);
471
458
  case "node":
472
- return await z.fn({ code: u.code }, t);
459
+ return await z.fn({ code: d.code }, t);
473
460
  case "python":
474
- return await G.fn({ code: u.code }, t);
461
+ return await G.fn({ code: d.code }, t);
475
462
  }
476
463
  } catch (e) {
477
464
  return { error: e?.message || e.toString() };
@@ -486,15 +473,15 @@ const N = {
486
473
  headers: { type: "object", description: "HTTP headers to send", default: {} },
487
474
  body: { type: "object", description: "HTTP body to send" }
488
475
  },
489
- fn: (u) => new q({ url: u.url, headers: u.headers }).request({ method: u.method || "GET", body: u.body })
476
+ fn: (d) => new q({ url: d.url, headers: d.headers }).request({ method: d.method || "GET", body: d.body })
490
477
  }, z = {
491
478
  name: "exec_javascript",
492
479
  description: "Execute commonjs javascript",
493
480
  args: {
494
481
  code: { type: "string", description: "CommonJS javascript", required: !0 }
495
482
  },
496
- fn: async (u) => {
497
- const t = v(null), e = await P({ console: t }, u.code, !0).catch((n) => t.output.error.push(n));
483
+ fn: async (d) => {
484
+ const t = v(null), e = await P({ console: t }, d.code, !0).catch((n) => t.output.error.push(n));
498
485
  return { ...t.output, return: e, stdout: void 0, stderr: void 0 };
499
486
  }
500
487
  }, G = {
@@ -503,7 +490,7 @@ const N = {
503
490
  args: {
504
491
  code: { type: "string", description: "CommonJS javascript", required: !0 }
505
492
  },
506
- fn: async (u) => ({ result: L`python -c "${u.code}"` })
493
+ fn: async (d) => ({ result: R`python -c "${d.code}"` })
507
494
  }, se = {
508
495
  name: "search",
509
496
  description: "Use a search engine to find relevant URLs, should be changed with fetch to scrape sources",
@@ -511,22 +498,22 @@ const N = {
511
498
  query: { type: "string", description: "Search string", required: !0 },
512
499
  length: { type: "string", description: "Number of results to return", default: 5 }
513
500
  },
514
- fn: async (u) => {
515
- const t = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(u.query)}`, {
501
+ fn: async (d) => {
502
+ const t = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(d.query)}`, {
516
503
  headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept-Language": "en-US,en;q=0.9" }
517
504
  }).then((c) => c.text());
518
505
  let e, n = /<a .*?href="(.+?)".+?<\/a>/g;
519
- const o = new A();
506
+ const a = new A();
520
507
  for (; (e = n.exec(t)) !== null; ) {
521
508
  let c = /uddg=(.+)&amp?/.exec(decodeURIComponent(e[1]))?.[1];
522
- if (c && (c = decodeURIComponent(c)), c && o.add(c), o.size >= (u.length || 5)) break;
509
+ if (c && (c = decodeURIComponent(c)), c && a.add(c), a.size >= (d.length || 5)) break;
523
510
  }
524
- return o;
511
+ return a;
525
512
  }
526
513
  };
527
514
  export {
528
515
  Z as Ai,
529
- R as Anthropic,
516
+ D as Anthropic,
530
517
  N as CliTool,
531
518
  ee as DateTimeTool,
532
519
  te as ExecTool,