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