@threaded/ai 1.0.1 → 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 +285 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -11
- package/dist/index.d.ts +92 -11
- package/dist/index.js +282 -90
- package/dist/index.js.map +1 -1
- package/package.json +6 -11
package/dist/index.cjs
CHANGED
|
@@ -25,7 +25,9 @@ __export(index_exports, {
|
|
|
25
25
|
compose: () => compose,
|
|
26
26
|
convertMCPSchemaToToolSchema: () => convertMCPSchemaToToolSchema,
|
|
27
27
|
convertStandardSchemaToJsonSchema: () => convertStandardSchemaToJsonSchema,
|
|
28
|
+
convertStandardSchemaToSchemaProperties: () => convertStandardSchemaToSchemaProperties,
|
|
28
29
|
createMCPTools: () => createMCPTools,
|
|
30
|
+
embed: () => embed,
|
|
29
31
|
everyNMessages: () => everyNMessages,
|
|
30
32
|
everyNTokens: () => everyNTokens,
|
|
31
33
|
generateApprovalToken: () => generateApprovalToken,
|
|
@@ -39,6 +41,7 @@ __export(index_exports, {
|
|
|
39
41
|
onApprovalRequested: () => onApprovalRequested,
|
|
40
42
|
onApprovalResolved: () => onApprovalResolved,
|
|
41
43
|
parseModelName: () => parseModelName,
|
|
44
|
+
rateLimited: () => rateLimited,
|
|
42
45
|
removeApprovalListener: () => removeApprovalListener,
|
|
43
46
|
requestApproval: () => requestApproval,
|
|
44
47
|
resolveApproval: () => resolveApproval,
|
|
@@ -54,24 +57,16 @@ __export(index_exports, {
|
|
|
54
57
|
module.exports = __toCommonJS(index_exports);
|
|
55
58
|
|
|
56
59
|
// src/schema.ts
|
|
60
|
+
var import_zod = require("zod");
|
|
57
61
|
var isStandardSchema = (schema) => {
|
|
58
62
|
return schema && typeof schema === "object" && "~standard" in schema;
|
|
59
63
|
};
|
|
60
64
|
var convertStandardSchemaToJsonSchema = (standardSchema, name = "Schema") => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
name,
|
|
67
|
-
schema: jsonSchema
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
} catch (error) {
|
|
71
|
-
}
|
|
72
|
-
throw new Error(
|
|
73
|
-
"Standard Schema conversion requires zod v4+ with toJSONSchema support. Please install zod@^4.0.0 or provide a JsonSchema object instead."
|
|
74
|
-
);
|
|
65
|
+
const jsonSchema = import_zod.z.toJSONSchema(standardSchema);
|
|
66
|
+
return {
|
|
67
|
+
name,
|
|
68
|
+
schema: jsonSchema
|
|
69
|
+
};
|
|
75
70
|
};
|
|
76
71
|
var convertMCPSchemaToToolSchema = (mcpSchema) => {
|
|
77
72
|
if (!mcpSchema?.properties) return {};
|
|
@@ -92,6 +87,10 @@ function normalizeSchema(schema, name) {
|
|
|
92
87
|
}
|
|
93
88
|
return schema;
|
|
94
89
|
}
|
|
90
|
+
var convertStandardSchemaToSchemaProperties = (standardSchema) => {
|
|
91
|
+
const jsonSchema = import_zod.z.toJSONSchema(standardSchema);
|
|
92
|
+
return convertMCPSchemaToToolSchema(jsonSchema);
|
|
93
|
+
};
|
|
95
94
|
|
|
96
95
|
// src/mcp.ts
|
|
97
96
|
var createMCPTools = async (client) => {
|
|
@@ -130,9 +129,10 @@ var Inherit = /* @__PURE__ */ ((Inherit2) => {
|
|
|
130
129
|
|
|
131
130
|
// src/utils.ts
|
|
132
131
|
var toolConfigToToolDefinition = (tool) => {
|
|
132
|
+
const schema = isStandardSchema(tool.schema) ? convertStandardSchemaToSchemaProperties(tool.schema) : tool.schema;
|
|
133
133
|
const properties = {};
|
|
134
134
|
const required = [];
|
|
135
|
-
for (const [key, prop] of Object.entries(
|
|
135
|
+
for (const [key, prop] of Object.entries(schema)) {
|
|
136
136
|
properties[key] = convertSchemaProperty(prop);
|
|
137
137
|
if (!prop.optional) {
|
|
138
138
|
required.push(key);
|
|
@@ -198,7 +198,66 @@ var maxCalls = (toolConfig, maxCalls2) => ({
|
|
|
198
198
|
_maxCalls: maxCalls2
|
|
199
199
|
});
|
|
200
200
|
|
|
201
|
+
// src/embed.ts
|
|
202
|
+
var import_transformers = require("@huggingface/transformers");
|
|
203
|
+
var modelCache = /* @__PURE__ */ new Map();
|
|
204
|
+
var embed = async (model2, text, config) => {
|
|
205
|
+
if (model2.startsWith("openai/")) {
|
|
206
|
+
const modelName = model2.replace("openai/", "");
|
|
207
|
+
const apiKey = getKey("openai") || process.env.OPENAI_API_KEY;
|
|
208
|
+
if (!apiKey) {
|
|
209
|
+
throw new Error("OpenAI API key not found");
|
|
210
|
+
}
|
|
211
|
+
const body = {
|
|
212
|
+
model: modelName,
|
|
213
|
+
input: text
|
|
214
|
+
};
|
|
215
|
+
if (config?.dimensions) {
|
|
216
|
+
body.dimensions = config.dimensions;
|
|
217
|
+
}
|
|
218
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: {
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
Authorization: `Bearer ${apiKey}`
|
|
223
|
+
},
|
|
224
|
+
body: JSON.stringify(body)
|
|
225
|
+
});
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
const error = await response.text();
|
|
228
|
+
throw new Error(`OpenAI API error: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
const data = await response.json();
|
|
231
|
+
return data.data[0].embedding;
|
|
232
|
+
}
|
|
233
|
+
if (!modelCache.has(model2)) {
|
|
234
|
+
const extractor2 = await (0, import_transformers.pipeline)("feature-extraction", model2, {
|
|
235
|
+
dtype: "fp32"
|
|
236
|
+
});
|
|
237
|
+
modelCache.set(model2, extractor2);
|
|
238
|
+
}
|
|
239
|
+
const extractor = modelCache.get(model2);
|
|
240
|
+
const result = await extractor(text, { pooling: "mean", normalize: true });
|
|
241
|
+
return Array.from(result.data);
|
|
242
|
+
};
|
|
243
|
+
|
|
201
244
|
// src/providers/openai.ts
|
|
245
|
+
var appendToolCalls = (toolCalls, tcchunklist) => {
|
|
246
|
+
for (const tcchunk of tcchunklist) {
|
|
247
|
+
while (toolCalls.length <= tcchunk.index) {
|
|
248
|
+
toolCalls.push({
|
|
249
|
+
id: "",
|
|
250
|
+
type: "function",
|
|
251
|
+
function: { name: "", arguments: "" }
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
const tc = toolCalls[tcchunk.index];
|
|
255
|
+
tc.id += tcchunk.id || "";
|
|
256
|
+
tc.function.name += tcchunk.function?.name || "";
|
|
257
|
+
tc.function.arguments += tcchunk.function?.arguments || "";
|
|
258
|
+
}
|
|
259
|
+
return toolCalls;
|
|
260
|
+
};
|
|
202
261
|
var callOpenAI = async (config, ctx) => {
|
|
203
262
|
const { model: model2, instructions, schema } = config;
|
|
204
263
|
const apiKey = getKey("openai") || process.env.OPENAI_API_KEY;
|
|
@@ -265,17 +324,19 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
265
324
|
const decoder = new TextDecoder();
|
|
266
325
|
let fullContent = "";
|
|
267
326
|
let toolCalls = [];
|
|
268
|
-
|
|
327
|
+
let buffer = "";
|
|
269
328
|
try {
|
|
270
329
|
while (true) {
|
|
271
330
|
const { done, value } = await reader.read();
|
|
272
331
|
if (done) break;
|
|
273
|
-
|
|
274
|
-
const lines =
|
|
332
|
+
buffer += decoder.decode(value, { stream: true });
|
|
333
|
+
const lines = buffer.split("\n");
|
|
334
|
+
buffer = lines.pop() || "";
|
|
275
335
|
for (const line of lines) {
|
|
276
336
|
if (line.startsWith("data: ")) {
|
|
277
|
-
const data = line.slice(6);
|
|
337
|
+
const data = line.slice(6).trim();
|
|
278
338
|
if (data === "[DONE]") continue;
|
|
339
|
+
if (!data) continue;
|
|
279
340
|
try {
|
|
280
341
|
const parsed = JSON.parse(data);
|
|
281
342
|
const delta = parsed.choices?.[0]?.delta;
|
|
@@ -286,25 +347,7 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
286
347
|
}
|
|
287
348
|
}
|
|
288
349
|
if (delta?.tool_calls) {
|
|
289
|
-
|
|
290
|
-
const { index } = toolCall;
|
|
291
|
-
if (!toolCallsBuffer[index]) {
|
|
292
|
-
toolCallsBuffer[index] = {
|
|
293
|
-
id: toolCall.id || "",
|
|
294
|
-
type: "function",
|
|
295
|
-
function: { name: "", arguments: "" }
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
if (toolCall.id) {
|
|
299
|
-
toolCallsBuffer[index].id = toolCall.id;
|
|
300
|
-
}
|
|
301
|
-
if (toolCall.function?.name) {
|
|
302
|
-
toolCallsBuffer[index].function.name += toolCall.function.name;
|
|
303
|
-
}
|
|
304
|
-
if (toolCall.function?.arguments) {
|
|
305
|
-
toolCallsBuffer[index].function.arguments += toolCall.function.arguments;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
350
|
+
toolCalls = appendToolCalls(toolCalls, delta.tool_calls);
|
|
308
351
|
}
|
|
309
352
|
} catch (e) {
|
|
310
353
|
}
|
|
@@ -314,7 +357,6 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
314
357
|
} finally {
|
|
315
358
|
reader.releaseLock();
|
|
316
359
|
}
|
|
317
|
-
toolCalls = Object.values(toolCallsBuffer);
|
|
318
360
|
const msg = {
|
|
319
361
|
role: "assistant",
|
|
320
362
|
content: fullContent
|
|
@@ -330,18 +372,66 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
330
372
|
};
|
|
331
373
|
|
|
332
374
|
// src/providers/anthropic.ts
|
|
375
|
+
var convertToAnthropicFormat = (messages) => {
|
|
376
|
+
const result = [];
|
|
377
|
+
let i = 0;
|
|
378
|
+
while (i < messages.length) {
|
|
379
|
+
const msg = messages[i];
|
|
380
|
+
if (msg.role === "system") {
|
|
381
|
+
i++;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (msg.role === "assistant") {
|
|
385
|
+
if (msg.tool_calls) {
|
|
386
|
+
result.push({
|
|
387
|
+
role: "assistant",
|
|
388
|
+
content: msg.tool_calls.map((tc) => ({
|
|
389
|
+
type: "tool_use",
|
|
390
|
+
id: tc.id,
|
|
391
|
+
name: tc.function.name,
|
|
392
|
+
input: JSON.parse(tc.function.arguments)
|
|
393
|
+
}))
|
|
394
|
+
});
|
|
395
|
+
} else {
|
|
396
|
+
result.push({
|
|
397
|
+
role: "assistant",
|
|
398
|
+
content: msg.content
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
i++;
|
|
402
|
+
} else if (msg.role === "tool") {
|
|
403
|
+
const toolResults = [];
|
|
404
|
+
while (i < messages.length && messages[i].role === "tool") {
|
|
405
|
+
const toolMsg = messages[i];
|
|
406
|
+
toolResults.push({
|
|
407
|
+
type: "tool_result",
|
|
408
|
+
tool_use_id: toolMsg.tool_call_id,
|
|
409
|
+
content: toolMsg.content
|
|
410
|
+
});
|
|
411
|
+
i++;
|
|
412
|
+
}
|
|
413
|
+
result.push({
|
|
414
|
+
role: "user",
|
|
415
|
+
content: toolResults
|
|
416
|
+
});
|
|
417
|
+
} else {
|
|
418
|
+
result.push(msg);
|
|
419
|
+
i++;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
};
|
|
333
424
|
var callAnthropic = async (config, ctx) => {
|
|
334
425
|
const { model: model2, instructions, schema } = config;
|
|
335
426
|
const apiKey = getKey("anthropic") || process.env.ANTHROPIC_API_KEY;
|
|
336
427
|
if (!apiKey) {
|
|
337
428
|
throw new Error("Anthropic API key not found");
|
|
338
429
|
}
|
|
339
|
-
const messages = [...ctx.history];
|
|
340
430
|
let system = instructions;
|
|
341
|
-
if (
|
|
342
|
-
system =
|
|
343
|
-
messages.shift();
|
|
431
|
+
if (ctx.history[0]?.role === "system") {
|
|
432
|
+
system = ctx.history[0].content;
|
|
344
433
|
}
|
|
434
|
+
const messages = convertToAnthropicFormat(ctx.history);
|
|
345
435
|
if (schema) {
|
|
346
436
|
const schemaPrompt = `
|
|
347
437
|
|
|
@@ -416,15 +506,18 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
416
506
|
const decoder = new TextDecoder();
|
|
417
507
|
let fullContent = "";
|
|
418
508
|
const toolCalls = [];
|
|
509
|
+
let buffer = "";
|
|
419
510
|
try {
|
|
420
511
|
while (true) {
|
|
421
512
|
const { done, value } = await reader.read();
|
|
422
513
|
if (done) break;
|
|
423
|
-
|
|
424
|
-
const lines =
|
|
514
|
+
buffer += decoder.decode(value, { stream: true });
|
|
515
|
+
const lines = buffer.split("\n");
|
|
516
|
+
buffer = lines.pop() || "";
|
|
425
517
|
for (const line of lines) {
|
|
426
518
|
if (line.startsWith("data: ")) {
|
|
427
|
-
const data = line.slice(6);
|
|
519
|
+
const data = line.slice(6).trim();
|
|
520
|
+
if (!data) continue;
|
|
428
521
|
try {
|
|
429
522
|
const parsed = JSON.parse(data);
|
|
430
523
|
if (parsed.type === "content_block_delta" && parsed.delta?.text) {
|
|
@@ -440,10 +533,17 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
440
533
|
type: "function",
|
|
441
534
|
function: {
|
|
442
535
|
name: toolUse.name,
|
|
443
|
-
arguments:
|
|
444
|
-
}
|
|
536
|
+
arguments: ""
|
|
537
|
+
},
|
|
538
|
+
index: parsed.index
|
|
445
539
|
});
|
|
446
540
|
}
|
|
541
|
+
if (parsed.type === "content_block_delta" && parsed.delta?.type === "input_json_delta") {
|
|
542
|
+
const toolCall = toolCalls.find((tc) => tc.index === parsed.index);
|
|
543
|
+
if (toolCall) {
|
|
544
|
+
toolCall.function.arguments += parsed.delta.partial_json;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
447
547
|
} catch (e) {
|
|
448
548
|
}
|
|
449
549
|
}
|
|
@@ -457,7 +557,7 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
457
557
|
content: fullContent
|
|
458
558
|
};
|
|
459
559
|
if (toolCalls.length > 0) {
|
|
460
|
-
msg.tool_calls = toolCalls;
|
|
560
|
+
msg.tool_calls = toolCalls.map(({ index, ...tc }) => tc);
|
|
461
561
|
}
|
|
462
562
|
return {
|
|
463
563
|
...ctx,
|
|
@@ -553,15 +653,18 @@ var handleGoogleStream = async (response, ctx) => {
|
|
|
553
653
|
const decoder = new TextDecoder();
|
|
554
654
|
let fullContent = "";
|
|
555
655
|
const toolCalls = [];
|
|
656
|
+
let buffer = "";
|
|
556
657
|
try {
|
|
557
658
|
while (true) {
|
|
558
659
|
const { done, value } = await reader.read();
|
|
559
660
|
if (done) break;
|
|
560
|
-
|
|
561
|
-
const lines =
|
|
661
|
+
buffer += decoder.decode(value, { stream: true });
|
|
662
|
+
const lines = buffer.split("\n");
|
|
663
|
+
buffer = lines.pop() || "";
|
|
562
664
|
for (const line of lines) {
|
|
563
665
|
if (line.startsWith("data: ")) {
|
|
564
|
-
const data = line.slice(6);
|
|
666
|
+
const data = line.slice(6).trim();
|
|
667
|
+
if (!data) continue;
|
|
565
668
|
try {
|
|
566
669
|
const parsed = JSON.parse(data);
|
|
567
670
|
const candidate = parsed.candidates?.[0];
|
|
@@ -669,10 +772,16 @@ var model = ({
|
|
|
669
772
|
schema
|
|
670
773
|
} = {}) => {
|
|
671
774
|
return async (ctxOrMessage) => {
|
|
672
|
-
const ctx = typeof ctxOrMessage === "string" ?
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
775
|
+
const ctx = typeof ctxOrMessage === "string" ? (
|
|
776
|
+
// model()("hello!");
|
|
777
|
+
{
|
|
778
|
+
history: [{ role: "user", content: ctxOrMessage }],
|
|
779
|
+
tools: []
|
|
780
|
+
}
|
|
781
|
+
) : (
|
|
782
|
+
// model()(/* few shot or history */);
|
|
783
|
+
ctxOrMessage
|
|
784
|
+
);
|
|
676
785
|
const normalizedSchema = schema ? normalizeSchema(schema) : void 0;
|
|
677
786
|
const systemMessage = ctx.history.find((m) => m.role === "system");
|
|
678
787
|
const instructions = systemMessage?.content;
|
|
@@ -701,29 +810,18 @@ var executeTools = async (ctx) => {
|
|
|
701
810
|
approvalCallback,
|
|
702
811
|
parallel = false,
|
|
703
812
|
retryCount = 0,
|
|
704
|
-
approvalId
|
|
813
|
+
approvalId,
|
|
814
|
+
executeOnApproval = false
|
|
705
815
|
} = toolConfig;
|
|
706
|
-
const approvalPromises = calls.map(async (call) => {
|
|
707
|
-
if (requireApproval) {
|
|
708
|
-
let approved;
|
|
709
|
-
if (approvalCallback) {
|
|
710
|
-
approved = await approvalCallback(call);
|
|
711
|
-
} else {
|
|
712
|
-
const response = await requestApproval(call, approvalId);
|
|
713
|
-
approved = response.approved;
|
|
714
|
-
}
|
|
715
|
-
return { call, approved };
|
|
716
|
-
} else {
|
|
717
|
-
return { call, approved: true };
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
const approvals = await Promise.all(approvalPromises);
|
|
721
816
|
const updatedCounts = { ...ctx.toolCallCounts || {} };
|
|
722
|
-
const runCall = async (call) => {
|
|
723
|
-
|
|
724
|
-
if (!approval?.approved) {
|
|
817
|
+
const runCall = async (call, approved) => {
|
|
818
|
+
if (!approved) {
|
|
725
819
|
if (ctx.stream) {
|
|
726
|
-
ctx.stream({
|
|
820
|
+
ctx.stream({
|
|
821
|
+
type: "tool_error",
|
|
822
|
+
call,
|
|
823
|
+
error: "Tool execution denied by user"
|
|
824
|
+
});
|
|
727
825
|
}
|
|
728
826
|
return {
|
|
729
827
|
call,
|
|
@@ -778,7 +876,51 @@ var executeTools = async (ctx) => {
|
|
|
778
876
|
}
|
|
779
877
|
return { call, result: { error } };
|
|
780
878
|
};
|
|
781
|
-
|
|
879
|
+
if (executeOnApproval && requireApproval) {
|
|
880
|
+
const resultPromises = calls.map(async (call) => {
|
|
881
|
+
let approved;
|
|
882
|
+
if (approvalCallback) {
|
|
883
|
+
approved = await approvalCallback(call);
|
|
884
|
+
} else {
|
|
885
|
+
const response = await requestApproval(call, approvalId);
|
|
886
|
+
approved = response.approved;
|
|
887
|
+
}
|
|
888
|
+
return runCall(call, approved);
|
|
889
|
+
});
|
|
890
|
+
const results2 = await Promise.all(resultPromises);
|
|
891
|
+
return {
|
|
892
|
+
...ctx,
|
|
893
|
+
history: [
|
|
894
|
+
...ctx.history,
|
|
895
|
+
...results2.map(({ call, result }) => ({
|
|
896
|
+
role: "tool",
|
|
897
|
+
tool_call_id: call.id,
|
|
898
|
+
content: JSON.stringify(result)
|
|
899
|
+
}))
|
|
900
|
+
],
|
|
901
|
+
toolCallCounts: updatedCounts
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
const approvalPromises = calls.map(async (call) => {
|
|
905
|
+
if (requireApproval) {
|
|
906
|
+
let approved;
|
|
907
|
+
if (approvalCallback) {
|
|
908
|
+
approved = await approvalCallback(call);
|
|
909
|
+
} else {
|
|
910
|
+
const response = await requestApproval(call, approvalId);
|
|
911
|
+
approved = response.approved;
|
|
912
|
+
}
|
|
913
|
+
return { call, approved };
|
|
914
|
+
} else {
|
|
915
|
+
return { call, approved: true };
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
const approvals = await Promise.all(approvalPromises);
|
|
919
|
+
const runCallWithApproval = async (call) => {
|
|
920
|
+
const approval = approvals.find((a) => a.call.id === call.id);
|
|
921
|
+
return runCall(call, approval?.approved ?? true);
|
|
922
|
+
};
|
|
923
|
+
const results = parallel ? await Promise.all(calls.map(runCallWithApproval)) : await runCallsSequentially(calls, runCallWithApproval);
|
|
782
924
|
return {
|
|
783
925
|
...ctx,
|
|
784
926
|
history: [
|
|
@@ -844,14 +986,15 @@ var createThread = (id, store) => {
|
|
|
844
986
|
}
|
|
845
987
|
};
|
|
846
988
|
};
|
|
847
|
-
var defaultStore = createMemoryStore();
|
|
848
989
|
var threads = /* @__PURE__ */ new Map();
|
|
849
|
-
var getOrCreateThread = (id, store
|
|
850
|
-
|
|
851
|
-
|
|
990
|
+
var getOrCreateThread = (id, store) => {
|
|
991
|
+
const cacheKey = store ? `${id}-${store}` : id;
|
|
992
|
+
if (threads.has(cacheKey)) {
|
|
993
|
+
return threads.get(cacheKey);
|
|
852
994
|
}
|
|
853
|
-
const
|
|
854
|
-
|
|
995
|
+
const threadStore = store || createMemoryStore();
|
|
996
|
+
const thread = createThread(id, threadStore);
|
|
997
|
+
threads.set(cacheKey, thread);
|
|
855
998
|
return thread;
|
|
856
999
|
};
|
|
857
1000
|
|
|
@@ -1082,6 +1225,9 @@ var scopeContext = (config, ctx) => {
|
|
|
1082
1225
|
scopedCtx.history = [{ role: "system", content: config.system }, ...scopedCtx.history];
|
|
1083
1226
|
}
|
|
1084
1227
|
}
|
|
1228
|
+
if (config.stream) {
|
|
1229
|
+
scopedCtx.stream = config.stream;
|
|
1230
|
+
}
|
|
1085
1231
|
return scopedCtx;
|
|
1086
1232
|
};
|
|
1087
1233
|
var scope = (config, ...steps) => {
|
|
@@ -1103,6 +1249,59 @@ var scope = (config, ...steps) => {
|
|
|
1103
1249
|
};
|
|
1104
1250
|
};
|
|
1105
1251
|
};
|
|
1252
|
+
|
|
1253
|
+
// src/utils/rateLimited.ts
|
|
1254
|
+
var rateLimited = (config) => (fn) => {
|
|
1255
|
+
const { rps, burst, concurrency } = config;
|
|
1256
|
+
let tokens = burst;
|
|
1257
|
+
let inFlight = 0;
|
|
1258
|
+
const queue = [];
|
|
1259
|
+
let intervalId = null;
|
|
1260
|
+
const refillTokens = () => {
|
|
1261
|
+
tokens = Math.min(tokens + 1, burst);
|
|
1262
|
+
processQueue();
|
|
1263
|
+
};
|
|
1264
|
+
const startInterval = () => {
|
|
1265
|
+
if (!intervalId) {
|
|
1266
|
+
intervalId = setInterval(refillTokens, 1e3 / rps);
|
|
1267
|
+
}
|
|
1268
|
+
};
|
|
1269
|
+
const stopInterval = () => {
|
|
1270
|
+
if (intervalId && queue.length === 0 && inFlight === 0) {
|
|
1271
|
+
clearInterval(intervalId);
|
|
1272
|
+
intervalId = null;
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1275
|
+
const processQueue = () => {
|
|
1276
|
+
while (queue.length > 0 && tokens > 0 && inFlight < concurrency) {
|
|
1277
|
+
tokens--;
|
|
1278
|
+
inFlight++;
|
|
1279
|
+
const item = queue.shift();
|
|
1280
|
+
item.fn().then((result) => {
|
|
1281
|
+
inFlight--;
|
|
1282
|
+
item.resolve(result);
|
|
1283
|
+
processQueue();
|
|
1284
|
+
stopInterval();
|
|
1285
|
+
}).catch((error) => {
|
|
1286
|
+
inFlight--;
|
|
1287
|
+
item.reject(error);
|
|
1288
|
+
processQueue();
|
|
1289
|
+
stopInterval();
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
return (async (...args) => {
|
|
1294
|
+
return new Promise((resolve, reject) => {
|
|
1295
|
+
queue.push({
|
|
1296
|
+
fn: () => fn(...args),
|
|
1297
|
+
resolve,
|
|
1298
|
+
reject
|
|
1299
|
+
});
|
|
1300
|
+
startInterval();
|
|
1301
|
+
processQueue();
|
|
1302
|
+
});
|
|
1303
|
+
});
|
|
1304
|
+
};
|
|
1106
1305
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1107
1306
|
0 && (module.exports = {
|
|
1108
1307
|
Inherit,
|
|
@@ -1110,7 +1309,9 @@ var scope = (config, ...steps) => {
|
|
|
1110
1309
|
compose,
|
|
1111
1310
|
convertMCPSchemaToToolSchema,
|
|
1112
1311
|
convertStandardSchemaToJsonSchema,
|
|
1312
|
+
convertStandardSchemaToSchemaProperties,
|
|
1113
1313
|
createMCPTools,
|
|
1314
|
+
embed,
|
|
1114
1315
|
everyNMessages,
|
|
1115
1316
|
everyNTokens,
|
|
1116
1317
|
generateApprovalToken,
|
|
@@ -1124,6 +1325,7 @@ var scope = (config, ...steps) => {
|
|
|
1124
1325
|
onApprovalRequested,
|
|
1125
1326
|
onApprovalResolved,
|
|
1126
1327
|
parseModelName,
|
|
1328
|
+
rateLimited,
|
|
1127
1329
|
removeApprovalListener,
|
|
1128
1330
|
requestApproval,
|
|
1129
1331
|
resolveApproval,
|