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