@ztimson/ai-utils 0.2.6 → 0.2.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,5 +1,5 @@
1
- import * as T from "node:os";
2
- import { deepCopy as j, objectMap as y, JSONAttemptParse as _, findByProp as k, JSONSanitize as b, Http as M, consoleInterceptor as A, fn as q, ASet as P } from "@ztimson/utils";
1
+ import * as j from "node:os";
2
+ import { deepCopy as T, objectMap as y, JSONAttemptParse as _, findByProp as k, JSONSanitize as b, Http as M, consoleInterceptor as A, fn as q, ASet as P } from "@ztimson/utils";
3
3
  import { Anthropic as O } from "@anthropic-ai/sdk";
4
4
  import { Ollama as $ } from "ollama";
5
5
  import { OpenAI as E } from "openai";
@@ -21,12 +21,12 @@ class I extends x {
21
21
  toStandard(t) {
22
22
  for (let e = 0; e < t.length; e++) {
23
23
  const s = e;
24
- typeof t[s].content != "string" && (t[s].role == "assistant" ? t[s].content.filter((o) => o.type == "tool_use").forEach((o) => {
25
- e++, t.splice(e, 0, { role: "tool", id: o.id, name: o.name, args: o.input, timestamp: Date.now() });
26
- }) : t[s].role == "user" && t[s].content.filter((o) => o.type == "tool_result").forEach((o) => {
27
- const c = t.find((f) => f.id == o.tool_use_id);
28
- c[o.is_error ? "error" : "content"] = o.content;
29
- }), t[s].content = t[s].content.filter((o) => o.type == "text").map((o) => o.text).join(`
24
+ typeof t[s].content != "string" && (t[s].role == "assistant" ? t[s].content.filter((n) => n.type == "tool_use").forEach((n) => {
25
+ e++, t.splice(e, 0, { role: "tool", id: n.id, name: n.name, args: n.input, timestamp: Date.now() });
26
+ }) : t[s].role == "user" && t[s].content.filter((n) => n.type == "tool_result").forEach((n) => {
27
+ const i = t.find((d) => d.id == n.tool_use_id);
28
+ i[n.is_error ? "error" : "content"] = n.content;
29
+ }), t[s].content = t[s].content.filter((n) => n.type == "text").map((n) => n.text).join(`
30
30
 
31
31
  `)), t[s].timestamp || (t[s].timestamp = Date.now());
32
32
  }
@@ -46,76 +46,76 @@ class I extends x {
46
46
  return t.map(({ timestamp: e, ...s }) => s);
47
47
  }
48
48
  ask(t, e = {}) {
49
- const s = new AbortController(), o = new Promise(async (c, f) => {
50
- let a = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
51
- const m = j(a);
52
- e.compress && (a = await this.ai.language.compressHistory(a, e.compress.max, e.compress.min, e));
53
- const h = e.tools || this.ai.options.tools || [], i = {
49
+ const s = new AbortController(), n = new Promise(async (i, d) => {
50
+ let r = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
51
+ const l = T(r);
52
+ e.compress && (r = await this.ai.language.compressHistory(r, e.compress.max, e.compress.min, e));
53
+ const u = e.tools || this.ai.options.tools || [], c = {
54
54
  model: e.model || this.model,
55
55
  max_tokens: e.max_tokens || this.ai.options.max_tokens || 4096,
56
56
  system: e.system || this.ai.options.system || "",
57
57
  temperature: e.temperature || this.ai.options.temperature || 0.7,
58
- tools: h.map((n) => ({
59
- name: n.name,
60
- description: n.description,
58
+ tools: u.map((o) => ({
59
+ name: o.name,
60
+ description: o.description,
61
61
  input_schema: {
62
62
  type: "object",
63
- properties: n.args ? y(n.args, (r, u) => ({ ...u, required: void 0 })) : {},
64
- required: n.args ? Object.entries(n.args).filter((r) => r[1].required).map((r) => r[0]) : []
63
+ properties: o.args ? y(o.args, (a, f) => ({ ...f, required: void 0 })) : {},
64
+ required: o.args ? Object.entries(o.args).filter((a) => a[1].required).map((a) => a[0]) : []
65
65
  },
66
66
  fn: void 0
67
67
  })),
68
- messages: a,
68
+ messages: r,
69
69
  stream: !!e.stream
70
70
  };
71
- let l, p = !0;
71
+ let m, h = !0;
72
72
  do {
73
- if (l = await this.client.messages.create(i).catch((r) => {
74
- throw r.message += `
73
+ if (m = await this.client.messages.create(c).catch((a) => {
74
+ throw a.message += `
75
75
 
76
76
  Messages:
77
- ${JSON.stringify(a, null, 2)}`, r;
77
+ ${JSON.stringify(r, null, 2)}`, a;
78
78
  }), e.stream) {
79
- p ? p = !1 : e.stream({ text: `
79
+ h ? h = !1 : e.stream({ text: `
80
80
 
81
- ` }), l.content = [];
82
- for await (const r of l) {
81
+ ` }), m.content = [];
82
+ for await (const a of m) {
83
83
  if (s.signal.aborted) break;
84
- if (r.type === "content_block_start")
85
- r.content_block.type === "text" ? l.content.push({ type: "text", text: "" }) : r.content_block.type === "tool_use" && l.content.push({ type: "tool_use", id: r.content_block.id, name: r.content_block.name, input: "" });
86
- else if (r.type === "content_block_delta")
87
- if (r.delta.type === "text_delta") {
88
- const u = r.delta.text;
89
- l.content.at(-1).text += u, e.stream({ text: u });
90
- } else r.delta.type === "input_json_delta" && (l.content.at(-1).input += r.delta.partial_json);
91
- else if (r.type === "content_block_stop") {
92
- const u = l.content.at(-1);
93
- u.input != null && (u.input = u.input ? _(u.input, {}) : {});
94
- } else if (r.type === "message_stop")
84
+ if (a.type === "content_block_start")
85
+ a.content_block.type === "text" ? m.content.push({ type: "text", text: "" }) : a.content_block.type === "tool_use" && m.content.push({ type: "tool_use", id: a.content_block.id, name: a.content_block.name, input: "" });
86
+ else if (a.type === "content_block_delta")
87
+ if (a.delta.type === "text_delta") {
88
+ const f = a.delta.text;
89
+ m.content.at(-1).text += f, e.stream({ text: f });
90
+ } else a.delta.type === "input_json_delta" && (m.content.at(-1).input += a.delta.partial_json);
91
+ else if (a.type === "content_block_stop") {
92
+ const f = m.content.at(-1);
93
+ f.input != null && (f.input = f.input ? _(f.input, {}) : {});
94
+ } else if (a.type === "message_stop")
95
95
  break;
96
96
  }
97
97
  }
98
- const n = l.content.filter((r) => r.type === "tool_use");
99
- if (n.length && !s.signal.aborted) {
100
- a.push({ role: "assistant", content: l.content }), m.push({ role: "assistant", content: l.content });
101
- const r = await Promise.all(n.map(async (u) => {
102
- const g = h.find(k("name", u.name));
103
- if (!g) return { tool_use_id: u.id, is_error: !0, content: "Tool not found" };
98
+ const o = m.content.filter((a) => a.type === "tool_use");
99
+ if (o.length && !s.signal.aborted) {
100
+ r.push({ role: "assistant", content: m.content }), l.push({ role: "assistant", content: m.content });
101
+ const a = await Promise.all(o.map(async (f) => {
102
+ const g = u.find(k("name", f.name));
103
+ if (!g) return { tool_use_id: f.id, is_error: !0, content: "Tool not found" };
104
104
  try {
105
- const w = await g.fn(u.input, this.ai);
106
- return { type: "tool_result", tool_use_id: u.id, content: b(w) };
105
+ const w = await g.fn(f.input, this.ai);
106
+ return { type: "tool_result", tool_use_id: f.id, content: b(w) };
107
107
  } catch (w) {
108
- return { type: "tool_result", tool_use_id: u.id, is_error: !0, content: w?.message || w?.toString() || "Unknown" };
108
+ return { type: "tool_result", tool_use_id: f.id, is_error: !0, content: w?.message || w?.toString() || "Unknown" };
109
109
  }
110
110
  }));
111
- a.push({ role: "user", content: r }), i.messages = a;
111
+ r.push({ role: "user", content: a }), c.messages = r;
112
112
  }
113
- } while (!s.signal.aborted && l.content.some((n) => n.type === "tool_use"));
114
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...a, { role: "assistant", content: l.content.filter((n) => n.type == "text").map((n) => n.text).join(`
113
+ } while (!s.signal.aborted && m.content.some((o) => o.type === "tool_use"));
114
+ e.stream && e.stream({ done: !0 }), i(this.toStandard([...r, { role: "assistant", content: m.content.filter((o) => o.type == "text").map((o) => o.text).join(`
115
115
 
116
116
  `) }]));
117
117
  });
118
- return Object.assign(o, { abort: () => s.abort() });
118
+ return Object.assign(n, { abort: () => s.abort() });
119
119
  }
120
120
  }
121
121
  class z extends x {
@@ -137,69 +137,69 @@ class z extends x {
137
137
  }
138
138
  fromStandard(t) {
139
139
  return t.map((e) => {
140
- const { timestamp: s, ...o } = e;
141
- return e.role != "tool" ? o : { role: "tool", tool_name: e.name, content: e.error || e.content };
140
+ const { timestamp: s, ...n } = e;
141
+ return e.role != "tool" ? n : { role: "tool", tool_name: e.name, content: e.error || e.content };
142
142
  });
143
143
  }
144
144
  ask(t, e = {}) {
145
- const s = new AbortController(), o = new Promise(async (c, f) => {
146
- let a = e.system || this.ai.options.system, m = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
147
- m[0].roll == "system" && (a ? m.shift() : a = m.shift()), e.compress && (m = await this.ai.language.compressHistory(m, e.compress.max, e.compress.min)), e.system && m.unshift({ role: "system", content: a });
148
- const h = e.tools || this.ai.options.tools || [], i = {
145
+ const s = new AbortController(), n = new Promise(async (i, d) => {
146
+ let r = e.system || this.ai.options.system, l = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
147
+ l[0].roll == "system" && (r ? l.shift() : r = l.shift()), e.compress && (l = await this.ai.language.compressHistory(l, e.compress.max, e.compress.min)), e.system && l.unshift({ role: "system", content: r });
148
+ const u = e.tools || this.ai.options.tools || [], c = {
149
149
  model: e.model || this.model,
150
- messages: m,
150
+ messages: l,
151
151
  stream: !!e.stream,
152
152
  signal: s.signal,
153
153
  options: {
154
154
  temperature: e.temperature || this.ai.options.temperature || 0.7,
155
155
  num_predict: e.max_tokens || this.ai.options.max_tokens || 4096
156
156
  },
157
- tools: h.map((n) => ({
157
+ tools: u.map((o) => ({
158
158
  type: "function",
159
159
  function: {
160
- name: n.name,
161
- description: n.description,
160
+ name: o.name,
161
+ description: o.description,
162
162
  parameters: {
163
163
  type: "object",
164
- properties: n.args ? y(n.args, (r, u) => ({ ...u, required: void 0 })) : {},
165
- required: n.args ? Object.entries(n.args).filter((r) => r[1].required).map((r) => r[0]) : []
164
+ properties: o.args ? y(o.args, (a, f) => ({ ...f, required: void 0 })) : {},
165
+ required: o.args ? Object.entries(o.args).filter((a) => a[1].required).map((a) => a[0]) : []
166
166
  }
167
167
  }
168
168
  }))
169
169
  };
170
- let l, p = !0;
170
+ let m, h = !0;
171
171
  do {
172
- if (l = await this.client.chat(i).catch((n) => {
173
- throw n.message += `
172
+ if (m = await this.client.chat(c).catch((o) => {
173
+ throw o.message += `
174
174
 
175
175
  Messages:
176
- ${JSON.stringify(m, null, 2)}`, n;
176
+ ${JSON.stringify(l, null, 2)}`, o;
177
177
  }), e.stream) {
178
- p ? p = !1 : e.stream({ text: `
178
+ h ? h = !1 : e.stream({ text: `
179
179
 
180
- ` }), l.message = { role: "assistant", content: "", tool_calls: [] };
181
- for await (const n of l)
182
- if (s.signal.aborted || (n.message?.content && (l.message.content += n.message.content, e.stream({ text: n.message.content })), n.message?.tool_calls && (l.message.tool_calls = n.message.tool_calls), n.done)) break;
180
+ ` }), m.message = { role: "assistant", content: "", tool_calls: [] };
181
+ for await (const o of m)
182
+ if (s.signal.aborted || (o.message?.content && (m.message.content += o.message.content, e.stream({ text: o.message.content })), o.message?.tool_calls && (m.message.tool_calls = o.message.tool_calls), o.done)) break;
183
183
  }
184
- if (l.message?.tool_calls?.length && !s.signal.aborted) {
185
- m.push(l.message);
186
- const n = await Promise.all(l.message.tool_calls.map(async (r) => {
187
- const u = h.find(k("name", r.function.name));
188
- if (!u) return { role: "tool", tool_name: r.function.name, content: '{"error": "Tool not found"}' };
189
- const g = typeof r.function.arguments == "string" ? _(r.function.arguments, {}) : r.function.arguments;
184
+ if (m.message?.tool_calls?.length && !s.signal.aborted) {
185
+ l.push(m.message);
186
+ const o = await Promise.all(m.message.tool_calls.map(async (a) => {
187
+ const f = u.find(k("name", a.function.name));
188
+ if (!f) return { role: "tool", tool_name: a.function.name, content: '{"error": "Tool not found"}' };
189
+ const g = typeof a.function.arguments == "string" ? _(a.function.arguments, {}) : a.function.arguments;
190
190
  try {
191
- const w = await u.fn(g, this.ai);
192
- return { role: "tool", tool_name: r.function.name, args: g, content: b(w) };
191
+ const w = await f.fn(g, this.ai);
192
+ return { role: "tool", tool_name: a.function.name, args: g, content: b(w) };
193
193
  } catch (w) {
194
- return { role: "tool", tool_name: r.function.name, args: g, content: b({ error: w?.message || w?.toString() || "Unknown" }) };
194
+ return { role: "tool", tool_name: a.function.name, args: g, content: b({ error: w?.message || w?.toString() || "Unknown" }) };
195
195
  }
196
196
  }));
197
- m.push(...n), i.messages = m;
197
+ l.push(...o), c.messages = l;
198
198
  }
199
- } while (!s.signal.aborted && l.message?.tool_calls?.length);
200
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...m, { role: "assistant", content: l.message?.content }]));
199
+ } while (!s.signal.aborted && m.message?.tool_calls?.length);
200
+ e.stream && e.stream({ done: !0 }), i(this.toStandard([...l, { role: "assistant", content: m.message?.content }]));
201
201
  });
202
- return Object.assign(o, { abort: () => s.abort() });
202
+ return Object.assign(n, { abort: () => s.abort() });
203
203
  }
204
204
  }
205
205
  class F extends x {
@@ -211,17 +211,17 @@ class F extends x {
211
211
  for (let e = 0; e < t.length; e++) {
212
212
  const s = t[e];
213
213
  if (s.role === "assistant" && s.tool_calls) {
214
- const o = s.tool_calls.map((c) => ({
214
+ const n = s.tool_calls.map((i) => ({
215
215
  role: "tool",
216
- id: c.id,
217
- name: c.function.name,
218
- args: _(c.function.arguments, {}),
216
+ id: i.id,
217
+ name: i.function.name,
218
+ args: _(i.function.arguments, {}),
219
219
  timestamp: s.timestamp
220
220
  }));
221
- t.splice(e, 1, ...o), e += o.length - 1;
221
+ t.splice(e, 1, ...n), e += n.length - 1;
222
222
  } else if (s.role === "tool" && s.content) {
223
- const o = t.find((c) => s.tool_call_id == c.id);
224
- o && (s.content.includes('"error":') ? o.error = s.content : o.content = s.content), t.splice(e, 1), e--;
223
+ const n = t.find((i) => s.tool_call_id == i.id);
224
+ n && (s.content.includes('"error":') ? n.error = s.content : n.content = s.content), t.splice(e, 1), e--;
225
225
  }
226
226
  t[e]?.timestamp || (t[e].timestamp = Date.now());
227
227
  }
@@ -242,77 +242,77 @@ class F extends x {
242
242
  content: s.error || s.content
243
243
  });
244
244
  else {
245
- const { timestamp: o, ...c } = s;
246
- e.push(c);
245
+ const { timestamp: n, ...i } = s;
246
+ e.push(i);
247
247
  }
248
248
  return e;
249
249
  }, []);
250
250
  }
251
251
  ask(t, e = {}) {
252
- const s = new AbortController(), o = new Promise(async (c, f) => {
253
- let a = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
254
- e.compress && (a = await this.ai.language.compressHistory(a, e.compress.max, e.compress.min, e));
255
- const m = e.tools || this.ai.options.tools || [], h = {
252
+ const s = new AbortController(), n = new Promise(async (i, d) => {
253
+ let r = this.fromStandard([...e.history || [], { role: "user", content: t, timestamp: Date.now() }]);
254
+ e.compress && (r = await this.ai.language.compressHistory(r, e.compress.max, e.compress.min, e));
255
+ const l = e.tools || this.ai.options.tools || [], u = {
256
256
  model: e.model || this.model,
257
- messages: a,
257
+ messages: r,
258
258
  stream: !!e.stream,
259
259
  max_tokens: e.max_tokens || this.ai.options.max_tokens || 4096,
260
260
  temperature: e.temperature || this.ai.options.temperature || 0.7,
261
- tools: m.map((p) => ({
261
+ tools: l.map((h) => ({
262
262
  type: "function",
263
263
  function: {
264
- name: p.name,
265
- description: p.description,
264
+ name: h.name,
265
+ description: h.description,
266
266
  parameters: {
267
267
  type: "object",
268
- properties: p.args ? y(p.args, (n, r) => ({ ...r, required: void 0 })) : {},
269
- required: p.args ? Object.entries(p.args).filter((n) => n[1].required).map((n) => n[0]) : []
268
+ properties: h.args ? y(h.args, (o, a) => ({ ...a, required: void 0 })) : {},
269
+ required: h.args ? Object.entries(h.args).filter((o) => o[1].required).map((o) => o[0]) : []
270
270
  }
271
271
  }
272
272
  }))
273
273
  };
274
- let i, l = !0;
274
+ let c, m = !0;
275
275
  do {
276
- if (i = await this.client.chat.completions.create(h).catch((n) => {
277
- throw n.message += `
276
+ if (c = await this.client.chat.completions.create(u).catch((o) => {
277
+ throw o.message += `
278
278
 
279
279
  Messages:
280
- ${JSON.stringify(a, null, 2)}`, n;
280
+ ${JSON.stringify(r, null, 2)}`, o;
281
281
  }), e.stream) {
282
- l ? l = !1 : e.stream({ text: `
282
+ m ? m = !1 : e.stream({ text: `
283
283
 
284
- ` }), i.choices = [{ message: { content: "", tool_calls: [] } }];
285
- for await (const n of i) {
284
+ ` }), c.choices = [{ message: { content: "", tool_calls: [] } }];
285
+ for await (const o of c) {
286
286
  if (s.signal.aborted) break;
287
- n.choices[0].delta.content && (i.choices[0].message.content += n.choices[0].delta.content, e.stream({ text: n.choices[0].delta.content })), n.choices[0].delta.tool_calls && (i.choices[0].message.tool_calls = n.choices[0].delta.tool_calls);
287
+ o.choices[0].delta.content && (c.choices[0].message.content += o.choices[0].delta.content, e.stream({ text: o.choices[0].delta.content })), o.choices[0].delta.tool_calls && (c.choices[0].message.tool_calls = o.choices[0].delta.tool_calls);
288
288
  }
289
289
  }
290
- const p = i.choices[0].message.tool_calls || [];
291
- if (p.length && !s.signal.aborted) {
292
- a.push(i.choices[0].message);
293
- const n = await Promise.all(p.map(async (r) => {
294
- const u = m?.find(k("name", r.function.name));
295
- if (!u) return { role: "tool", tool_call_id: r.id, content: '{"error": "Tool not found"}' };
290
+ const h = c.choices[0].message.tool_calls || [];
291
+ if (h.length && !s.signal.aborted) {
292
+ r.push(c.choices[0].message);
293
+ const o = await Promise.all(h.map(async (a) => {
294
+ const f = l?.find(k("name", a.function.name));
295
+ if (!f) return { role: "tool", tool_call_id: a.id, content: '{"error": "Tool not found"}' };
296
296
  try {
297
- const g = _(r.function.arguments, {}), w = await u.fn(g, this.ai);
298
- return { role: "tool", tool_call_id: r.id, content: b(w) };
297
+ const g = _(a.function.arguments, {}), w = await f.fn(g, this.ai);
298
+ return { role: "tool", tool_call_id: a.id, content: b(w) };
299
299
  } catch (g) {
300
- return { role: "tool", tool_call_id: r.id, content: b({ error: g?.message || g?.toString() || "Unknown" }) };
300
+ return { role: "tool", tool_call_id: a.id, content: b({ error: g?.message || g?.toString() || "Unknown" }) };
301
301
  }
302
302
  }));
303
- a.push(...n), h.messages = a;
303
+ r.push(...o), u.messages = r;
304
304
  }
305
- } while (!s.signal.aborted && i.choices?.[0]?.message?.tool_calls?.length);
306
- e.stream && e.stream({ done: !0 }), c(this.toStandard([...a, { role: "assistant", content: i.choices[0].message.content || "" }]));
305
+ } while (!s.signal.aborted && c.choices?.[0]?.message?.tool_calls?.length);
306
+ e.stream && e.stream({ done: !0 }), i(this.toStandard([...r, { role: "assistant", content: c.choices[0].message.content || "" }]));
307
307
  });
308
- return Object.assign(o, { abort: () => s.abort() });
308
+ return Object.assign(n, { abort: () => s.abort() });
309
309
  }
310
310
  }
311
311
  class G {
312
312
  constructor(t) {
313
313
  this.ai = t, this.embedWorker = new v(U(L(R(import.meta.url)), "embedder.js")), this.embedWorker.on("message", ({ id: e, embedding: s }) => {
314
- const o = this.embedQueue.get(e);
315
- o && (o.resolve(s), this.embedQueue.delete(e));
314
+ const n = this.embedQueue.get(e);
315
+ n && (n.resolve(s), this.embedQueue.delete(e));
316
316
  }), t.options.anthropic?.token && (this.providers.anthropic = new I(this.ai, t.options.anthropic.token, t.options.anthropic.model)), t.options.ollama?.host && (this.providers.ollama = new z(this.ai, t.options.ollama.host, t.options.ollama.model)), t.options.openAi?.token && (this.providers.openAi = new F(this.ai, t.options.openAi.token, t.options.openAi.model));
317
317
  }
318
318
  embedWorker = null;
@@ -338,56 +338,57 @@ class G {
338
338
  * @param {LLMRequest} options LLM options
339
339
  * @returns {Promise<LLMMessage[]>} New chat history will summary at index 0
340
340
  */
341
- async compressHistory(t, e, s, o) {
341
+ async compressHistory(t, e, s, n) {
342
342
  if (this.estimateTokens(t) < e) return t;
343
- let c = 0, f = 0;
344
- for (let i of t.toReversed())
345
- if (f += this.estimateTokens(i.content), f < s) c++;
343
+ let i = 0, d = 0;
344
+ for (let c of t.toReversed())
345
+ if (d += this.estimateTokens(c.content), d < s) i++;
346
346
  else break;
347
- if (t.length <= c) return t;
348
- const a = c == 0 ? [] : t.slice(-c), m = (c == 0 ? t : t.slice(0, -c)).filter((i) => i.role === "assistant" || i.role === "user");
349
- return [{ role: "assistant", content: `Conversation Summary: ${await this.summarize(m.map((i) => `${i.role}: ${i.content}`).join(`
347
+ if (t.length <= i) return t;
348
+ const r = i == 0 ? [] : t.slice(-i), l = (i == 0 ? t : t.slice(0, -i)).filter((c) => c.role === "assistant" || c.role === "user");
349
+ return [{ role: "assistant", content: `Conversation Summary: ${await this.summarize(l.map((c) => `${c.role}: ${c.content}`).join(`
350
350
 
351
- `), 250, o)}`, timestamp: Date.now() }, ...a];
351
+ `), 250, n)}`, timestamp: Date.now() }, ...r];
352
352
  }
353
353
  cosineSimilarity(t, e) {
354
354
  if (t.length !== e.length) throw new Error("Vectors must be same length");
355
- let s = 0, o = 0, c = 0;
356
- for (let a = 0; a < t.length; a++)
357
- s += t[a] * e[a], o += t[a] * t[a], c += e[a] * e[a];
358
- const f = Math.sqrt(o) * Math.sqrt(c);
359
- return f === 0 ? 0 : s / f;
355
+ let s = 0, n = 0, i = 0;
356
+ for (let r = 0; r < t.length; r++)
357
+ s += t[r] * e[r], n += t[r] * t[r], i += e[r] * e[r];
358
+ const d = Math.sqrt(n) * Math.sqrt(i);
359
+ return d === 0 ? 0 : s / d;
360
360
  }
361
- embedding(t, e = 500, s = 50) {
362
- const o = (i, l = "") => i == null ? [] : Object.entries(i).flatMap(([p, n]) => {
363
- const r = l ? `${l}${isNaN(+p) ? `.${p}` : `[${p}]`}` : p;
364
- if (typeof n == "object" && n !== null && !Array.isArray(n)) return o(n, r);
365
- const u = Array.isArray(n) ? n.join(", ") : String(n);
366
- return `${r}: ${u}`;
367
- }), c = (i) => new Promise((l, p) => {
368
- const n = this.embedId++;
369
- this.embedQueue.set(n, { resolve: l, reject: p }), this.embedWorker?.postMessage({ id: n, text: i });
370
- }), a = (typeof t == "object" ? o(t) : t.split(`
371
- `)).flatMap((i) => [...i.split(/\s+/).filter((l) => l.trim()), `
372
- `]), m = [];
373
- let h = 0;
374
- for (; h < a.length; ) {
375
- let i = h, l = "";
376
- for (; i < a.length; ) {
377
- const n = a[i], r = l + (l ? " " : "") + n;
378
- if (this.estimateTokens(r.replace(/\s*\n\s*/g, `
379
- `)) > e && l) break;
380
- l = r, i++;
361
+ chunk(t, e = 500, s = 50) {
362
+ const n = (l, u = "") => l ? Object.entries(l).flatMap(([c, m]) => {
363
+ const h = u ? `${u}${isNaN(+c) ? `.${c}` : `[${c}]`}` : c;
364
+ return typeof m == "object" && !Array.isArray(m) ? n(m, h) : `${h}: ${Array.isArray(m) ? m.join(", ") : m}`;
365
+ }) : [], d = (typeof t == "object" ? n(t) : t.split(`
366
+ `)).flatMap((l) => [...l.split(/\s+/).filter(Boolean), `
367
+ `]), r = [];
368
+ for (let l = 0; l < d.length; ) {
369
+ let u = "", c = l;
370
+ for (; c < d.length; ) {
371
+ const h = u + (u ? " " : "") + d[c];
372
+ if (this.estimateTokens(h.replace(/\s*\n\s*/g, `
373
+ `)) > e && u) break;
374
+ u = h, c++;
381
375
  }
382
- const p = l.replace(/\s*\n\s*/g, `
376
+ const m = u.replace(/\s*\n\s*/g, `
383
377
  `).trim();
384
- p && m.push(p), h = i - s, h <= i - a.length + i && (h = i);
378
+ m && r.push(m), l = Math.max(c - s, c === l ? l + 1 : c);
385
379
  }
386
- return Promise.all(m.map(async (i, l) => ({
387
- index: l,
388
- embedding: await c(i),
389
- text: i,
390
- tokens: this.estimateTokens(i)
380
+ return r;
381
+ }
382
+ embedding(t, e = 500, s = 50) {
383
+ const n = (d) => new Promise((r, l) => {
384
+ const u = this.embedId++;
385
+ this.embedQueue.set(u, { resolve: r, reject: l }), this.embedWorker?.postMessage({ id: u, text: d });
386
+ }), i = this.chunk(t, e, s);
387
+ return Promise.all(i.map(async (d, r) => ({
388
+ index: r,
389
+ embedding: await n(d),
390
+ text: d,
391
+ tokens: this.estimateTokens(d)
391
392
  })));
392
393
  }
393
394
  /**
@@ -407,8 +408,8 @@ class G {
407
408
  */
408
409
  fuzzyMatch(t, ...e) {
409
410
  if (e.length < 2) throw new Error("Requires at least 2 strings to compare");
410
- const s = (f, a = 10) => f.toLowerCase().split("").map((m, h) => m.charCodeAt(0) * (h + 1) % a / a).slice(0, a), o = s(t), c = e.map((f) => s(f)).map((f) => this.cosineSimilarity(o, f));
411
- return { avg: c.reduce((f, a) => f + a, 0) / c.length, max: Math.max(...c), similarities: c };
411
+ const s = (d, r = 10) => d.toLowerCase().split("").map((l, u) => l.charCodeAt(0) * (u + 1) % r / r).slice(0, r), n = s(t), i = e.map((d) => s(d)).map((d) => this.cosineSimilarity(n, d));
412
+ return { avg: i.reduce((d, r) => d + r, 0) / i.length, max: Math.max(...i), similarities: i };
412
413
  }
413
414
  /**
414
415
  * Ask a question with JSON response
@@ -431,10 +432,10 @@ class G {
431
432
  * @returns {Promise<string>} Summary
432
433
  */
433
434
  summarize(t, e, s) {
434
- return this.ask(t, { system: `Generate a brief summary <= ${e} tokens. Output nothing else`, temperature: 0.3, ...s }).then((o) => o.pop()?.content || null);
435
+ return this.ask(t, { system: `Generate a brief summary <= ${e} tokens. Output nothing else`, temperature: 0.3, ...s }).then((n) => n.pop()?.content || null);
435
436
  }
436
437
  }
437
- class C {
438
+ class B {
438
439
  constructor(t) {
439
440
  this.ai = t, t.options.whisper?.binary && (this.whisperModel = t.options.whisper?.model.endsWith(".bin") ? t.options.whisper?.model : t.options.whisper?.model + ".bin", this.downloadAsrModel());
440
441
  }
@@ -450,12 +451,12 @@ class C {
450
451
  if (!this.ai.options.whisper?.binary) throw new Error("Whisper not configured");
451
452
  let s = () => {
452
453
  };
453
- return { response: new Promise((c, f) => {
454
- this.downloadAsrModel(e).then((a) => {
455
- let m = "";
456
- const h = N(this.ai.options.whisper?.binary, ["-nt", "-np", "-m", a, "-f", t], { stdio: ["ignore", "pipe", "ignore"] });
457
- s = () => h.kill("SIGTERM"), h.on("error", (i) => f(i)), h.stdout.on("data", (i) => m += i.toString()), h.on("close", (i) => {
458
- i === 0 ? c(m.trim() || null) : f(new Error(`Exit code ${i}`));
454
+ return { response: new Promise((i, d) => {
455
+ this.downloadAsrModel(e).then((r) => {
456
+ let l = "";
457
+ const u = N(this.ai.options.whisper?.binary, ["-nt", "-np", "-m", r, "-f", t], { stdio: ["ignore", "pipe", "ignore"] });
458
+ s = () => u.kill("SIGTERM"), u.on("error", (c) => d(c)), u.stdout.on("data", (c) => l += c.toString()), u.on("close", (c) => {
459
+ c === 0 ? i(l.trim() || null) : d(new Error(`Exit code ${c}`));
459
460
  });
460
461
  });
461
462
  }), abort: s };
@@ -473,7 +474,7 @@ class C {
473
474
  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((s) => s.arrayBuffer()).then((s) => Buffer.from(s)).then(async (s) => (await S.writeFile(e, s), delete this.downloads[t], e)), this.downloads[t]);
474
475
  }
475
476
  }
476
- class B {
477
+ class C {
477
478
  constructor(t) {
478
479
  this.ai = t;
479
480
  }
@@ -490,15 +491,15 @@ class B {
490
491
  },
491
492
  response: new Promise(async (s) => {
492
493
  e = await D(this.ai.options.tesseract?.model || "eng", 2, { cachePath: this.ai.options.path });
493
- const { data: o } = await e.recognize(t);
494
- await e.terminate(), s(o.text.trim() || null);
494
+ const { data: n } = await e.recognize(t);
495
+ await e.terminate(), s(n.text.trim() || null);
495
496
  })
496
497
  };
497
498
  }
498
499
  }
499
500
  class le {
500
501
  constructor(t) {
501
- this.options = t, t.path || (t.path = T.tmpdir()), process.env.TRANSFORMERS_CACHE = t.path, this.audio = new C(this), this.language = new G(this), this.vision = new B(this);
502
+ this.options = t, t.path || (t.path = j.tmpdir()), process.env.TRANSFORMERS_CACHE = t.path, this.audio = new B(this), this.language = new G(this), this.vision = new C(this);
502
503
  }
503
504
  /** Audio processing AI */
504
505
  audio;
@@ -511,7 +512,7 @@ const Q = {
511
512
  name: "cli",
512
513
  description: "Use the command line interface, returns any output",
513
514
  args: { command: { type: "string", description: "Command to run", required: !0 } },
514
- fn: (d) => J`${d.command}`
515
+ fn: (p) => J`${p.command}`
515
516
  }, me = {
516
517
  name: "get_datetime",
517
518
  description: "Get current date and time",
@@ -524,15 +525,15 @@ const Q = {
524
525
  language: { type: "string", description: "Execution language", enum: ["cli", "node", "python"], required: !0 },
525
526
  code: { type: "string", description: "Code to execute", required: !0 }
526
527
  },
527
- fn: async (d, t) => {
528
+ fn: async (p, t) => {
528
529
  try {
529
- switch (d.type) {
530
+ switch (p.type) {
530
531
  case "bash":
531
- return await Q.fn({ command: d.code }, t);
532
+ return await Q.fn({ command: p.code }, t);
532
533
  case "node":
533
- return await K.fn({ code: d.code }, t);
534
+ return await K.fn({ code: p.code }, t);
534
535
  case "python":
535
- return await V.fn({ code: d.code }, t);
536
+ return await V.fn({ code: p.code }, t);
536
537
  }
537
538
  } catch (e) {
538
539
  return { error: e?.message || e.toString() };
@@ -547,15 +548,15 @@ const Q = {
547
548
  headers: { type: "object", description: "HTTP headers to send", default: {} },
548
549
  body: { type: "object", description: "HTTP body to send" }
549
550
  },
550
- fn: (d) => new M({ url: d.url, headers: d.headers }).request({ method: d.method || "GET", body: d.body })
551
+ fn: (p) => new M({ url: p.url, headers: p.headers }).request({ method: p.method || "GET", body: p.body })
551
552
  }, K = {
552
553
  name: "exec_javascript",
553
554
  description: "Execute commonjs javascript",
554
555
  args: {
555
556
  code: { type: "string", description: "CommonJS javascript", required: !0 }
556
557
  },
557
- fn: async (d) => {
558
- const t = A(null), e = await q({ console: t }, d.code, !0).catch((s) => t.output.error.push(s));
558
+ fn: async (p) => {
559
+ const t = A(null), e = await q({ console: t }, p.code, !0).catch((s) => t.output.error.push(s));
559
560
  return { ...t.output, return: e, stdout: void 0, stderr: void 0 };
560
561
  }
561
562
  }, V = {
@@ -564,7 +565,7 @@ const Q = {
564
565
  args: {
565
566
  code: { type: "string", description: "CommonJS javascript", required: !0 }
566
567
  },
567
- fn: async (d) => ({ result: H`python -c "${d.code}"` })
568
+ fn: async (p) => ({ result: H`python -c "${p.code}"` })
568
569
  }, pe = {
569
570
  name: "search",
570
571
  description: "Use a search engine to find relevant URLs, should be changed with fetch to scrape sources",
@@ -572,17 +573,17 @@ const Q = {
572
573
  query: { type: "string", description: "Search string", required: !0 },
573
574
  length: { type: "string", description: "Number of results to return", default: 5 }
574
575
  },
575
- fn: async (d) => {
576
- const t = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(d.query)}`, {
576
+ fn: async (p) => {
577
+ const t = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(p.query)}`, {
577
578
  headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept-Language": "en-US,en;q=0.9" }
578
- }).then((c) => c.text());
579
+ }).then((i) => i.text());
579
580
  let e, s = /<a .*?href="(.+?)".+?<\/a>/g;
580
- const o = new P();
581
+ const n = new P();
581
582
  for (; (e = s.exec(t)) !== null; ) {
582
- let c = /uddg=(.+)&amp?/.exec(decodeURIComponent(e[1]))?.[1];
583
- if (c && (c = decodeURIComponent(c)), c && o.add(c), o.size >= (d.length || 5)) break;
583
+ let i = /uddg=(.+)&amp?/.exec(decodeURIComponent(e[1]))?.[1];
584
+ if (i && (i = decodeURIComponent(i)), i && n.add(i), n.size >= (p.length || 5)) break;
584
585
  }
585
- return o;
586
+ return n;
586
587
  }
587
588
  };
588
589
  export {