@threaded/ai 1.0.0 → 1.0.2
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 +80 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.js +75 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -100,9 +100,10 @@ interface ScopeConfig {
|
|
|
100
100
|
system?: string;
|
|
101
101
|
silent?: boolean;
|
|
102
102
|
until?: (ctx: ConversationContext) => boolean;
|
|
103
|
+
stream?: (event: StreamEvent) => void;
|
|
103
104
|
}
|
|
104
105
|
type StepFunction = (ctx: ConversationContext) => Promise<ConversationContext>;
|
|
105
|
-
type ComposedFunction = (ctxOrMessage
|
|
106
|
+
type ComposedFunction = (ctxOrMessage: ConversationContext | string) => Promise<ConversationContext>;
|
|
106
107
|
interface JsonSchema {
|
|
107
108
|
name: string;
|
|
108
109
|
schema: {
|
|
@@ -146,6 +147,34 @@ interface RetryOptions {
|
|
|
146
147
|
|
|
147
148
|
declare const createMCPTools: (client: Client) => Promise<ToolConfig[]>;
|
|
148
149
|
|
|
150
|
+
declare const toolConfigToToolDefinition: (tool: ToolConfig) => ToolDefinition;
|
|
151
|
+
declare const parseModelName: (model: string) => ParsedModel;
|
|
152
|
+
declare const setKeys: (keys: ApiKeys) => void;
|
|
153
|
+
declare const getKey: (provider: string) => string;
|
|
154
|
+
declare const maxCalls: (toolConfig: ToolConfig, maxCalls: number) => ToolConfig;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @example
|
|
158
|
+
* // in-memory (default)
|
|
159
|
+
* const thread = getOrCreateThread('user-123');
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* // sqlite
|
|
163
|
+
* const thread = getOrCreateThread('user-123', {
|
|
164
|
+
* async get(id) {
|
|
165
|
+
* const row = await db.get('SELECT messages FROM threads WHERE id = ?', id);
|
|
166
|
+
* return row ? JSON.parse(row.messages) : [];
|
|
167
|
+
* },
|
|
168
|
+
* async set(id, messages) {
|
|
169
|
+
* await db.run(
|
|
170
|
+
* 'INSERT OR REPLACE INTO threads (id, messages, updated_at) VALUES (?, ?, ?)',
|
|
171
|
+
* id,
|
|
172
|
+
* JSON.stringify(messages),
|
|
173
|
+
* Date.now()
|
|
174
|
+
* );
|
|
175
|
+
* }
|
|
176
|
+
* });
|
|
177
|
+
*/
|
|
149
178
|
declare const getOrCreateThread: (id: string, store?: ThreadStore) => Thread;
|
|
150
179
|
|
|
151
180
|
declare const isStandardSchema: (schema: any) => schema is StandardSchema;
|
|
@@ -192,8 +221,8 @@ declare const when: (condition: (ctx: ConversationContext) => boolean, action: S
|
|
|
192
221
|
|
|
193
222
|
declare const model: ({ model, schema, }?: {
|
|
194
223
|
model?: string;
|
|
195
|
-
schema?:
|
|
196
|
-
}) =>
|
|
224
|
+
schema?: JsonSchema | StandardSchema;
|
|
225
|
+
}) => ComposedFunction;
|
|
197
226
|
|
|
198
227
|
/**
|
|
199
228
|
* scope({}, retry({ times: 2 }, model(...)))
|
|
@@ -204,4 +233,4 @@ declare const scope: (config: ScopeConfig, ...steps: StepFunction[]) => StepFunc
|
|
|
204
233
|
|
|
205
234
|
declare const compose: (...steps: StepFunction[]) => ComposedFunction;
|
|
206
235
|
|
|
207
|
-
export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConversationContext, Inherit, type JsonSchema, type Message, type ParsedModel, type ProviderConfig, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, createMCPTools, everyNMessages, everyNTokens, generateApprovalToken, getOrCreateThread, isStandardSchema, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, removeApprovalListener, requestApproval, resolveApproval, retry, scope, tap, toolNotUsedInNTurns, toolWasCalled, when };
|
|
236
|
+
export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConversationContext, Inherit, type JsonSchema, type Message, type ParsedModel, type ProviderConfig, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, createMCPTools, everyNMessages, everyNTokens, generateApprovalToken, getKey, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
|
package/dist/index.d.ts
CHANGED
|
@@ -100,9 +100,10 @@ interface ScopeConfig {
|
|
|
100
100
|
system?: string;
|
|
101
101
|
silent?: boolean;
|
|
102
102
|
until?: (ctx: ConversationContext) => boolean;
|
|
103
|
+
stream?: (event: StreamEvent) => void;
|
|
103
104
|
}
|
|
104
105
|
type StepFunction = (ctx: ConversationContext) => Promise<ConversationContext>;
|
|
105
|
-
type ComposedFunction = (ctxOrMessage
|
|
106
|
+
type ComposedFunction = (ctxOrMessage: ConversationContext | string) => Promise<ConversationContext>;
|
|
106
107
|
interface JsonSchema {
|
|
107
108
|
name: string;
|
|
108
109
|
schema: {
|
|
@@ -146,6 +147,34 @@ interface RetryOptions {
|
|
|
146
147
|
|
|
147
148
|
declare const createMCPTools: (client: Client) => Promise<ToolConfig[]>;
|
|
148
149
|
|
|
150
|
+
declare const toolConfigToToolDefinition: (tool: ToolConfig) => ToolDefinition;
|
|
151
|
+
declare const parseModelName: (model: string) => ParsedModel;
|
|
152
|
+
declare const setKeys: (keys: ApiKeys) => void;
|
|
153
|
+
declare const getKey: (provider: string) => string;
|
|
154
|
+
declare const maxCalls: (toolConfig: ToolConfig, maxCalls: number) => ToolConfig;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @example
|
|
158
|
+
* // in-memory (default)
|
|
159
|
+
* const thread = getOrCreateThread('user-123');
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* // sqlite
|
|
163
|
+
* const thread = getOrCreateThread('user-123', {
|
|
164
|
+
* async get(id) {
|
|
165
|
+
* const row = await db.get('SELECT messages FROM threads WHERE id = ?', id);
|
|
166
|
+
* return row ? JSON.parse(row.messages) : [];
|
|
167
|
+
* },
|
|
168
|
+
* async set(id, messages) {
|
|
169
|
+
* await db.run(
|
|
170
|
+
* 'INSERT OR REPLACE INTO threads (id, messages, updated_at) VALUES (?, ?, ?)',
|
|
171
|
+
* id,
|
|
172
|
+
* JSON.stringify(messages),
|
|
173
|
+
* Date.now()
|
|
174
|
+
* );
|
|
175
|
+
* }
|
|
176
|
+
* });
|
|
177
|
+
*/
|
|
149
178
|
declare const getOrCreateThread: (id: string, store?: ThreadStore) => Thread;
|
|
150
179
|
|
|
151
180
|
declare const isStandardSchema: (schema: any) => schema is StandardSchema;
|
|
@@ -192,8 +221,8 @@ declare const when: (condition: (ctx: ConversationContext) => boolean, action: S
|
|
|
192
221
|
|
|
193
222
|
declare const model: ({ model, schema, }?: {
|
|
194
223
|
model?: string;
|
|
195
|
-
schema?:
|
|
196
|
-
}) =>
|
|
224
|
+
schema?: JsonSchema | StandardSchema;
|
|
225
|
+
}) => ComposedFunction;
|
|
197
226
|
|
|
198
227
|
/**
|
|
199
228
|
* scope({}, retry({ times: 2 }, model(...)))
|
|
@@ -204,4 +233,4 @@ declare const scope: (config: ScopeConfig, ...steps: StepFunction[]) => StepFunc
|
|
|
204
233
|
|
|
205
234
|
declare const compose: (...steps: StepFunction[]) => ComposedFunction;
|
|
206
235
|
|
|
207
|
-
export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConversationContext, Inherit, type JsonSchema, type Message, type ParsedModel, type ProviderConfig, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, createMCPTools, everyNMessages, everyNTokens, generateApprovalToken, getOrCreateThread, isStandardSchema, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, removeApprovalListener, requestApproval, resolveApproval, retry, scope, tap, toolNotUsedInNTurns, toolWasCalled, when };
|
|
236
|
+
export { type ApiKeys, type ApprovalRequest, type ApprovalResponse, type ComposedFunction, type ConversationContext, Inherit, type JsonSchema, type Message, type ParsedModel, type ProviderConfig, type RetryOptions, type SchemaProperty, type ScopeConfig, type StandardSchema, type StepFunction, type StreamEvent, type Thread, type ThreadStore, type ToolCall, type ToolCallResult, type ToolConfig, type ToolDefinition, type ToolExecutionConfig, appendToLastRequest, compose, convertMCPSchemaToToolSchema, convertStandardSchemaToJsonSchema, createMCPTools, everyNMessages, everyNTokens, generateApprovalToken, getKey, getOrCreateThread, isStandardSchema, maxCalls, model, noToolsCalled, normalizeSchema, onApprovalRequested, onApprovalResolved, parseModelName, removeApprovalListener, requestApproval, resolveApproval, retry, scope, setKeys, tap, toolConfigToToolDefinition, toolNotUsedInNTurns, toolWasCalled, when };
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,9 @@ var parseModelName = (model2) => {
|
|
|
135
135
|
};
|
|
136
136
|
};
|
|
137
137
|
var globalKeys = {};
|
|
138
|
+
var setKeys = (keys) => {
|
|
139
|
+
globalKeys = { ...globalKeys, ...keys };
|
|
140
|
+
};
|
|
138
141
|
var getKey = (provider) => {
|
|
139
142
|
const key = globalKeys[provider.toLowerCase()];
|
|
140
143
|
if (!key) {
|
|
@@ -142,8 +145,28 @@ var getKey = (provider) => {
|
|
|
142
145
|
}
|
|
143
146
|
return key;
|
|
144
147
|
};
|
|
148
|
+
var maxCalls = (toolConfig, maxCalls2) => ({
|
|
149
|
+
...toolConfig,
|
|
150
|
+
_maxCalls: maxCalls2
|
|
151
|
+
});
|
|
145
152
|
|
|
146
153
|
// src/providers/openai.ts
|
|
154
|
+
var appendToolCalls = (toolCalls, tcchunklist) => {
|
|
155
|
+
for (const tcchunk of tcchunklist) {
|
|
156
|
+
while (toolCalls.length <= tcchunk.index) {
|
|
157
|
+
toolCalls.push({
|
|
158
|
+
id: "",
|
|
159
|
+
type: "function",
|
|
160
|
+
function: { name: "", arguments: "" }
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const tc = toolCalls[tcchunk.index];
|
|
164
|
+
tc.id += tcchunk.id || "";
|
|
165
|
+
tc.function.name += tcchunk.function?.name || "";
|
|
166
|
+
tc.function.arguments += tcchunk.function?.arguments || "";
|
|
167
|
+
}
|
|
168
|
+
return toolCalls;
|
|
169
|
+
};
|
|
147
170
|
var callOpenAI = async (config, ctx) => {
|
|
148
171
|
const { model: model2, instructions, schema } = config;
|
|
149
172
|
const apiKey = getKey("openai") || process.env.OPENAI_API_KEY;
|
|
@@ -210,17 +233,19 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
210
233
|
const decoder = new TextDecoder();
|
|
211
234
|
let fullContent = "";
|
|
212
235
|
let toolCalls = [];
|
|
213
|
-
|
|
236
|
+
let buffer = "";
|
|
214
237
|
try {
|
|
215
238
|
while (true) {
|
|
216
239
|
const { done, value } = await reader.read();
|
|
217
240
|
if (done) break;
|
|
218
|
-
|
|
219
|
-
const lines =
|
|
241
|
+
buffer += decoder.decode(value, { stream: true });
|
|
242
|
+
const lines = buffer.split("\n");
|
|
243
|
+
buffer = lines.pop() || "";
|
|
220
244
|
for (const line of lines) {
|
|
221
245
|
if (line.startsWith("data: ")) {
|
|
222
|
-
const data = line.slice(6);
|
|
246
|
+
const data = line.slice(6).trim();
|
|
223
247
|
if (data === "[DONE]") continue;
|
|
248
|
+
if (!data) continue;
|
|
224
249
|
try {
|
|
225
250
|
const parsed = JSON.parse(data);
|
|
226
251
|
const delta = parsed.choices?.[0]?.delta;
|
|
@@ -231,25 +256,7 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
231
256
|
}
|
|
232
257
|
}
|
|
233
258
|
if (delta?.tool_calls) {
|
|
234
|
-
|
|
235
|
-
const { index } = toolCall;
|
|
236
|
-
if (!toolCallsBuffer[index]) {
|
|
237
|
-
toolCallsBuffer[index] = {
|
|
238
|
-
id: toolCall.id || "",
|
|
239
|
-
type: "function",
|
|
240
|
-
function: { name: "", arguments: "" }
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
if (toolCall.id) {
|
|
244
|
-
toolCallsBuffer[index].id = toolCall.id;
|
|
245
|
-
}
|
|
246
|
-
if (toolCall.function?.name) {
|
|
247
|
-
toolCallsBuffer[index].function.name += toolCall.function.name;
|
|
248
|
-
}
|
|
249
|
-
if (toolCall.function?.arguments) {
|
|
250
|
-
toolCallsBuffer[index].function.arguments += toolCall.function.arguments;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
259
|
+
toolCalls = appendToolCalls(toolCalls, delta.tool_calls);
|
|
253
260
|
}
|
|
254
261
|
} catch (e) {
|
|
255
262
|
}
|
|
@@ -259,7 +266,6 @@ var handleOpenAIStream = async (response, ctx) => {
|
|
|
259
266
|
} finally {
|
|
260
267
|
reader.releaseLock();
|
|
261
268
|
}
|
|
262
|
-
toolCalls = Object.values(toolCallsBuffer);
|
|
263
269
|
const msg = {
|
|
264
270
|
role: "assistant",
|
|
265
271
|
content: fullContent
|
|
@@ -361,15 +367,18 @@ var handleAnthropicStream = async (response, ctx) => {
|
|
|
361
367
|
const decoder = new TextDecoder();
|
|
362
368
|
let fullContent = "";
|
|
363
369
|
const toolCalls = [];
|
|
370
|
+
let buffer = "";
|
|
364
371
|
try {
|
|
365
372
|
while (true) {
|
|
366
373
|
const { done, value } = await reader.read();
|
|
367
374
|
if (done) break;
|
|
368
|
-
|
|
369
|
-
const lines =
|
|
375
|
+
buffer += decoder.decode(value, { stream: true });
|
|
376
|
+
const lines = buffer.split("\n");
|
|
377
|
+
buffer = lines.pop() || "";
|
|
370
378
|
for (const line of lines) {
|
|
371
379
|
if (line.startsWith("data: ")) {
|
|
372
|
-
const data = line.slice(6);
|
|
380
|
+
const data = line.slice(6).trim();
|
|
381
|
+
if (!data) continue;
|
|
373
382
|
try {
|
|
374
383
|
const parsed = JSON.parse(data);
|
|
375
384
|
if (parsed.type === "content_block_delta" && parsed.delta?.text) {
|
|
@@ -498,15 +507,18 @@ var handleGoogleStream = async (response, ctx) => {
|
|
|
498
507
|
const decoder = new TextDecoder();
|
|
499
508
|
let fullContent = "";
|
|
500
509
|
const toolCalls = [];
|
|
510
|
+
let buffer = "";
|
|
501
511
|
try {
|
|
502
512
|
while (true) {
|
|
503
513
|
const { done, value } = await reader.read();
|
|
504
514
|
if (done) break;
|
|
505
|
-
|
|
506
|
-
const lines =
|
|
515
|
+
buffer += decoder.decode(value, { stream: true });
|
|
516
|
+
const lines = buffer.split("\n");
|
|
517
|
+
buffer = lines.pop() || "";
|
|
507
518
|
for (const line of lines) {
|
|
508
519
|
if (line.startsWith("data: ")) {
|
|
509
|
-
const data = line.slice(6);
|
|
520
|
+
const data = line.slice(6).trim();
|
|
521
|
+
if (!data) continue;
|
|
510
522
|
try {
|
|
511
523
|
const parsed = JSON.parse(data);
|
|
512
524
|
const candidate = parsed.candidates?.[0];
|
|
@@ -614,10 +626,16 @@ var model = ({
|
|
|
614
626
|
schema
|
|
615
627
|
} = {}) => {
|
|
616
628
|
return async (ctxOrMessage) => {
|
|
617
|
-
const ctx = typeof ctxOrMessage === "string" ?
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
629
|
+
const ctx = typeof ctxOrMessage === "string" ? (
|
|
630
|
+
// model()("hello!");
|
|
631
|
+
{
|
|
632
|
+
history: [{ role: "user", content: ctxOrMessage }],
|
|
633
|
+
tools: []
|
|
634
|
+
}
|
|
635
|
+
) : (
|
|
636
|
+
// model()(/* few shot / history */);
|
|
637
|
+
ctxOrMessage
|
|
638
|
+
);
|
|
621
639
|
const normalizedSchema = schema ? normalizeSchema(schema) : void 0;
|
|
622
640
|
const systemMessage = ctx.history.find((m) => m.role === "system");
|
|
623
641
|
const instructions = systemMessage?.content;
|
|
@@ -668,7 +686,11 @@ var executeTools = async (ctx) => {
|
|
|
668
686
|
const approval = approvals.find((a) => a.call.id === call.id);
|
|
669
687
|
if (!approval?.approved) {
|
|
670
688
|
if (ctx.stream) {
|
|
671
|
-
ctx.stream({
|
|
689
|
+
ctx.stream({
|
|
690
|
+
type: "tool_error",
|
|
691
|
+
call,
|
|
692
|
+
error: "Tool execution denied by user"
|
|
693
|
+
});
|
|
672
694
|
}
|
|
673
695
|
return {
|
|
674
696
|
call,
|
|
@@ -677,10 +699,10 @@ var executeTools = async (ctx) => {
|
|
|
677
699
|
}
|
|
678
700
|
const toolName = call.function.name;
|
|
679
701
|
const limits = ctx.toolLimits || {};
|
|
680
|
-
const
|
|
702
|
+
const maxCalls2 = limits[toolName];
|
|
681
703
|
const currentCount = updatedCounts[toolName] || 0;
|
|
682
|
-
if (
|
|
683
|
-
const error2 = `Tool ${toolName} has reached its limit of ${
|
|
704
|
+
if (maxCalls2 && currentCount >= maxCalls2) {
|
|
705
|
+
const error2 = `Tool ${toolName} has reached its limit of ${maxCalls2} calls`;
|
|
684
706
|
if (ctx.stream) {
|
|
685
707
|
ctx.stream({ type: "tool_error", call, error: error2 });
|
|
686
708
|
}
|
|
@@ -789,14 +811,15 @@ var createThread = (id, store) => {
|
|
|
789
811
|
}
|
|
790
812
|
};
|
|
791
813
|
};
|
|
792
|
-
var defaultStore = createMemoryStore();
|
|
793
814
|
var threads = /* @__PURE__ */ new Map();
|
|
794
|
-
var getOrCreateThread = (id, store
|
|
795
|
-
|
|
796
|
-
|
|
815
|
+
var getOrCreateThread = (id, store) => {
|
|
816
|
+
const cacheKey = store ? `${id}-${store}` : id;
|
|
817
|
+
if (threads.has(cacheKey)) {
|
|
818
|
+
return threads.get(cacheKey);
|
|
797
819
|
}
|
|
798
|
-
const
|
|
799
|
-
|
|
820
|
+
const threadStore = store || createMemoryStore();
|
|
821
|
+
const thread = createThread(id, threadStore);
|
|
822
|
+
threads.set(cacheKey, thread);
|
|
800
823
|
return thread;
|
|
801
824
|
};
|
|
802
825
|
|
|
@@ -1027,6 +1050,9 @@ var scopeContext = (config, ctx) => {
|
|
|
1027
1050
|
scopedCtx.history = [{ role: "system", content: config.system }, ...scopedCtx.history];
|
|
1028
1051
|
}
|
|
1029
1052
|
}
|
|
1053
|
+
if (config.stream) {
|
|
1054
|
+
scopedCtx.stream = config.stream;
|
|
1055
|
+
}
|
|
1030
1056
|
return scopedCtx;
|
|
1031
1057
|
};
|
|
1032
1058
|
var scope = (config, ...steps) => {
|
|
@@ -1058,19 +1084,24 @@ export {
|
|
|
1058
1084
|
everyNMessages,
|
|
1059
1085
|
everyNTokens,
|
|
1060
1086
|
generateApprovalToken,
|
|
1087
|
+
getKey,
|
|
1061
1088
|
getOrCreateThread,
|
|
1062
1089
|
isStandardSchema,
|
|
1090
|
+
maxCalls,
|
|
1063
1091
|
model,
|
|
1064
1092
|
noToolsCalled,
|
|
1065
1093
|
normalizeSchema,
|
|
1066
1094
|
onApprovalRequested,
|
|
1067
1095
|
onApprovalResolved,
|
|
1096
|
+
parseModelName,
|
|
1068
1097
|
removeApprovalListener,
|
|
1069
1098
|
requestApproval,
|
|
1070
1099
|
resolveApproval,
|
|
1071
1100
|
retry,
|
|
1072
1101
|
scope,
|
|
1102
|
+
setKeys,
|
|
1073
1103
|
tap,
|
|
1104
|
+
toolConfigToToolDefinition,
|
|
1074
1105
|
toolNotUsedInNTurns,
|
|
1075
1106
|
toolWasCalled,
|
|
1076
1107
|
when
|