@node-llm/core 1.5.0 → 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/aliases.d.ts +563 -71
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +569 -77
- 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/models/models.d.ts +113 -1427
- package/dist/models/models.d.ts.map +1 -1
- package/dist/models/models.js +5700 -24218
- package/dist/models/types.js +0 -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/Chat.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Message } from "./Message.js";
|
|
2
|
+
import { ContentPart } from "./Content.js";
|
|
2
3
|
import { ChatOptions } from "./ChatOptions.js";
|
|
3
4
|
import { Provider, Usage, ChatChunk } from "../providers/Provider.js";
|
|
4
5
|
import { Stream } from "../streaming/Stream.js";
|
|
5
|
-
import {
|
|
6
|
+
import { ToolResolvable } from "./Tool.js";
|
|
6
7
|
import { Schema } from "../schema/Schema.js";
|
|
7
8
|
import { z } from "zod";
|
|
8
9
|
import { ToolExecutionMode } from "../constants.js";
|
|
@@ -40,7 +41,7 @@ export declare class Chat {
|
|
|
40
41
|
* Add a tool to the chat session (fluent API)
|
|
41
42
|
* Supports passing a tool instance or a tool class (which will be instantiated).
|
|
42
43
|
*/
|
|
43
|
-
withTool(tool:
|
|
44
|
+
withTool(tool: ToolResolvable): this;
|
|
44
45
|
/**
|
|
45
46
|
* Add multiple tools to the chat session.
|
|
46
47
|
* Supports passing Tool classes (which will be instantiated) or instances.
|
|
@@ -49,9 +50,7 @@ export declare class Chat {
|
|
|
49
50
|
* @example
|
|
50
51
|
* chat.withTools([WeatherTool, new CalculatorTool()], { replace: true });
|
|
51
52
|
*/
|
|
52
|
-
withTools(tools:
|
|
53
|
-
new (): Tool;
|
|
54
|
-
} | any)[], options?: {
|
|
53
|
+
withTools(tools: ToolResolvable[], options?: {
|
|
55
54
|
replace?: boolean;
|
|
56
55
|
}): this;
|
|
57
56
|
/**
|
|
@@ -107,10 +106,7 @@ export declare class Chat {
|
|
|
107
106
|
* Called when a tool call ends successfully.
|
|
108
107
|
*/
|
|
109
108
|
onToolCallEnd(handler: (toolCall: any, result: any) => void): this;
|
|
110
|
-
|
|
111
|
-
* Called when a tool call fails.
|
|
112
|
-
*/
|
|
113
|
-
onToolCallError(handler: (toolCall: any, error: Error) => void): this;
|
|
109
|
+
onToolCallError(handler: (toolCall: any, error: Error) => 'STOP' | 'CONTINUE' | void | Promise<'STOP' | 'CONTINUE' | void>): this;
|
|
114
110
|
/**
|
|
115
111
|
* Set the tool execution mode.
|
|
116
112
|
* - "auto": (Default) Automatically execute all tool calls.
|
|
@@ -140,19 +136,10 @@ export declare class Chat {
|
|
|
140
136
|
/**
|
|
141
137
|
* Streams the model's response to a user question.
|
|
142
138
|
*/
|
|
143
|
-
stream(content: string): Stream<ChatChunk>;
|
|
144
|
-
/**
|
|
145
|
-
* Check if tool execution should proceed based on the current mode.
|
|
146
|
-
*/
|
|
147
|
-
private shouldExecuteTools;
|
|
148
|
-
/**
|
|
149
|
-
* Request user confirmation for a tool call in "confirm" mode.
|
|
150
|
-
* Returns true if approved, false if rejected.
|
|
151
|
-
*/
|
|
152
|
-
private requestToolConfirmation;
|
|
139
|
+
stream(content: string | ContentPart[], options?: AskOptions): Stream<ChatChunk>;
|
|
153
140
|
/**
|
|
154
|
-
*
|
|
141
|
+
* Normalizes a ToolResolvable into a ToolDefinition.
|
|
155
142
|
*/
|
|
156
|
-
private
|
|
143
|
+
private normalizeTool;
|
|
157
144
|
}
|
|
158
145
|
//# sourceMappingURL=Chat.d.ts.map
|
package/dist/chat/Chat.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGtE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../src/chat/Chat.ts"],"names":[],"mappings":"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"}
|
package/dist/chat/Chat.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FileLoader } from "../utils/FileLoader.js";
|
|
2
|
+
import { isBinaryContent, formatMultimodalContent } from "./Content.js";
|
|
2
3
|
import { Executor } from "../executor/Executor.js";
|
|
3
4
|
import { ChatStream } from "./ChatStream.js";
|
|
4
5
|
import { Schema } from "../schema/Schema.js";
|
|
@@ -6,6 +7,9 @@ import { toJsonSchema } from "../schema/to-json-schema.js";
|
|
|
6
7
|
import { z } from "zod";
|
|
7
8
|
import { config } from "../config.js";
|
|
8
9
|
import { ToolExecutionMode } from "../constants.js";
|
|
10
|
+
import { ConfigurationError } from "../errors/index.js";
|
|
11
|
+
import { ChatValidator } from "./Validation.js";
|
|
12
|
+
import { ToolHandler } from "./ToolHandler.js";
|
|
9
13
|
import { ChatResponseString } from "./ChatResponse.js";
|
|
10
14
|
export class Chat {
|
|
11
15
|
provider;
|
|
@@ -35,6 +39,11 @@ export class Chat {
|
|
|
35
39
|
if (!this.options.toolExecution) {
|
|
36
40
|
this.options.toolExecution = config.toolExecution || ToolExecutionMode.AUTO;
|
|
37
41
|
}
|
|
42
|
+
if (options.tools) {
|
|
43
|
+
const toolList = options.tools;
|
|
44
|
+
this.options.tools = []; // Clear and re-add via normalized method
|
|
45
|
+
this.withTools(toolList);
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
48
|
/**
|
|
40
49
|
* Read-only access to message history
|
|
@@ -84,27 +93,9 @@ export class Chat {
|
|
|
84
93
|
this.options.tools = [];
|
|
85
94
|
}
|
|
86
95
|
for (const tool of tools) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
toolInstance = new tool();
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
console.error(`[NodeLLM] Failed to instantiate tool class: ${tool.name}`, e);
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
toolInstance = tool;
|
|
100
|
-
}
|
|
101
|
-
// Normalized to standard ToolDefinition interface if it's a Tool class instance
|
|
102
|
-
if (toolInstance && typeof toolInstance.toLLMTool === "function") {
|
|
103
|
-
this.options.tools.push(toolInstance.toLLMTool());
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
// Fallback for legacy raw tool objects (defined as objects with type: 'function')
|
|
107
|
-
this.options.tools.push(toolInstance);
|
|
96
|
+
const normalized = this.normalizeTool(tool);
|
|
97
|
+
if (normalized) {
|
|
98
|
+
this.options.tools.push(normalized);
|
|
108
99
|
}
|
|
109
100
|
}
|
|
110
101
|
return this;
|
|
@@ -213,9 +204,6 @@ export class Chat {
|
|
|
213
204
|
this.options.onToolCallEnd = handler;
|
|
214
205
|
return this;
|
|
215
206
|
}
|
|
216
|
-
/**
|
|
217
|
-
* Called when a tool call fails.
|
|
218
|
-
*/
|
|
219
207
|
onToolCallError(handler) {
|
|
220
208
|
this.options.onToolCallError = handler;
|
|
221
209
|
return this;
|
|
@@ -261,41 +249,13 @@ export class Chat {
|
|
|
261
249
|
let messageContent = content;
|
|
262
250
|
const files = [...(options?.images ?? []), ...(options?.files ?? [])];
|
|
263
251
|
if (files.length > 0) {
|
|
264
|
-
const processedFiles = await Promise.all(files.map(f => FileLoader.load(f)));
|
|
265
|
-
const hasBinary = processedFiles.some(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
if (hasBinary && this.options.assumeModelExists) {
|
|
270
|
-
console.warn(`[NodeLLM] Skipping vision capability validation for model ${this.model}`);
|
|
271
|
-
}
|
|
272
|
-
// Separate text files from binary files
|
|
273
|
-
const textFiles = processedFiles.filter(p => p.type === "text");
|
|
274
|
-
const binaryFiles = processedFiles.filter(p => p.type !== "text");
|
|
275
|
-
// Concatenate text files into the main content
|
|
276
|
-
let fullText = content;
|
|
277
|
-
if (textFiles.length > 0) {
|
|
278
|
-
fullText += "\n" + textFiles.map(f => f.text).join("\n");
|
|
279
|
-
}
|
|
280
|
-
// If we have binary files, create multimodal content
|
|
281
|
-
if (binaryFiles.length > 0) {
|
|
282
|
-
messageContent = [
|
|
283
|
-
{ type: "text", text: fullText },
|
|
284
|
-
...binaryFiles
|
|
285
|
-
];
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
// Only text files, keep as string
|
|
289
|
-
messageContent = fullText;
|
|
290
|
-
}
|
|
252
|
+
const processedFiles = await Promise.all(files.map((f) => FileLoader.load(f)));
|
|
253
|
+
const hasBinary = processedFiles.some(isBinaryContent);
|
|
254
|
+
ChatValidator.validateVision(this.provider, this.model, hasBinary, this.options);
|
|
255
|
+
messageContent = formatMultimodalContent(content, processedFiles);
|
|
291
256
|
}
|
|
292
257
|
if (this.options.tools && this.options.tools.length > 0) {
|
|
293
|
-
|
|
294
|
-
throw new Error(`Model ${this.model} does not support tool calling.`);
|
|
295
|
-
}
|
|
296
|
-
if (this.options.assumeModelExists) {
|
|
297
|
-
console.warn(`[NodeLLM] Skipping tool capability validation for model ${this.model}`);
|
|
298
|
-
}
|
|
258
|
+
ChatValidator.validateTools(this.provider, this.model, true, this.options);
|
|
299
259
|
}
|
|
300
260
|
this.messages.push({
|
|
301
261
|
role: "user",
|
|
@@ -304,12 +264,7 @@ export class Chat {
|
|
|
304
264
|
// Process Schema/Structured Output
|
|
305
265
|
let responseFormat = this.options.responseFormat;
|
|
306
266
|
if (this.options.schema) {
|
|
307
|
-
|
|
308
|
-
throw new Error(`Model ${this.model} does not support structured output.`);
|
|
309
|
-
}
|
|
310
|
-
if (this.options.assumeModelExists) {
|
|
311
|
-
console.warn(`[NodeLLM] Skipping structured output capability validation for model ${this.model}`);
|
|
312
|
-
}
|
|
267
|
+
ChatValidator.validateStructuredOutput(this.provider, this.model, true, this.options);
|
|
313
268
|
const jsonSchema = toJsonSchema(this.options.schema.definition.schema);
|
|
314
269
|
responseFormat = {
|
|
315
270
|
type: "json_schema",
|
|
@@ -381,7 +336,7 @@ export class Chat {
|
|
|
381
336
|
let stepCount = 0;
|
|
382
337
|
while (response.tool_calls && response.tool_calls.length > 0) {
|
|
383
338
|
// Dry-run mode: stop after proposing tools
|
|
384
|
-
if (!
|
|
339
|
+
if (!ToolHandler.shouldExecuteTools(response.tool_calls, this.options.toolExecution)) {
|
|
385
340
|
break;
|
|
386
341
|
}
|
|
387
342
|
stepCount++;
|
|
@@ -389,9 +344,9 @@ export class Chat {
|
|
|
389
344
|
throw new Error(`[NodeLLM] Maximum tool execution calls (${maxToolCalls}) exceeded.`);
|
|
390
345
|
}
|
|
391
346
|
for (const toolCall of response.tool_calls) {
|
|
392
|
-
//
|
|
347
|
+
// Human-in-the-loop: check for approval
|
|
393
348
|
if (this.options.toolExecution === ToolExecutionMode.CONFIRM) {
|
|
394
|
-
const approved = await
|
|
349
|
+
const approved = await ToolHandler.requestToolConfirmation(toolCall, this.options.onConfirmToolCall);
|
|
395
350
|
if (!approved) {
|
|
396
351
|
this.messages.push({
|
|
397
352
|
role: "tool",
|
|
@@ -401,9 +356,30 @@ export class Chat {
|
|
|
401
356
|
continue;
|
|
402
357
|
}
|
|
403
358
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
359
|
+
try {
|
|
360
|
+
const toolResult = await ToolHandler.execute(toolCall, this.options.tools, this.options.onToolCallStart, this.options.onToolCallEnd);
|
|
361
|
+
this.messages.push(toolResult);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
const directive = await this.options.onToolCallError?.(toolCall, error);
|
|
365
|
+
if (directive === 'STOP') {
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
this.messages.push({
|
|
369
|
+
role: "tool",
|
|
370
|
+
tool_call_id: toolCall.id,
|
|
371
|
+
content: `Fatal error executing tool '${toolCall.function.name}': ${error.message}`,
|
|
372
|
+
});
|
|
373
|
+
if (directive === 'CONTINUE') {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
// Default short-circuit logic
|
|
377
|
+
const isFatal = error.fatal === true || error.status === 401 || error.status === 403;
|
|
378
|
+
if (isFatal) {
|
|
379
|
+
throw error;
|
|
380
|
+
}
|
|
381
|
+
console.error(`[NodeLLM] Tool execution failed for '${toolCall.function.name}':`, error);
|
|
382
|
+
}
|
|
407
383
|
}
|
|
408
384
|
response = await this.executor.executeChat({
|
|
409
385
|
model: this.model,
|
|
@@ -438,68 +414,46 @@ export class Chat {
|
|
|
438
414
|
/**
|
|
439
415
|
* Streams the model's response to a user question.
|
|
440
416
|
*/
|
|
441
|
-
stream(content) {
|
|
417
|
+
stream(content, options = {}) {
|
|
442
418
|
const streamer = new ChatStream(this.provider, this.model, this.options, this.messages, this.systemMessages);
|
|
443
|
-
return streamer.create(content);
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Check if tool execution should proceed based on the current mode.
|
|
447
|
-
*/
|
|
448
|
-
shouldExecuteTools(toolCalls, mode) {
|
|
449
|
-
if (!toolCalls || toolCalls.length === 0)
|
|
450
|
-
return false;
|
|
451
|
-
if (mode === ToolExecutionMode.DRY_RUN)
|
|
452
|
-
return false;
|
|
453
|
-
return true;
|
|
419
|
+
return streamer.create(content, options);
|
|
454
420
|
}
|
|
455
421
|
/**
|
|
456
|
-
*
|
|
457
|
-
* Returns true if approved, false if rejected.
|
|
422
|
+
* Normalizes a ToolResolvable into a ToolDefinition.
|
|
458
423
|
*/
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
return confirmed !== false;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Execute a single tool call and return the result message.
|
|
467
|
-
*/
|
|
468
|
-
async executeToolCall(toolCall, tools, onStart, onEnd, onError) {
|
|
469
|
-
if (onStart)
|
|
470
|
-
onStart(toolCall);
|
|
471
|
-
const tool = tools?.find((t) => t.function.name === toolCall.function.name);
|
|
472
|
-
if (tool?.handler) {
|
|
424
|
+
normalizeTool(tool) {
|
|
425
|
+
let toolInstance;
|
|
426
|
+
// Handle class constructor
|
|
427
|
+
if (typeof tool === "function") {
|
|
473
428
|
try {
|
|
474
|
-
|
|
475
|
-
const result = await tool.handler(args);
|
|
476
|
-
if (onEnd)
|
|
477
|
-
onEnd(toolCall, result);
|
|
478
|
-
return {
|
|
479
|
-
role: "tool",
|
|
480
|
-
tool_call_id: toolCall.id,
|
|
481
|
-
content: result,
|
|
482
|
-
};
|
|
429
|
+
toolInstance = new tool();
|
|
483
430
|
}
|
|
484
|
-
catch (
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
return {
|
|
488
|
-
role: "tool",
|
|
489
|
-
tool_call_id: toolCall.id,
|
|
490
|
-
content: `Error executing tool: ${error.message}`,
|
|
491
|
-
};
|
|
431
|
+
catch (e) {
|
|
432
|
+
console.error(`[NodeLLM] Failed to instantiate tool class: ${tool.name}`, e);
|
|
433
|
+
return null;
|
|
492
434
|
}
|
|
493
435
|
}
|
|
494
436
|
else {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
return
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
437
|
+
toolInstance = tool;
|
|
438
|
+
}
|
|
439
|
+
if (!toolInstance)
|
|
440
|
+
return null;
|
|
441
|
+
// Normalized to standard ToolDefinition interface if it's a Tool class instance
|
|
442
|
+
if (typeof toolInstance.toLLMTool === "function") {
|
|
443
|
+
return toolInstance.toLLMTool();
|
|
444
|
+
}
|
|
445
|
+
if (!toolInstance.function || !toolInstance.function.name) {
|
|
446
|
+
// 1. Validate structure
|
|
447
|
+
throw new ConfigurationError(`[NodeLLM] Tool validation failed: 'function.name' is required for raw tool objects.`);
|
|
448
|
+
}
|
|
449
|
+
if (toolInstance.type !== 'function') {
|
|
450
|
+
// 2. Ensure 'type: function' exists (standardize for providers)
|
|
451
|
+
toolInstance.type = 'function';
|
|
452
|
+
}
|
|
453
|
+
if (typeof toolInstance.handler !== 'function') {
|
|
454
|
+
// 3. Validate handler existence
|
|
455
|
+
throw new ConfigurationError(`[NodeLLM] Tool validation failed: Tool '${toolInstance.function.name}' must have a 'handler' function. (Note: Only Tool subclasses use 'execute()')`);
|
|
503
456
|
}
|
|
457
|
+
return toolInstance;
|
|
504
458
|
}
|
|
505
459
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Message } from "./Message.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ToolResolvable } from "./Tool.js";
|
|
3
3
|
import { Schema } from "../schema/Schema.js";
|
|
4
4
|
import { ChatResponseString } from "./ChatResponse.js";
|
|
5
5
|
import { ToolExecutionMode } from "../constants.js";
|
|
6
6
|
export interface ChatOptions {
|
|
7
7
|
systemPrompt?: string;
|
|
8
8
|
messages?: Message[];
|
|
9
|
-
tools?:
|
|
9
|
+
tools?: ToolResolvable[];
|
|
10
10
|
temperature?: number;
|
|
11
11
|
maxTokens?: number;
|
|
12
12
|
onNewMessage?: () => void;
|
|
13
13
|
onEndMessage?: (message: any) => void;
|
|
14
14
|
onToolCallStart?: (toolCall: any) => void;
|
|
15
15
|
onToolCallEnd?: (toolCall: any, result: any) => void;
|
|
16
|
-
onToolCallError?: (toolCall: any, error: Error) => void
|
|
16
|
+
onToolCallError?: (toolCall: any, error: Error) => 'STOP' | 'CONTINUE' | void | Promise<'STOP' | 'CONTINUE' | void>;
|
|
17
17
|
headers?: Record<string, string>;
|
|
18
18
|
schema?: Schema;
|
|
19
19
|
responseFormat?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC;IACpH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE;QAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAAA;KAAE,CAAC;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAClE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACxF"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Message } from "./Message.js";
|
|
2
|
+
import { ContentPart } from "./Content.js";
|
|
2
3
|
import { ChatOptions } from "./ChatOptions.js";
|
|
3
4
|
import { Provider, ChatChunk } from "../providers/Provider.js";
|
|
4
5
|
import { Stream } from "../streaming/Stream.js";
|
|
6
|
+
import { AskOptions } from "./Chat.js";
|
|
5
7
|
/**
|
|
6
8
|
* Internal handler for chat streaming logic.
|
|
7
9
|
* Wraps the provider's stream with side effects like history updates and events.
|
|
@@ -13,27 +15,7 @@ export declare class ChatStream {
|
|
|
13
15
|
private messages;
|
|
14
16
|
private systemMessages;
|
|
15
17
|
constructor(provider: Provider, model: string, options?: ChatOptions, messages?: Message[], systemMessages?: Message[]);
|
|
16
|
-
/**
|
|
17
|
-
* Read-only access to message history
|
|
18
|
-
*/
|
|
19
18
|
get history(): readonly Message[];
|
|
20
|
-
|
|
21
|
-
* Creates a high-level Stream object for the chat response.
|
|
22
|
-
* @param content The user's question.
|
|
23
|
-
*/
|
|
24
|
-
create(content: string): Stream<ChatChunk>;
|
|
25
|
-
/**
|
|
26
|
-
* Check if tool execution should proceed based on the current mode.
|
|
27
|
-
*/
|
|
28
|
-
private shouldExecuteTools;
|
|
29
|
-
/**
|
|
30
|
-
* Request user confirmation for a tool call in "confirm" mode.
|
|
31
|
-
* Returns true if approved, false if rejected.
|
|
32
|
-
*/
|
|
33
|
-
private requestToolConfirmation;
|
|
34
|
-
/**
|
|
35
|
-
* Execute a single tool call and return the result message.
|
|
36
|
-
*/
|
|
37
|
-
private executeToolCall;
|
|
19
|
+
create(content: string | ContentPart[], options?: AskOptions): Stream<ChatChunk>;
|
|
38
20
|
}
|
|
39
21
|
//# sourceMappingURL=ChatStream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatStream.d.ts","sourceRoot":"","sources":["../../src/chat/ChatStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"ChatStream.d.ts","sourceRoot":"","sources":["../../src/chat/ChatStream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAA4C,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAS,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAOvC;;;GAGG;AACH,qBAAa,UAAU;IAKnB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN1B,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,cAAc,CAAY;gBAGf,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,WAAgB,EAC1C,QAAQ,CAAC,EAAE,OAAO,EAAE,EACpB,cAAc,CAAC,EAAE,OAAO,EAAE;IA6B5B,IAAI,OAAO,IAAI,SAAS,OAAO,EAAE,CAEhC;IAED,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CAAC,SAAS,CAAC;CAsOrF"}
|