@node-llm/core 1.5.1 → 1.5.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/chat/Chat.d.ts +8 -21
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +76 -122
- package/dist/chat/ChatOptions.d.ts +3 -3
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatStream.d.ts +3 -21
- package/dist/chat/ChatStream.d.ts.map +1 -1
- package/dist/chat/ChatStream.js +95 -97
- package/dist/chat/Content.d.ts +10 -0
- package/dist/chat/Content.d.ts.map +1 -1
- package/dist/chat/Content.js +34 -1
- package/dist/chat/Tool.d.ts +6 -0
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/ToolHandler.d.ts +11 -0
- package/dist/chat/ToolHandler.d.ts.map +1 -0
- package/dist/chat/ToolHandler.js +41 -0
- package/dist/chat/Validation.d.ts +10 -0
- package/dist/chat/Validation.d.ts.map +1 -0
- package/dist/chat/Validation.js +32 -0
- package/dist/config.d.ts +43 -14
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +58 -13
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +13 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +13 -3
- package/dist/providers/openai/Capabilities.d.ts +1 -0
- package/dist/providers/openai/Capabilities.d.ts.map +1 -1
- package/dist/providers/openai/Capabilities.js +3 -0
- package/dist/providers/openai/Chat.d.ts.map +1 -1
- package/dist/providers/openai/Chat.js +11 -3
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +6 -1
- package/dist/providers/openai/types.d.ts +4 -0
- package/dist/providers/openai/types.d.ts.map +1 -1
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +2 -0
- package/dist/utils/logger.js +1 -1
- package/package.json +1 -1
package/dist/chat/ChatStream.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { isBinaryContent, formatMultimodalContent } from "./Content.js";
|
|
1
2
|
import { ChatResponseString } from "./ChatResponse.js";
|
|
2
3
|
import { Stream } from "../streaming/Stream.js";
|
|
3
4
|
import { config } from "../config.js";
|
|
4
5
|
import { ToolExecutionMode } from "../constants.js";
|
|
6
|
+
import { FileLoader } from "../utils/FileLoader.js";
|
|
7
|
+
import { toJsonSchema } from "../schema/to-json-schema.js";
|
|
8
|
+
import { ChatValidator } from "./Validation.js";
|
|
9
|
+
import { ToolHandler } from "./ToolHandler.js";
|
|
5
10
|
/**
|
|
6
11
|
* Internal handler for chat streaming logic.
|
|
7
12
|
* Wraps the provider's stream with side effects like history updates and events.
|
|
@@ -18,7 +23,6 @@ export class ChatStream {
|
|
|
18
23
|
this.options = options;
|
|
19
24
|
this.messages = messages ?? [];
|
|
20
25
|
this.systemMessages = systemMessages ?? [];
|
|
21
|
-
// Only initialize if we're starting a new history
|
|
22
26
|
if (this.messages.length === 0 && this.systemMessages.length === 0) {
|
|
23
27
|
if (options.systemPrompt) {
|
|
24
28
|
this.systemMessages.push({
|
|
@@ -41,39 +45,74 @@ export class ChatStream {
|
|
|
41
45
|
this.options.toolExecution = config.toolExecution || ToolExecutionMode.AUTO;
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Read-only access to message history
|
|
46
|
-
*/
|
|
47
48
|
get history() {
|
|
48
49
|
return [...this.systemMessages, ...this.messages];
|
|
49
50
|
}
|
|
50
|
-
|
|
51
|
-
* Creates a high-level Stream object for the chat response.
|
|
52
|
-
* @param content The user's question.
|
|
53
|
-
*/
|
|
54
|
-
create(content) {
|
|
51
|
+
create(content, options = {}) {
|
|
55
52
|
const controller = new AbortController();
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
const sideEffectGenerator = async function* (self, provider, model, messages, systemMessages, baseOptions, abortController, content, requestOptions) {
|
|
54
|
+
const options = {
|
|
55
|
+
...baseOptions,
|
|
56
|
+
...requestOptions,
|
|
57
|
+
headers: { ...baseOptions.headers, ...requestOptions.headers }
|
|
58
|
+
};
|
|
59
|
+
// Process Multimodal Content
|
|
60
|
+
let messageContent = content;
|
|
61
|
+
const files = [...(requestOptions.images ?? []), ...(requestOptions.files ?? [])];
|
|
62
|
+
if (files.length > 0) {
|
|
63
|
+
const processedFiles = await Promise.all(files.map((f) => FileLoader.load(f)));
|
|
64
|
+
const hasBinary = processedFiles.some(isBinaryContent);
|
|
65
|
+
ChatValidator.validateVision(provider, model, hasBinary, options);
|
|
66
|
+
messageContent = formatMultimodalContent(content, processedFiles);
|
|
67
|
+
}
|
|
68
|
+
if (options.tools && options.tools.length > 0) {
|
|
69
|
+
ChatValidator.validateTools(provider, model, true, options);
|
|
70
|
+
}
|
|
71
|
+
messages.push({ role: "user", content: messageContent });
|
|
72
|
+
if (!provider.stream) {
|
|
73
|
+
throw new Error("Streaming not supported by provider");
|
|
74
|
+
}
|
|
75
|
+
// Process Schema/Structured Output
|
|
76
|
+
let responseFormat = options.responseFormat;
|
|
77
|
+
if (!responseFormat && options.schema) {
|
|
78
|
+
ChatValidator.validateStructuredOutput(provider, model, true, options);
|
|
79
|
+
const jsonSchema = toJsonSchema(options.schema.definition.schema);
|
|
80
|
+
responseFormat = {
|
|
81
|
+
type: "json_schema",
|
|
82
|
+
json_schema: {
|
|
83
|
+
name: options.schema.definition.name,
|
|
84
|
+
description: options.schema.definition.description,
|
|
85
|
+
strict: options.schema.definition.strict ?? true,
|
|
86
|
+
schema: jsonSchema,
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
59
90
|
if (!provider.stream) {
|
|
60
91
|
throw new Error("Streaming not supported by provider");
|
|
61
92
|
}
|
|
62
|
-
let fullContent = "";
|
|
63
|
-
let fullReasoning = "";
|
|
64
|
-
let toolCalls;
|
|
65
93
|
let isFirst = true;
|
|
66
94
|
const maxToolCalls = options.maxToolCalls ?? 5;
|
|
67
95
|
let stepCount = 0;
|
|
68
|
-
|
|
96
|
+
let totalUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
|
|
97
|
+
const trackUsage = (u) => {
|
|
98
|
+
if (u) {
|
|
99
|
+
totalUsage.input_tokens += u.input_tokens;
|
|
100
|
+
totalUsage.output_tokens += u.output_tokens;
|
|
101
|
+
totalUsage.total_tokens += u.total_tokens;
|
|
102
|
+
if (u.cached_tokens) {
|
|
103
|
+
totalUsage.cached_tokens = (totalUsage.cached_tokens ?? 0) + u.cached_tokens;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
69
107
|
while (true) {
|
|
70
108
|
stepCount++;
|
|
71
109
|
if (stepCount > maxToolCalls) {
|
|
72
110
|
throw new Error(`[NodeLLM] Maximum tool execution calls (${maxToolCalls}) exceeded during streaming.`);
|
|
73
111
|
}
|
|
74
|
-
fullContent = "";
|
|
75
|
-
fullReasoning = "";
|
|
76
|
-
toolCalls
|
|
112
|
+
let fullContent = "";
|
|
113
|
+
let fullReasoning = "";
|
|
114
|
+
let toolCalls;
|
|
115
|
+
let currentTurnUsage;
|
|
77
116
|
try {
|
|
78
117
|
let requestMessages = [...systemMessages, ...messages];
|
|
79
118
|
if (options.onBeforeRequest) {
|
|
@@ -88,8 +127,11 @@ export class ChatStream {
|
|
|
88
127
|
tools: options.tools,
|
|
89
128
|
temperature: options.temperature,
|
|
90
129
|
max_tokens: options.maxTokens ?? config.maxTokens,
|
|
130
|
+
response_format: responseFormat,
|
|
131
|
+
headers: options.headers,
|
|
91
132
|
requestTimeout: options.requestTimeout ?? config.requestTimeout,
|
|
92
133
|
signal: abortController.signal,
|
|
134
|
+
...options.params,
|
|
93
135
|
})) {
|
|
94
136
|
if (isFirst) {
|
|
95
137
|
if (options.onNewMessage)
|
|
@@ -104,43 +146,40 @@ export class ChatStream {
|
|
|
104
146
|
fullReasoning += chunk.reasoning;
|
|
105
147
|
yield { content: "", reasoning: chunk.reasoning };
|
|
106
148
|
}
|
|
107
|
-
// Accumulate tool calls from the final chunk
|
|
108
149
|
if (chunk.tool_calls) {
|
|
109
150
|
toolCalls = chunk.tool_calls;
|
|
110
151
|
}
|
|
152
|
+
if (chunk.usage) {
|
|
153
|
+
currentTurnUsage = chunk.usage;
|
|
154
|
+
trackUsage(currentTurnUsage);
|
|
155
|
+
}
|
|
111
156
|
}
|
|
112
|
-
|
|
113
|
-
let assistantResponse = new ChatResponseString(fullContent || "", { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, model, provider.id, fullReasoning || undefined);
|
|
114
|
-
// --- Content Policy Hooks (Output) ---
|
|
157
|
+
let assistantResponse = new ChatResponseString(fullContent || "", currentTurnUsage || { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, model, provider.id, fullReasoning || undefined);
|
|
115
158
|
if (options.onAfterResponse) {
|
|
116
159
|
const result = await options.onAfterResponse(assistantResponse);
|
|
117
160
|
if (result) {
|
|
118
161
|
assistantResponse = result;
|
|
119
162
|
}
|
|
120
163
|
}
|
|
121
|
-
// Add assistant message to history (now potentially redacted)
|
|
122
164
|
messages.push({
|
|
123
165
|
role: "assistant",
|
|
124
166
|
content: assistantResponse || null,
|
|
125
167
|
tool_calls: toolCalls,
|
|
126
|
-
reasoning: fullReasoning || undefined
|
|
168
|
+
reasoning: fullReasoning || undefined,
|
|
169
|
+
usage: currentTurnUsage
|
|
127
170
|
});
|
|
128
|
-
// If no tool calls, we're done
|
|
129
171
|
if (!toolCalls || toolCalls.length === 0) {
|
|
130
172
|
if (options.onEndMessage) {
|
|
131
173
|
options.onEndMessage(assistantResponse);
|
|
132
174
|
}
|
|
133
175
|
break;
|
|
134
176
|
}
|
|
135
|
-
|
|
136
|
-
if (!self.shouldExecuteTools(toolCalls, options.toolExecution)) {
|
|
177
|
+
if (!ToolHandler.shouldExecuteTools(toolCalls, options.toolExecution)) {
|
|
137
178
|
break;
|
|
138
179
|
}
|
|
139
|
-
// Execute tool calls
|
|
140
180
|
for (const toolCall of toolCalls) {
|
|
141
|
-
// Confirm mode: request approval
|
|
142
181
|
if (options.toolExecution === ToolExecutionMode.CONFIRM) {
|
|
143
|
-
const approved = await
|
|
182
|
+
const approved = await ToolHandler.requestToolConfirmation(toolCall, options.onConfirmToolCall);
|
|
144
183
|
if (!approved) {
|
|
145
184
|
messages.push({
|
|
146
185
|
role: "tool",
|
|
@@ -150,80 +189,39 @@ export class ChatStream {
|
|
|
150
189
|
continue;
|
|
151
190
|
}
|
|
152
191
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
192
|
+
try {
|
|
193
|
+
const toolResult = await ToolHandler.execute(toolCall, options.tools, options.onToolCallStart, options.onToolCallEnd);
|
|
194
|
+
messages.push(toolResult);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
const directive = await options.onToolCallError?.(toolCall, error);
|
|
198
|
+
if (directive === 'STOP') {
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
messages.push({
|
|
202
|
+
role: "tool",
|
|
203
|
+
tool_call_id: toolCall.id,
|
|
204
|
+
content: `Fatal error executing tool '${toolCall.function.name}': ${error.message}`,
|
|
205
|
+
});
|
|
206
|
+
if (directive === 'CONTINUE') {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const isFatal = error.fatal === true || error.status === 401 || error.status === 403;
|
|
210
|
+
if (isFatal) {
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
console.error(`[NodeLLM] Tool execution failed for '${toolCall.function.name}':`, error);
|
|
214
|
+
}
|
|
156
215
|
}
|
|
157
|
-
// Continue loop to stream the next response after tool execution
|
|
158
216
|
}
|
|
159
217
|
catch (error) {
|
|
160
218
|
if (error instanceof Error && error.name === 'AbortError') {
|
|
161
|
-
//
|
|
219
|
+
// Aborted
|
|
162
220
|
}
|
|
163
221
|
throw error;
|
|
164
222
|
}
|
|
165
223
|
}
|
|
166
224
|
};
|
|
167
|
-
return new Stream(() => sideEffectGenerator(this, this.provider, this.model, this.messages, this.systemMessages, this.options, controller), controller);
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Check if tool execution should proceed based on the current mode.
|
|
171
|
-
*/
|
|
172
|
-
shouldExecuteTools(toolCalls, mode) {
|
|
173
|
-
if (!toolCalls || toolCalls.length === 0)
|
|
174
|
-
return false;
|
|
175
|
-
if (mode === ToolExecutionMode.DRY_RUN)
|
|
176
|
-
return false;
|
|
177
|
-
return true;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Request user confirmation for a tool call in "confirm" mode.
|
|
181
|
-
* Returns true if approved, false if rejected.
|
|
182
|
-
*/
|
|
183
|
-
async requestToolConfirmation(toolCall, onConfirm) {
|
|
184
|
-
if (!onConfirm)
|
|
185
|
-
return true;
|
|
186
|
-
const confirmed = await onConfirm(toolCall);
|
|
187
|
-
return confirmed !== false;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Execute a single tool call and return the result message.
|
|
191
|
-
*/
|
|
192
|
-
async executeToolCall(toolCall, tools, onStart, onEnd, onError) {
|
|
193
|
-
if (onStart)
|
|
194
|
-
onStart(toolCall);
|
|
195
|
-
const tool = tools?.find((t) => t.function.name === toolCall.function.name);
|
|
196
|
-
if (tool?.handler) {
|
|
197
|
-
try {
|
|
198
|
-
const args = JSON.parse(toolCall.function.arguments);
|
|
199
|
-
const result = await tool.handler(args);
|
|
200
|
-
if (onEnd)
|
|
201
|
-
onEnd(toolCall, result);
|
|
202
|
-
return {
|
|
203
|
-
role: "tool",
|
|
204
|
-
tool_call_id: toolCall.id,
|
|
205
|
-
content: result,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
if (onError)
|
|
210
|
-
onError(toolCall, error);
|
|
211
|
-
return {
|
|
212
|
-
role: "tool",
|
|
213
|
-
tool_call_id: toolCall.id,
|
|
214
|
-
content: `Error executing tool: ${error.message}`,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
const error = new Error("Tool not found or no handler provided");
|
|
220
|
-
if (onError)
|
|
221
|
-
onError(toolCall, error);
|
|
222
|
-
return {
|
|
223
|
-
role: "tool",
|
|
224
|
-
tool_call_id: toolCall.id,
|
|
225
|
-
content: "Error: Tool not found or no handler provided",
|
|
226
|
-
};
|
|
227
|
-
}
|
|
225
|
+
return new Stream(() => sideEffectGenerator(this, this.provider, this.model, this.messages, this.systemMessages, this.options, controller, content, options), controller);
|
|
228
226
|
}
|
|
229
227
|
}
|
package/dist/chat/Content.d.ts
CHANGED
|
@@ -18,5 +18,15 @@ export type ContentPart = {
|
|
|
18
18
|
url: string;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
+
export declare const isBinaryContent: (part: ContentPart) => boolean;
|
|
22
|
+
export declare const isTextContent: (part: ContentPart) => boolean;
|
|
23
|
+
export declare const partitionContentParts: (parts: ContentPart[]) => {
|
|
24
|
+
textParts: ({
|
|
25
|
+
type: "text";
|
|
26
|
+
text: string;
|
|
27
|
+
})[];
|
|
28
|
+
binaryParts: ContentPart[];
|
|
29
|
+
};
|
|
30
|
+
export declare const formatMultimodalContent: (content: string | ContentPart[], parts: ContentPart[]) => MessageContent;
|
|
21
31
|
export type MessageContent = string | String | ContentPart[];
|
|
22
32
|
//# sourceMappingURL=Content.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../../src/chat/Content.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"Content.d.ts","sourceRoot":"","sources":["../../src/chat/Content.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAEtD,eAAO,MAAM,eAAe,GAAI,MAAM,WAAW,KAAG,OACmC,CAAC;AAExF,eAAO,MAAM,aAAa,GAAI,MAAM,WAAW,KAAG,OAC5B,CAAC;AAEvB,eAAO,MAAM,qBAAqB,GAAI,OAAO,WAAW,EAAE;eAEZ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE;;CAG/E,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,SAAS,MAAM,GAAG,WAAW,EAAE,EAAE,OAAO,WAAW,EAAE,KAAG,cA2B/F,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,EAAE,CAAC"}
|
package/dist/chat/Content.js
CHANGED
|
@@ -1 +1,34 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const isBinaryContent = (part) => part.type === "image_url" || part.type === "input_audio" || part.type === "video_url";
|
|
2
|
+
export const isTextContent = (part) => part.type === "text";
|
|
3
|
+
export const partitionContentParts = (parts) => {
|
|
4
|
+
return {
|
|
5
|
+
textParts: parts.filter(isTextContent),
|
|
6
|
+
binaryParts: parts.filter(isBinaryContent)
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export const formatMultimodalContent = (content, parts) => {
|
|
10
|
+
const { textParts, binaryParts } = partitionContentParts(parts);
|
|
11
|
+
let fullText = typeof content === "string" ? content : "";
|
|
12
|
+
let currentParts = typeof content === "string" ? [] : content;
|
|
13
|
+
if (textParts.length > 0) {
|
|
14
|
+
const additionalText = textParts.map(f => f.text).join("\n");
|
|
15
|
+
if (typeof content === "string") {
|
|
16
|
+
fullText += "\n" + additionalText;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
currentParts.push({ type: "text", text: additionalText });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (binaryParts.length > 0) {
|
|
23
|
+
if (typeof content === "string") {
|
|
24
|
+
return [
|
|
25
|
+
{ type: "text", text: fullText },
|
|
26
|
+
...binaryParts
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return [...currentParts, ...binaryParts];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return typeof content === "string" ? fullText : currentParts;
|
|
34
|
+
};
|
package/dist/chat/Tool.d.ts
CHANGED
|
@@ -16,6 +16,12 @@ export interface ToolDefinition {
|
|
|
16
16
|
};
|
|
17
17
|
handler?: (args: any) => Promise<string>;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Anything that can be resolved into a ToolDefinition.
|
|
21
|
+
*/
|
|
22
|
+
export type ToolResolvable = Tool | {
|
|
23
|
+
new (): Tool;
|
|
24
|
+
} | ToolDefinition | any;
|
|
19
25
|
/**
|
|
20
26
|
* Subclass this to create tools with auto-generated schemas and type safety.
|
|
21
27
|
*/
|
package/dist/chat/Tool.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../../src/chat/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,8BAAsB,IAAI,CAAC,CAAC,GAAG,GAAG;IAChC;;OAEG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,SAAgB,WAAW,EAAE,MAAM,CAAC;IAEpC;;;OAGG;IACH,SAAgB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE/D;;;OAGG;aACa,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAE9C;;;OAGG;IACU,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAM9C;;;OAGG;IACI,SAAS,IAAI,cAAc;CAoBnC"}
|
|
1
|
+
{"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../../src/chat/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG;IAAE,QAAO,IAAI,CAAA;CAAE,GAAG,cAAc,GAAG,GAAG,CAAC;AAE3E;;GAEG;AACH,8BAAsB,IAAI,CAAC,CAAC,GAAG,GAAG;IAChC;;OAEG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,SAAgB,WAAW,EAAE,MAAM,CAAC;IAEpC;;;OAGG;IACH,SAAgB,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE/D;;;OAGG;aACa,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAE9C;;;OAGG;IACU,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAM9C;;;OAGG;IACI,SAAS,IAAI,cAAc;CAoBnC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ToolExecutionMode } from "../constants.js";
|
|
2
|
+
export declare class ToolHandler {
|
|
3
|
+
static shouldExecuteTools(toolCalls: any[] | undefined, mode?: ToolExecutionMode): boolean;
|
|
4
|
+
static requestToolConfirmation(toolCall: any, onConfirm?: (call: any) => Promise<boolean> | boolean): Promise<boolean>;
|
|
5
|
+
static execute(toolCall: any, tools: any[] | undefined, onStart?: (call: any) => void, onEnd?: (call: any, result: any) => void): Promise<{
|
|
6
|
+
role: "tool";
|
|
7
|
+
tool_call_id: string;
|
|
8
|
+
content: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ToolHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolHandler.d.ts","sourceRoot":"","sources":["../../src/chat/ToolHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,qBAAa,WAAW;IACtB,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO;WAM7E,uBAAuB,CAClC,QAAQ,EAAE,GAAG,EACb,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GACpD,OAAO,CAAC,OAAO,CAAC;WAMN,OAAO,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,EAAE,GAAG,EAAE,GAAG,SAAS,EACxB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,EAC7B,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,GACvC,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAwBpE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ToolExecutionMode } from "../constants.js";
|
|
2
|
+
import { ToolError } from "../errors/index.js";
|
|
3
|
+
export class ToolHandler {
|
|
4
|
+
static shouldExecuteTools(toolCalls, mode) {
|
|
5
|
+
if (!toolCalls || toolCalls.length === 0)
|
|
6
|
+
return false;
|
|
7
|
+
if (mode === ToolExecutionMode.DRY_RUN)
|
|
8
|
+
return false;
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
static async requestToolConfirmation(toolCall, onConfirm) {
|
|
12
|
+
if (!onConfirm)
|
|
13
|
+
return true;
|
|
14
|
+
const confirmed = await onConfirm(toolCall);
|
|
15
|
+
return confirmed !== false;
|
|
16
|
+
}
|
|
17
|
+
static async execute(toolCall, tools, onStart, onEnd) {
|
|
18
|
+
if (onStart)
|
|
19
|
+
onStart(toolCall);
|
|
20
|
+
const tool = tools?.find((t) => t.function.name === toolCall.function.name);
|
|
21
|
+
if (tool?.handler) {
|
|
22
|
+
try {
|
|
23
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
24
|
+
const result = await tool.handler(args);
|
|
25
|
+
if (onEnd)
|
|
26
|
+
onEnd(toolCall, result);
|
|
27
|
+
return {
|
|
28
|
+
role: "tool",
|
|
29
|
+
tool_call_id: toolCall.id,
|
|
30
|
+
content: result,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw new ToolError("Tool not found or no handler provided", toolCall.function?.name ?? "unknown");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Provider } from "../providers/Provider.js";
|
|
2
|
+
export interface ValidationOptions {
|
|
3
|
+
assumeModelExists?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare class ChatValidator {
|
|
6
|
+
static validateVision(provider: Provider, model: string, hasBinary: boolean, options: ValidationOptions): void;
|
|
7
|
+
static validateTools(provider: Provider, model: string, hasTools: boolean, options: ValidationOptions): void;
|
|
8
|
+
static validateStructuredOutput(provider: Provider, model: string, hasSchema: boolean, options: ValidationOptions): void;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=Validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validation.d.ts","sourceRoot":"","sources":["../../src/chat/Validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,qBAAa,aAAa;IACxB,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB;IAYvG,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB;IAYrG,MAAM,CAAC,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB;CAWlH"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export class ChatValidator {
|
|
2
|
+
static validateVision(provider, model, hasBinary, options) {
|
|
3
|
+
if (!hasBinary)
|
|
4
|
+
return;
|
|
5
|
+
if (!options.assumeModelExists && provider.capabilities && !provider.capabilities.supportsVision(model)) {
|
|
6
|
+
throw new Error(`Model ${model} does not support vision/binary files.`);
|
|
7
|
+
}
|
|
8
|
+
if (options.assumeModelExists) {
|
|
9
|
+
console.warn(`[NodeLLM] Skipping vision capability validation for model ${model}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
static validateTools(provider, model, hasTools, options) {
|
|
13
|
+
if (!hasTools)
|
|
14
|
+
return;
|
|
15
|
+
if (!options.assumeModelExists && provider.capabilities && !provider.capabilities.supportsTools(model)) {
|
|
16
|
+
throw new Error(`Model ${model} does not support tool calling.`);
|
|
17
|
+
}
|
|
18
|
+
if (options.assumeModelExists) {
|
|
19
|
+
console.warn(`[NodeLLM] Skipping tool capability validation for model ${model}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
static validateStructuredOutput(provider, model, hasSchema, options) {
|
|
23
|
+
if (!hasSchema)
|
|
24
|
+
return;
|
|
25
|
+
if (!options.assumeModelExists && provider.capabilities && !provider.capabilities.supportsStructuredOutput(model)) {
|
|
26
|
+
throw new Error(`Model ${model} does not support structured output.`);
|
|
27
|
+
}
|
|
28
|
+
if (options.assumeModelExists) {
|
|
29
|
+
console.warn(`[NodeLLM] Skipping structured output capability validation for model ${model}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/dist/config.d.ts
CHANGED
|
@@ -22,25 +22,54 @@ export interface NodeLLMConfig {
|
|
|
22
22
|
toolExecution?: ToolExecutionMode;
|
|
23
23
|
}
|
|
24
24
|
import { ToolExecutionMode } from "./constants.js";
|
|
25
|
-
declare class Configuration implements NodeLLMConfig {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
export declare class Configuration implements NodeLLMConfig {
|
|
26
|
+
private _openaiApiKey?;
|
|
27
|
+
private _openaiApiBase?;
|
|
28
|
+
private _anthropicApiKey?;
|
|
29
|
+
private _anthropicApiBase?;
|
|
30
|
+
private _geminiApiKey?;
|
|
31
|
+
private _geminiApiBase?;
|
|
32
|
+
private _deepseekApiKey?;
|
|
33
|
+
private _deepseekApiBase?;
|
|
34
|
+
private _ollamaApiBase?;
|
|
35
|
+
private _openrouterApiKey?;
|
|
36
|
+
private _openrouterApiBase?;
|
|
37
|
+
private _debug?;
|
|
38
|
+
get openaiApiKey(): string | undefined;
|
|
39
|
+
set openaiApiKey(v: string | undefined);
|
|
40
|
+
get openaiApiBase(): string | undefined;
|
|
41
|
+
set openaiApiBase(v: string | undefined);
|
|
42
|
+
get anthropicApiKey(): string | undefined;
|
|
43
|
+
set anthropicApiKey(v: string | undefined);
|
|
44
|
+
get anthropicApiBase(): string | undefined;
|
|
45
|
+
set anthropicApiBase(v: string | undefined);
|
|
46
|
+
get geminiApiKey(): string | undefined;
|
|
47
|
+
set geminiApiKey(v: string | undefined);
|
|
48
|
+
get geminiApiBase(): string | undefined;
|
|
49
|
+
set geminiApiBase(v: string | undefined);
|
|
50
|
+
get deepseekApiKey(): string | undefined;
|
|
51
|
+
set deepseekApiKey(v: string | undefined);
|
|
52
|
+
get deepseekApiBase(): string | undefined;
|
|
53
|
+
set deepseekApiBase(v: string | undefined);
|
|
54
|
+
get ollamaApiBase(): string | undefined;
|
|
55
|
+
set ollamaApiBase(v: string | undefined);
|
|
56
|
+
get openrouterApiKey(): string | undefined;
|
|
57
|
+
set openrouterApiKey(v: string | undefined);
|
|
58
|
+
get openrouterApiBase(): string | undefined;
|
|
59
|
+
set openrouterApiBase(v: string | undefined);
|
|
60
|
+
get debug(): boolean | undefined;
|
|
61
|
+
set debug(v: boolean | undefined);
|
|
38
62
|
maxToolCalls: number;
|
|
39
63
|
maxRetries: number;
|
|
40
64
|
requestTimeout: number;
|
|
41
65
|
maxTokens: number;
|
|
42
66
|
toolExecution: ToolExecutionMode;
|
|
67
|
+
/**
|
|
68
|
+
* Returns a plain object with all configuration values.
|
|
69
|
+
* This is useful for cloning or serialization.
|
|
70
|
+
* It handles getters (lazy-loaded values) correctly.
|
|
71
|
+
*/
|
|
72
|
+
toPlainObject(): NodeLLMConfig;
|
|
43
73
|
}
|
|
44
74
|
export declare const config: Configuration;
|
|
45
|
-
export {};
|
|
46
75
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,OAAO,EAOL,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AAExB,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -1,21 +1,66 @@
|
|
|
1
1
|
import { DEFAULT_MAX_TOOL_CALLS, DEFAULT_MAX_RETRIES, DEFAULT_REQUEST_TIMEOUT, DEFAULT_MAX_TOKENS, DEFAULT_TOOL_EXECUTION, DEFAULT_OLLAMA_BASE_URL } from "./constants.js";
|
|
2
|
-
class Configuration {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
export class Configuration {
|
|
3
|
+
_openaiApiKey;
|
|
4
|
+
_openaiApiBase;
|
|
5
|
+
_anthropicApiKey;
|
|
6
|
+
_anthropicApiBase;
|
|
7
|
+
_geminiApiKey;
|
|
8
|
+
_geminiApiBase;
|
|
9
|
+
_deepseekApiKey;
|
|
10
|
+
_deepseekApiBase;
|
|
11
|
+
_ollamaApiBase;
|
|
12
|
+
_openrouterApiKey;
|
|
13
|
+
_openrouterApiBase;
|
|
14
|
+
_debug;
|
|
15
|
+
get openaiApiKey() { return this._openaiApiKey ?? process.env.OPENAI_API_KEY?.trim(); }
|
|
16
|
+
set openaiApiKey(v) { this._openaiApiKey = v; }
|
|
17
|
+
get openaiApiBase() { return this._openaiApiBase ?? process.env.OPENAI_API_BASE?.trim(); }
|
|
18
|
+
set openaiApiBase(v) { this._openaiApiBase = v; }
|
|
19
|
+
get anthropicApiKey() { return this._anthropicApiKey ?? process.env.ANTHROPIC_API_KEY?.trim(); }
|
|
20
|
+
set anthropicApiKey(v) { this._anthropicApiKey = v; }
|
|
21
|
+
get anthropicApiBase() { return this._anthropicApiBase ?? process.env.ANTHROPIC_API_BASE?.trim(); }
|
|
22
|
+
set anthropicApiBase(v) { this._anthropicApiBase = v; }
|
|
23
|
+
get geminiApiKey() { return this._geminiApiKey ?? process.env.GEMINI_API_KEY?.trim(); }
|
|
24
|
+
set geminiApiKey(v) { this._geminiApiKey = v; }
|
|
25
|
+
get geminiApiBase() { return this._geminiApiBase ?? process.env.GEMINI_API_BASE?.trim(); }
|
|
26
|
+
set geminiApiBase(v) { this._geminiApiBase = v; }
|
|
27
|
+
get deepseekApiKey() { return this._deepseekApiKey ?? process.env.DEEPSEEK_API_KEY?.trim(); }
|
|
28
|
+
set deepseekApiKey(v) { this._deepseekApiKey = v; }
|
|
29
|
+
get deepseekApiBase() { return this._deepseekApiBase ?? process.env.DEEPSEEK_API_BASE?.trim(); }
|
|
30
|
+
set deepseekApiBase(v) { this._deepseekApiBase = v; }
|
|
31
|
+
get ollamaApiBase() { return this._ollamaApiBase ?? process.env.OLLAMA_API_BASE?.trim() ?? DEFAULT_OLLAMA_BASE_URL; }
|
|
32
|
+
set ollamaApiBase(v) { this._ollamaApiBase = v; }
|
|
33
|
+
get openrouterApiKey() { return this._openrouterApiKey ?? process.env.OPENROUTER_API_KEY?.trim(); }
|
|
34
|
+
set openrouterApiKey(v) { this._openrouterApiKey = v; }
|
|
35
|
+
get openrouterApiBase() { return this._openrouterApiBase ?? process.env.OPENROUTER_API_BASE?.trim(); }
|
|
36
|
+
set openrouterApiBase(v) { this._openrouterApiBase = v; }
|
|
37
|
+
get debug() { return this._debug ?? process.env.NODELLM_DEBUG === "true"; }
|
|
38
|
+
set debug(v) { this._debug = v; }
|
|
15
39
|
maxToolCalls = DEFAULT_MAX_TOOL_CALLS;
|
|
16
40
|
maxRetries = DEFAULT_MAX_RETRIES;
|
|
17
41
|
requestTimeout = DEFAULT_REQUEST_TIMEOUT;
|
|
18
42
|
maxTokens = DEFAULT_MAX_TOKENS;
|
|
19
43
|
toolExecution = DEFAULT_TOOL_EXECUTION;
|
|
44
|
+
/**
|
|
45
|
+
* Returns a plain object with all configuration values.
|
|
46
|
+
* This is useful for cloning or serialization.
|
|
47
|
+
* It handles getters (lazy-loaded values) correctly.
|
|
48
|
+
*/
|
|
49
|
+
toPlainObject() {
|
|
50
|
+
const plain = { ...this }; // Capture all enumerable "own" properties (custom keys, overrides)
|
|
51
|
+
// Capture all getters from the class prototype (lazy-loaded values)
|
|
52
|
+
const prototype = Object.getPrototypeOf(this);
|
|
53
|
+
const propertyNames = Object.getOwnPropertyNames(prototype);
|
|
54
|
+
for (const name of propertyNames) {
|
|
55
|
+
if (name === "constructor")
|
|
56
|
+
continue;
|
|
57
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
|
|
58
|
+
if (descriptor && descriptor.get) {
|
|
59
|
+
// Trigger the getter to snapshot the live value (including env fallbacks)
|
|
60
|
+
plain[name] = this[name];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return plain;
|
|
64
|
+
}
|
|
20
65
|
}
|
|
21
66
|
export const config = new Configuration();
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -85,4 +85,12 @@ export declare class ModelCapabilityError extends LLMError {
|
|
|
85
85
|
readonly capability: string;
|
|
86
86
|
constructor(model: string, capability: string);
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Thrown when a tool execution fails
|
|
90
|
+
*/
|
|
91
|
+
export declare class ToolError extends LLMError {
|
|
92
|
+
readonly toolName?: string | undefined;
|
|
93
|
+
readonly fatal: boolean;
|
|
94
|
+
constructor(message: string, toolName?: string | undefined, fatal?: boolean);
|
|
95
|
+
}
|
|
88
96
|
//# sourceMappingURL=index.d.ts.map
|