@ztimson/ai-utils 0.1.19 → 0.1.21

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