@threaded/ai 1.0.2 → 1.0.4
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.cjs +228 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -8
- package/dist/index.d.ts +66 -8
- package/dist/index.js +225 -51
- package/dist/index.js.map +1 -1
- package/package.json +6 -11
package/dist/index.js
CHANGED
|
@@ -1,29 +1,14 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
1
|
// src/schema.ts
|
|
2
|
+
import { z } from "zod";
|
|
9
3
|
var isStandardSchema = (schema) => {
|
|
10
4
|
return schema && typeof schema === "object" && "~standard" in schema;
|
|
11
5
|
};
|
|
12
6
|
var convertStandardSchemaToJsonSchema = (standardSchema, name = "Schema") => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
name,
|
|
19
|
-
schema: jsonSchema
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
} catch (error) {
|
|
23
|
-
}
|
|
24
|
-
throw new Error(
|
|
25
|
-
"Standard Schema conversion requires zod v4+ with toJSONSchema support. Please install zod@^4.0.0 or provide a JsonSchema object instead."
|
|
26
|
-
);
|
|
7
|
+
const jsonSchema = z.toJSONSchema(standardSchema);
|
|
8
|
+
return {
|
|
9
|
+
name,
|
|
10
|
+
schema: jsonSchema
|
|
11
|
+
};
|
|
27
12
|
};
|
|
28
13
|
var convertMCPSchemaToToolSchema = (mcpSchema) => {
|
|
29
14
|
if (!mcpSchema?.properties) return {};
|
|
@@ -33,7 +18,8 @@ var convertMCPSchemaToToolSchema = (mcpSchema) => {
|
|
|
33
18
|
result[key] = {
|
|
34
19
|
type: prop.type || "string",
|
|
35
20
|
description: prop.description || "",
|
|
36
|
-
optional: !mcpSchema.required?.includes(key)
|
|
21
|
+
optional: !mcpSchema.required?.includes(key),
|
|
22
|
+
...prop.enum && { enum: prop.enum }
|
|
37
23
|
};
|
|
38
24
|
}
|
|
39
25
|
return result;
|
|
@@ -44,6 +30,10 @@ function normalizeSchema(schema, name) {
|
|
|
44
30
|
}
|
|
45
31
|
return schema;
|
|
46
32
|
}
|
|
33
|
+
var convertStandardSchemaToSchemaProperties = (standardSchema) => {
|
|
34
|
+
const jsonSchema = z.toJSONSchema(standardSchema);
|
|
35
|
+
return convertMCPSchemaToToolSchema(jsonSchema);
|
|
36
|
+
};
|
|
47
37
|
|
|
48
38
|
// src/mcp.ts
|
|
49
39
|
var createMCPTools = async (client) => {
|
|
@@ -82,9 +72,10 @@ var Inherit = /* @__PURE__ */ ((Inherit2) => {
|
|
|
82
72
|
|
|
83
73
|
// src/utils.ts
|
|
84
74
|
var toolConfigToToolDefinition = (tool) => {
|
|
75
|
+
const schema = isStandardSchema(tool.schema) ? convertStandardSchemaToSchemaProperties(tool.schema) : tool.schema;
|
|
85
76
|
const properties = {};
|
|
86
77
|
const required = [];
|
|
87
|
-
for (const [key, prop] of Object.entries(
|
|
78
|
+
for (const [key, prop] of Object.entries(schema)) {
|
|
88
79
|
properties[key] = convertSchemaProperty(prop);
|
|
89
80
|
if (!prop.optional) {
|
|
90
81
|
required.push(key);
|
|
@@ -150,6 +141,49 @@ var maxCalls = (toolConfig, maxCalls2) => ({
|
|
|
150
141
|
_maxCalls: maxCalls2
|
|
151
142
|
});
|
|
152
143
|
|
|
144
|
+
// src/embed.ts
|
|
145
|
+
import { pipeline } from "@huggingface/transformers";
|
|
146
|
+
var modelCache = /* @__PURE__ */ new Map();
|
|
147
|
+
var embed = async (model2, text, config) => {
|
|
148
|
+
if (model2.startsWith("openai/")) {
|
|
149
|
+
const modelName = model2.replace("openai/", "");
|
|
150
|
+
const apiKey = getKey("openai") || process.env.OPENAI_API_KEY;
|
|
151
|
+
if (!apiKey) {
|
|
152
|
+
throw new Error("OpenAI API key not found");
|
|
153
|
+
}
|
|
154
|
+
const body = {
|
|
155
|
+
model: modelName,
|
|
156
|
+
input: text
|
|
157
|
+
};
|
|
158
|
+
if (config?.dimensions) {
|
|
159
|
+
body.dimensions = config.dimensions;
|
|
160
|
+
}
|
|
161
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
162
|
+
method: "POST",
|
|
163
|
+
headers: {
|
|
164
|
+
"Content-Type": "application/json",
|
|
165
|
+
Authorization: `Bearer ${apiKey}`
|
|
166
|
+
},
|
|
167
|
+
body: JSON.stringify(body)
|
|
168
|
+
});
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
const error = await response.text();
|
|
171
|
+
throw new Error(`OpenAI API error: ${error}`);
|
|
172
|
+
}
|
|
173
|
+
const data = await response.json();
|
|
174
|
+
return data.data[0].embedding;
|
|
175
|
+
}
|
|
176
|
+
if (!modelCache.has(model2)) {
|
|
177
|
+
const extractor2 = await pipeline("feature-extraction", model2, {
|
|
178
|
+
dtype: "fp32"
|
|
179
|
+
});
|
|
180
|
+
modelCache.set(model2, extractor2);
|
|
181
|
+
}
|
|
182
|
+
const extractor = modelCache.get(model2);
|
|
183
|
+
const result = await extractor(text, { pooling: "mean", normalize: true });
|
|
184
|
+
return Array.from(result.data);
|
|
185
|
+
};
|
|
186
|
+
|
|
153
187
|
// src/providers/openai.ts
|
|
154
188
|
var appendToolCalls = (toolCalls, tcchunklist) => {
|
|
155
189
|
for (const tcchunk of tcchunklist) {
|
|
@@ -281,18 +315,66 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
281
315
|
};
|
|
282
316
|
|
|
283
317
|
// src/providers/anthropic.ts
|
|
318
|
+
var convertToAnthropicFormat = (messages) => {
|
|
319
|
+
const result = [];
|
|
320
|
+
let i = 0;
|
|
321
|
+
while (i < messages.length) {
|
|
322
|
+
const msg = messages[i];
|
|
323
|
+
if (msg.role === "system") {
|
|
324
|
+
i++;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (msg.role === "assistant") {
|
|
328
|
+
if (msg.tool_calls) {
|
|
329
|
+
result.push({
|
|
330
|
+
role: "assistant",
|
|
331
|
+
content: msg.tool_calls.map((tc) => ({
|
|
332
|
+
type: "tool_use",
|
|
333
|
+
id: tc.id,
|
|
334
|
+
name: tc.function.name,
|
|
335
|
+
input: JSON.parse(tc.function.arguments)
|
|
336
|
+
}))
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
result.push({
|
|
340
|
+
role: "assistant",
|
|
341
|
+
content: msg.content
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
i++;
|
|
345
|
+
} else if (msg.role === "tool") {
|
|
346
|
+
const toolResults = [];
|
|
347
|
+
while (i < messages.length && messages[i].role === "tool") {
|
|
348
|
+
const toolMsg = messages[i];
|
|
349
|
+
toolResults.push({
|
|
350
|
+
type: "tool_result",
|
|
351
|
+
tool_use_id: toolMsg.tool_call_id,
|
|
352
|
+
content: toolMsg.content
|
|
353
|
+
});
|
|
354
|
+
i++;
|
|
355
|
+
}
|
|
356
|
+
result.push({
|
|
357
|
+
role: "user",
|
|
358
|
+
content: toolResults
|
|
359
|
+
});
|
|
360
|
+
} else {
|
|
361
|
+
result.push(msg);
|
|
362
|
+
i++;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return result;
|
|
366
|
+
};
|
|
284
367
|
var callAnthropic = async (config, ctx) => {
|
|
285
368
|
const { model: model2, instructions, schema } = config;
|
|
286
369
|
const apiKey = getKey("anthropic") || process.env.ANTHROPIC_API_KEY;
|
|
287
370
|
if (!apiKey) {
|
|
288
371
|
throw new Error("Anthropic API key not found");
|
|
289
372
|
}
|
|
290
|
-
const messages = [...ctx.history];
|
|
291
373
|
let system = instructions;
|
|
292
|
-
if (
|
|
293
|
-
system =
|
|
294
|
-
messages.shift();
|
|
374
|
+
if (ctx.history[0]?.role === "system") {
|
|
375
|
+
system = ctx.history[0].content;
|
|
295
376
|
}
|
|
377
|
+
const messages = convertToAnthropicFormat(ctx.history);
|
|
296
378
|
if (schema) {
|
|
297
379
|
const schemaPrompt = `
|
|
298
380
|
|
|
@@ -394,10 +476,17 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
394
476
|
type: "function",
|
|
395
477
|
function: {
|
|
396
478
|
name: toolUse.name,
|
|
397
|
-
arguments:
|
|
398
|
-
}
|
|
479
|
+
arguments: ""
|
|
480
|
+
},
|
|
481
|
+
index: parsed.index
|
|
399
482
|
});
|
|
400
483
|
}
|
|
484
|
+
if (parsed.type === "content_block_delta" && parsed.delta?.type === "input_json_delta") {
|
|
485
|
+
const toolCall = toolCalls.find((tc) => tc.index === parsed.index);
|
|
486
|
+
if (toolCall) {
|
|
487
|
+
toolCall.function.arguments += parsed.delta.partial_json;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
401
490
|
} catch (e) {
|
|
402
491
|
}
|
|
403
492
|
}
|
|
@@ -411,7 +500,7 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
411
500
|
content: fullContent
|
|
412
501
|
};
|
|
413
502
|
if (toolCalls.length > 0) {
|
|
414
|
-
msg.tool_calls = toolCalls;
|
|
503
|
+
msg.tool_calls = toolCalls.map(({ index, ...tc }) => tc);
|
|
415
504
|
}
|
|
416
505
|
return {
|
|
417
506
|
...ctx,
|
|
@@ -633,7 +722,7 @@ var model = ({
|
|
|
633
722
|
tools: []
|
|
634
723
|
}
|
|
635
724
|
) : (
|
|
636
|
-
// model()(/* few shot
|
|
725
|
+
// model()(/* few shot or history */);
|
|
637
726
|
ctxOrMessage
|
|
638
727
|
);
|
|
639
728
|
const normalizedSchema = schema ? normalizeSchema(schema) : void 0;
|
|
@@ -664,27 +753,12 @@ var executeTools = async (ctx) => {
|
|
|
664
753
|
approvalCallback,
|
|
665
754
|
parallel = false,
|
|
666
755
|
retryCount = 0,
|
|
667
|
-
approvalId
|
|
756
|
+
approvalId,
|
|
757
|
+
executeOnApproval = false
|
|
668
758
|
} = toolConfig;
|
|
669
|
-
const approvalPromises = calls.map(async (call) => {
|
|
670
|
-
if (requireApproval) {
|
|
671
|
-
let approved;
|
|
672
|
-
if (approvalCallback) {
|
|
673
|
-
approved = await approvalCallback(call);
|
|
674
|
-
} else {
|
|
675
|
-
const response = await requestApproval(call, approvalId);
|
|
676
|
-
approved = response.approved;
|
|
677
|
-
}
|
|
678
|
-
return { call, approved };
|
|
679
|
-
} else {
|
|
680
|
-
return { call, approved: true };
|
|
681
|
-
}
|
|
682
|
-
});
|
|
683
|
-
const approvals = await Promise.all(approvalPromises);
|
|
684
759
|
const updatedCounts = { ...ctx.toolCallCounts || {} };
|
|
685
|
-
const runCall = async (call) => {
|
|
686
|
-
|
|
687
|
-
if (!approval?.approved) {
|
|
760
|
+
const runCall = async (call, approved) => {
|
|
761
|
+
if (!approved) {
|
|
688
762
|
if (ctx.stream) {
|
|
689
763
|
ctx.stream({
|
|
690
764
|
type: "tool_error",
|
|
@@ -745,7 +819,51 @@ var executeTools = async (ctx) => {
|
|
|
745
819
|
}
|
|
746
820
|
return { call, result: { error } };
|
|
747
821
|
};
|
|
748
|
-
|
|
822
|
+
if (executeOnApproval && requireApproval) {
|
|
823
|
+
const resultPromises = calls.map(async (call) => {
|
|
824
|
+
let approved;
|
|
825
|
+
if (approvalCallback) {
|
|
826
|
+
approved = await approvalCallback(call);
|
|
827
|
+
} else {
|
|
828
|
+
const response = await requestApproval(call, approvalId);
|
|
829
|
+
approved = response.approved;
|
|
830
|
+
}
|
|
831
|
+
return runCall(call, approved);
|
|
832
|
+
});
|
|
833
|
+
const results2 = await Promise.all(resultPromises);
|
|
834
|
+
return {
|
|
835
|
+
...ctx,
|
|
836
|
+
history: [
|
|
837
|
+
...ctx.history,
|
|
838
|
+
...results2.map(({ call, result }) => ({
|
|
839
|
+
role: "tool",
|
|
840
|
+
tool_call_id: call.id,
|
|
841
|
+
content: JSON.stringify(result)
|
|
842
|
+
}))
|
|
843
|
+
],
|
|
844
|
+
toolCallCounts: updatedCounts
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
const approvalPromises = calls.map(async (call) => {
|
|
848
|
+
if (requireApproval) {
|
|
849
|
+
let approved;
|
|
850
|
+
if (approvalCallback) {
|
|
851
|
+
approved = await approvalCallback(call);
|
|
852
|
+
} else {
|
|
853
|
+
const response = await requestApproval(call, approvalId);
|
|
854
|
+
approved = response.approved;
|
|
855
|
+
}
|
|
856
|
+
return { call, approved };
|
|
857
|
+
} else {
|
|
858
|
+
return { call, approved: true };
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
const approvals = await Promise.all(approvalPromises);
|
|
862
|
+
const runCallWithApproval = async (call) => {
|
|
863
|
+
const approval = approvals.find((a) => a.call.id === call.id);
|
|
864
|
+
return runCall(call, approval?.approved ?? true);
|
|
865
|
+
};
|
|
866
|
+
const results = parallel ? await Promise.all(calls.map(runCallWithApproval)) : await runCallsSequentially(calls, runCallWithApproval);
|
|
749
867
|
return {
|
|
750
868
|
...ctx,
|
|
751
869
|
history: [
|
|
@@ -1074,13 +1192,68 @@ var scope = (config, ...steps) => {
|
|
|
1074
1192
|
};
|
|
1075
1193
|
};
|
|
1076
1194
|
};
|
|
1195
|
+
|
|
1196
|
+
// src/utils/rateLimited.ts
|
|
1197
|
+
var rateLimited = (config) => (fn) => {
|
|
1198
|
+
const { rps, burst, concurrency } = config;
|
|
1199
|
+
let tokens = burst;
|
|
1200
|
+
let inFlight = 0;
|
|
1201
|
+
const queue = [];
|
|
1202
|
+
let intervalId = null;
|
|
1203
|
+
const refillTokens = () => {
|
|
1204
|
+
tokens = Math.min(tokens + 1, burst);
|
|
1205
|
+
processQueue();
|
|
1206
|
+
};
|
|
1207
|
+
const startInterval = () => {
|
|
1208
|
+
if (!intervalId) {
|
|
1209
|
+
intervalId = setInterval(refillTokens, 1e3 / rps);
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
const stopInterval = () => {
|
|
1213
|
+
if (intervalId && queue.length === 0 && inFlight === 0) {
|
|
1214
|
+
clearInterval(intervalId);
|
|
1215
|
+
intervalId = null;
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
const processQueue = () => {
|
|
1219
|
+
while (queue.length > 0 && tokens > 0 && inFlight < concurrency) {
|
|
1220
|
+
tokens--;
|
|
1221
|
+
inFlight++;
|
|
1222
|
+
const item = queue.shift();
|
|
1223
|
+
item.fn().then((result) => {
|
|
1224
|
+
inFlight--;
|
|
1225
|
+
item.resolve(result);
|
|
1226
|
+
processQueue();
|
|
1227
|
+
stopInterval();
|
|
1228
|
+
}).catch((error) => {
|
|
1229
|
+
inFlight--;
|
|
1230
|
+
item.reject(error);
|
|
1231
|
+
processQueue();
|
|
1232
|
+
stopInterval();
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
return (async (...args) => {
|
|
1237
|
+
return new Promise((resolve, reject) => {
|
|
1238
|
+
queue.push({
|
|
1239
|
+
fn: () => fn(...args),
|
|
1240
|
+
resolve,
|
|
1241
|
+
reject
|
|
1242
|
+
});
|
|
1243
|
+
startInterval();
|
|
1244
|
+
processQueue();
|
|
1245
|
+
});
|
|
1246
|
+
});
|
|
1247
|
+
};
|
|
1077
1248
|
export {
|
|
1078
1249
|
Inherit,
|
|
1079
1250
|
appendToLastRequest,
|
|
1080
1251
|
compose,
|
|
1081
1252
|
convertMCPSchemaToToolSchema,
|
|
1082
1253
|
convertStandardSchemaToJsonSchema,
|
|
1254
|
+
convertStandardSchemaToSchemaProperties,
|
|
1083
1255
|
createMCPTools,
|
|
1256
|
+
embed,
|
|
1084
1257
|
everyNMessages,
|
|
1085
1258
|
everyNTokens,
|
|
1086
1259
|
generateApprovalToken,
|
|
@@ -1094,6 +1267,7 @@ export {
|
|
|
1094
1267
|
onApprovalRequested,
|
|
1095
1268
|
onApprovalResolved,
|
|
1096
1269
|
parseModelName,
|
|
1270
|
+
rateLimited,
|
|
1097
1271
|
removeApprovalListener,
|
|
1098
1272
|
requestApproval,
|
|
1099
1273
|
resolveApproval,
|