@node-llm/core 1.14.1 → 1.15.0
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/agent/Agent.d.ts +13 -9
- package/dist/agent/Agent.d.ts.map +1 -1
- package/dist/agent/Agent.js +4 -1
- package/dist/aliases.d.ts +123 -215
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +177 -269
- package/dist/chat/Chat.d.ts +6 -0
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +189 -163
- package/dist/chat/ChatOptions.d.ts +4 -2
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/ChatStream.d.ts.map +1 -1
- package/dist/chat/ChatStream.js +7 -2
- package/dist/chat/Tool.d.ts +6 -0
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/Tool.js +13 -1
- package/dist/executor/Executor.d.ts.map +1 -1
- package/dist/executor/Executor.js +3 -0
- package/dist/middlewares/CostGuardMiddleware.d.ts +6 -2
- package/dist/middlewares/CostGuardMiddleware.d.ts.map +1 -1
- package/dist/middlewares/CostGuardMiddleware.js +6 -0
- package/dist/middlewares/SchemaSelfCorrection.d.ts +26 -0
- package/dist/middlewares/SchemaSelfCorrection.d.ts.map +1 -0
- package/dist/middlewares/SchemaSelfCorrection.js +70 -0
- package/dist/middlewares/UsageLoggerMiddleware.d.ts +6 -2
- package/dist/middlewares/UsageLoggerMiddleware.d.ts.map +1 -1
- package/dist/middlewares/UsageLoggerMiddleware.js +6 -0
- package/dist/middlewares/index.d.ts +1 -0
- package/dist/middlewares/index.d.ts.map +1 -1
- package/dist/middlewares/index.js +1 -0
- package/dist/models/models.json +1057 -2007
- package/dist/providers/Provider.d.ts +3 -0
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/ollama/OllamaProvider.d.ts.map +1 -1
- package/dist/providers/ollama/OllamaProvider.js +1 -0
- 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 +38 -5
- package/dist/providers/openai/OpenAIProvider.d.ts +2 -1
- package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/openai/OpenAIProvider.js +2 -1
- package/dist/providers/openai/Streaming.d.ts.map +1 -1
- package/dist/providers/openai/Streaming.js +33 -2
- package/dist/providers/openrouter/OpenRouterProvider.d.ts +1 -0
- package/dist/providers/openrouter/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/openrouter/OpenRouterProvider.js +1 -0
- package/dist/schema/strict.d.ts +2 -0
- package/dist/schema/strict.d.ts.map +1 -0
- package/dist/schema/strict.js +39 -0
- package/dist/types/Middleware.d.ts +16 -2
- package/dist/types/Middleware.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/chat/Chat.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface AskOptions {
|
|
|
16
16
|
maxToolCalls?: number;
|
|
17
17
|
requestTimeout?: number;
|
|
18
18
|
thinking?: ThinkingConfig;
|
|
19
|
+
prediction?: string | ContentPart[];
|
|
19
20
|
signal?: AbortSignal;
|
|
20
21
|
inputs?: Record<string, any>;
|
|
21
22
|
}
|
|
@@ -113,6 +114,11 @@ export declare class Chat<S = unknown> {
|
|
|
113
114
|
* Can accept a Schema object or a Zod schema/JSON Schema directly.
|
|
114
115
|
*/
|
|
115
116
|
withSchema<T>(schema: Schema | z.ZodType<T> | Record<string, unknown> | null): Chat<T>;
|
|
117
|
+
/**
|
|
118
|
+
* Provide a prediction of the expected output to reduce latency.
|
|
119
|
+
* Particularly useful for code-editing agents modifying existing text.
|
|
120
|
+
*/
|
|
121
|
+
withPrediction(prediction: string | ContentPart[] | null): this;
|
|
116
122
|
/**
|
|
117
123
|
* Enable and configure extended thinking for reasoning models.
|
|
118
124
|
*/
|
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,EACL,WAAW,EAGX,cAAc,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EAET,cAAc,EACf,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,OAAO,EAAkB,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
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
|
@@ -222,6 +222,19 @@ export class Chat {
|
|
|
222
222
|
}
|
|
223
223
|
return this;
|
|
224
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Provide a prediction of the expected output to reduce latency.
|
|
227
|
+
* Particularly useful for code-editing agents modifying existing text.
|
|
228
|
+
*/
|
|
229
|
+
withPrediction(prediction) {
|
|
230
|
+
if (prediction === null) {
|
|
231
|
+
delete this.options.prediction;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
this.options.prediction = prediction;
|
|
235
|
+
}
|
|
236
|
+
return this;
|
|
237
|
+
}
|
|
225
238
|
/**
|
|
226
239
|
* Enable and configure extended thinking for reasoning models.
|
|
227
240
|
*/
|
|
@@ -350,179 +363,74 @@ export class Chat {
|
|
|
350
363
|
try {
|
|
351
364
|
// 1. onRequest Hook
|
|
352
365
|
await runMiddleware(this.middlewares, "onRequest", context);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
model: this.model,
|
|
357
|
-
messages: messagesToUse,
|
|
358
|
-
tools: this.options.tools,
|
|
359
|
-
temperature: options?.temperature ?? this.options.temperature,
|
|
360
|
-
max_tokens: options?.maxTokens ?? this.options.maxTokens ?? config.maxTokens,
|
|
361
|
-
headers: { ...this.options.headers, ...options?.headers },
|
|
362
|
-
response_format: responseFormat, // Pass to provider
|
|
363
|
-
requestTimeout: options?.requestTimeout ?? this.options.requestTimeout ?? config.requestTimeout,
|
|
364
|
-
thinking: options?.thinking ?? this.options.thinking,
|
|
365
|
-
signal: options?.signal,
|
|
366
|
-
...this.options.params
|
|
367
|
-
};
|
|
368
|
-
// --- Content Policy Hooks (Input) ---
|
|
369
|
-
if (this.options.onBeforeRequest) {
|
|
370
|
-
const result = await this.options.onBeforeRequest(executeOptions.messages);
|
|
371
|
-
if (result) {
|
|
372
|
-
executeOptions.messages = result;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
366
|
+
let assistantMessage;
|
|
367
|
+
let finalResponse;
|
|
368
|
+
let correctionAttempt = 0;
|
|
375
369
|
const totalUsage = { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
u.cost = withCost.cost;
|
|
382
|
-
u.input_cost = withCost.input_cost;
|
|
383
|
-
u.output_cost = withCost.output_cost;
|
|
384
|
-
}
|
|
385
|
-
totalUsage.input_tokens += u.input_tokens;
|
|
386
|
-
totalUsage.output_tokens += u.output_tokens;
|
|
387
|
-
totalUsage.total_tokens += u.total_tokens;
|
|
388
|
-
if (u.cached_tokens) {
|
|
389
|
-
totalUsage.cached_tokens = (totalUsage.cached_tokens ?? 0) + u.cached_tokens;
|
|
390
|
-
}
|
|
391
|
-
if (u.cost !== undefined) {
|
|
392
|
-
totalUsage.cost = (totalUsage.cost ?? 0) + u.cost;
|
|
393
|
-
}
|
|
394
|
-
if (u.input_cost !== undefined) {
|
|
395
|
-
totalUsage.input_cost = (totalUsage.input_cost ?? 0) + u.input_cost;
|
|
396
|
-
}
|
|
397
|
-
if (u.output_cost !== undefined) {
|
|
398
|
-
totalUsage.output_cost = (totalUsage.output_cost ?? 0) + u.output_cost;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
// First round
|
|
403
|
-
if (this.options.onNewMessage)
|
|
404
|
-
this.options.onNewMessage();
|
|
405
|
-
let response = await this.executor.executeChat(executeOptions);
|
|
406
|
-
trackUsage(response.usage);
|
|
407
|
-
let assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model, this.provider.id, response.thinking, response.reasoning, response.tool_calls, response.finish_reason, this.options.schema);
|
|
408
|
-
// --- Content Policy Hooks (Output - Turn 1) ---
|
|
409
|
-
if (this.options.onAfterResponse) {
|
|
410
|
-
const result = await this.options.onAfterResponse(assistantMessage);
|
|
411
|
-
if (result) {
|
|
412
|
-
assistantMessage = result;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
this.messages.push({
|
|
416
|
-
role: "assistant",
|
|
417
|
-
content: assistantMessage?.toString() || null,
|
|
418
|
-
tool_calls: response.tool_calls,
|
|
419
|
-
usage: response.usage
|
|
420
|
-
});
|
|
421
|
-
if (this.options.onEndMessage && (!response.tool_calls || response.tool_calls.length === 0)) {
|
|
422
|
-
this.options.onEndMessage(assistantMessage);
|
|
423
|
-
}
|
|
424
|
-
const maxToolCalls = options?.maxToolCalls ?? this.options.maxToolCalls ?? 5;
|
|
425
|
-
let stepCount = 0;
|
|
426
|
-
let haltTriggered = false;
|
|
427
|
-
while (response.tool_calls && response.tool_calls.length > 0 && !haltTriggered) {
|
|
428
|
-
// Dry-run mode: stop after proposing tools
|
|
429
|
-
if (!ToolHandler.shouldExecuteTools(response.tool_calls, this.options.toolExecution)) {
|
|
430
|
-
break;
|
|
431
|
-
}
|
|
432
|
-
stepCount++;
|
|
433
|
-
if (stepCount > maxToolCalls) {
|
|
434
|
-
throw new Error(`[NodeLLM] Maximum tool execution calls (${maxToolCalls}) exceeded.`);
|
|
435
|
-
}
|
|
436
|
-
for (const toolCall of response.tool_calls) {
|
|
437
|
-
// Human-in-the-loop: check for approval
|
|
438
|
-
if (this.options.toolExecution === ToolExecutionMode.CONFIRM) {
|
|
439
|
-
const approved = await ToolHandler.requestToolConfirmation(toolCall, this.options.onConfirmToolCall);
|
|
440
|
-
if (!approved) {
|
|
441
|
-
this.messages.push(this.provider.formatToolResultMessage(toolCall.id, "Action cancelled by user."));
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
// 2. onToolCallStart Hook
|
|
446
|
-
await runMiddleware(this.middlewares, "onToolCallStart", context, toolCall);
|
|
447
|
-
try {
|
|
448
|
-
const toolResult = await ToolHandler.execute(toolCall, this.options.tools, this.options.onToolCallStart, this.options.onToolCallEnd);
|
|
449
|
-
// 3. onToolCallEnd Hook
|
|
450
|
-
await runMiddleware(this.middlewares, "onToolCallEnd", context, toolCall, toolResult.content);
|
|
451
|
-
this.messages.push(this.provider.formatToolResultMessage(toolResult.tool_call_id, toolResult.content));
|
|
452
|
-
// Check if tool signaled a halt - stop the agentic loop
|
|
453
|
-
if (toolResult.halted) {
|
|
454
|
-
haltTriggered = true;
|
|
455
|
-
// Create final response from halt content
|
|
456
|
-
assistantMessage = new ChatResponseString(toolResult.content, totalUsage, this.model, this.provider.id, undefined, undefined, undefined, "tool_halt");
|
|
457
|
-
if (this.options.onEndMessage) {
|
|
458
|
-
this.options.onEndMessage(assistantMessage);
|
|
459
|
-
}
|
|
460
|
-
break; // Exit the for loop
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
catch (error) {
|
|
464
|
-
let currentError = error;
|
|
465
|
-
// 4. onToolCallError Hook
|
|
466
|
-
const middlewareDirective = await runMiddleware(this.middlewares, "onToolCallError", context, toolCall, currentError);
|
|
467
|
-
const directive = middlewareDirective ||
|
|
468
|
-
(await this.options.onToolCallError?.(toolCall, currentError));
|
|
469
|
-
if (directive === "STOP") {
|
|
470
|
-
throw currentError;
|
|
471
|
-
}
|
|
472
|
-
if (directive === "RETRY") {
|
|
473
|
-
// ... retry logic (simplified: recurse or duplicate logic? adhering to original logic)
|
|
474
|
-
// Original logic duplicated the execution block. For brevity in this replacement, I'll simplified retry to "try once more"
|
|
475
|
-
try {
|
|
476
|
-
// Retry Hook? Maybe skip start hook on retry or re-run?
|
|
477
|
-
// Let's assume onToolCallStart fires again for cleanliness?
|
|
478
|
-
// Or just execute directly to match existing behavior.
|
|
479
|
-
// Existing logs show we just call ToolHandler.execute again.
|
|
480
|
-
const toolResult = await ToolHandler.execute(toolCall, this.options.tools, this.options.onToolCallStart, this.options.onToolCallEnd);
|
|
481
|
-
await runMiddleware(this.middlewares, "onToolCallEnd", context, toolCall, toolResult.content);
|
|
482
|
-
this.messages.push(this.provider.formatToolResultMessage(toolResult.tool_call_id, toolResult.content));
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
catch (retryError) {
|
|
486
|
-
currentError = retryError;
|
|
487
|
-
await runMiddleware(this.middlewares, "onToolCallError", context, toolCall, currentError);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
this.messages.push(this.provider.formatToolResultMessage(toolCall.id, `Fatal error executing tool '${toolCall.function.name}': ${currentError.message}`, { isError: true }));
|
|
491
|
-
if (directive === "CONTINUE") {
|
|
492
|
-
continue;
|
|
493
|
-
}
|
|
494
|
-
// Default short-circuit logic
|
|
495
|
-
const errorObj = currentError;
|
|
496
|
-
const isFatal = errorObj.fatal === true || errorObj.status === 401 || errorObj.status === 403;
|
|
497
|
-
if (isFatal) {
|
|
498
|
-
throw currentError;
|
|
499
|
-
}
|
|
500
|
-
logger.error(`Tool execution failed for '${toolCall.function.name}':`, currentError);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
// If halt was triggered, exit the while loop immediately
|
|
504
|
-
if (haltTriggered) {
|
|
505
|
-
break;
|
|
506
|
-
}
|
|
507
|
-
response = await this.executor.executeChat({
|
|
370
|
+
// Self-Correction Loop
|
|
371
|
+
while (true) {
|
|
372
|
+
// Prepare execution options
|
|
373
|
+
const messagesToUse = context.messages || [];
|
|
374
|
+
const executeOptions = {
|
|
508
375
|
model: this.model,
|
|
509
|
-
messages:
|
|
376
|
+
messages: messagesToUse,
|
|
510
377
|
tools: this.options.tools,
|
|
511
378
|
temperature: options?.temperature ?? this.options.temperature,
|
|
512
379
|
max_tokens: options?.maxTokens ?? this.options.maxTokens ?? config.maxTokens,
|
|
513
|
-
headers: this.options.headers,
|
|
380
|
+
headers: { ...this.options.headers, ...options?.headers },
|
|
514
381
|
response_format: responseFormat, // Pass to provider
|
|
515
382
|
requestTimeout: options?.requestTimeout ?? this.options.requestTimeout ?? config.requestTimeout,
|
|
383
|
+
thinking: options?.thinking ?? this.options.thinking,
|
|
384
|
+
prediction: options?.prediction ?? this.options.prediction,
|
|
516
385
|
signal: options?.signal,
|
|
517
386
|
...this.options.params
|
|
518
|
-
}
|
|
387
|
+
};
|
|
388
|
+
// --- Content Policy Hooks (Input) ---
|
|
389
|
+
if (this.options.onBeforeRequest) {
|
|
390
|
+
const result = await this.options.onBeforeRequest(executeOptions.messages);
|
|
391
|
+
if (result) {
|
|
392
|
+
executeOptions.messages = result;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const trackUsage = (u) => {
|
|
396
|
+
if (u) {
|
|
397
|
+
if (u.cost === undefined) {
|
|
398
|
+
const withCost = ModelRegistry.calculateCost(u, this.model, this.provider.id);
|
|
399
|
+
u.cost = withCost.cost;
|
|
400
|
+
u.input_cost = withCost.input_cost;
|
|
401
|
+
u.output_cost = withCost.output_cost;
|
|
402
|
+
}
|
|
403
|
+
totalUsage.input_tokens += u.input_tokens;
|
|
404
|
+
totalUsage.output_tokens += u.output_tokens;
|
|
405
|
+
totalUsage.total_tokens += u.total_tokens;
|
|
406
|
+
if (u.cached_tokens) {
|
|
407
|
+
totalUsage.cached_tokens = (totalUsage.cached_tokens ?? 0) + u.cached_tokens;
|
|
408
|
+
}
|
|
409
|
+
if (u.cost !== undefined) {
|
|
410
|
+
totalUsage.cost = (totalUsage.cost ?? 0) + u.cost;
|
|
411
|
+
}
|
|
412
|
+
if (u.input_cost !== undefined) {
|
|
413
|
+
totalUsage.input_cost = (totalUsage.input_cost ?? 0) + u.input_cost;
|
|
414
|
+
}
|
|
415
|
+
if (u.output_cost !== undefined) {
|
|
416
|
+
totalUsage.output_cost = (totalUsage.output_cost ?? 0) + u.output_cost;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
// Start generation
|
|
421
|
+
if (this.options.onNewMessage)
|
|
422
|
+
this.options.onNewMessage();
|
|
423
|
+
let response = await this.executor.executeChat(executeOptions);
|
|
519
424
|
trackUsage(response.usage);
|
|
520
425
|
assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model, this.provider.id, response.thinking, response.reasoning, response.tool_calls, response.finish_reason, this.options.schema);
|
|
426
|
+
// --- Content Policy Hooks (Output - Turn 1) ---
|
|
521
427
|
if (this.options.onAfterResponse) {
|
|
522
428
|
const result = await this.options.onAfterResponse(assistantMessage);
|
|
523
|
-
if (result)
|
|
429
|
+
if (result) {
|
|
524
430
|
assistantMessage = result;
|
|
431
|
+
}
|
|
525
432
|
}
|
|
433
|
+
// Add to history (temporary, might be rolled back on retry)
|
|
526
434
|
this.messages.push({
|
|
527
435
|
role: "assistant",
|
|
528
436
|
content: assistantMessage?.toString() || null,
|
|
@@ -533,15 +441,133 @@ export class Chat {
|
|
|
533
441
|
(!response.tool_calls || response.tool_calls.length === 0)) {
|
|
534
442
|
this.options.onEndMessage(assistantMessage);
|
|
535
443
|
}
|
|
444
|
+
const maxToolCalls = options?.maxToolCalls ?? this.options.maxToolCalls ?? 5;
|
|
445
|
+
let stepCount = 0;
|
|
446
|
+
let haltTriggered = false;
|
|
447
|
+
// Tool Calling Loop
|
|
448
|
+
while (response.tool_calls && response.tool_calls.length > 0 && !haltTriggered) {
|
|
449
|
+
if (!ToolHandler.shouldExecuteTools(response.tool_calls, this.options.toolExecution)) {
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
stepCount++;
|
|
453
|
+
if (stepCount > maxToolCalls) {
|
|
454
|
+
throw new Error(`[NodeLLM] Maximum tool execution calls (${maxToolCalls}) exceeded.`);
|
|
455
|
+
}
|
|
456
|
+
for (const toolCall of response.tool_calls) {
|
|
457
|
+
if (this.options.toolExecution === ToolExecutionMode.CONFIRM) {
|
|
458
|
+
const approved = await ToolHandler.requestToolConfirmation(toolCall, this.options.onConfirmToolCall);
|
|
459
|
+
if (!approved) {
|
|
460
|
+
this.messages.push(this.provider.formatToolResultMessage(toolCall.id, "Action cancelled by user."));
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
await runMiddleware(this.middlewares, "onToolCallStart", context, toolCall);
|
|
465
|
+
try {
|
|
466
|
+
const toolResult = await ToolHandler.execute(toolCall, this.options.tools, this.options.onToolCallStart, this.options.onToolCallEnd);
|
|
467
|
+
await runMiddleware(this.middlewares, "onToolCallEnd", context, toolCall, toolResult.content);
|
|
468
|
+
this.messages.push(this.provider.formatToolResultMessage(toolResult.tool_call_id, toolResult.content));
|
|
469
|
+
if (toolResult.halted) {
|
|
470
|
+
haltTriggered = true;
|
|
471
|
+
assistantMessage = new ChatResponseString(toolResult.content, totalUsage, this.model, this.provider.id, undefined, undefined, undefined, "tool_halt");
|
|
472
|
+
if (this.options.onEndMessage) {
|
|
473
|
+
this.options.onEndMessage(assistantMessage);
|
|
474
|
+
}
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
let currentError = error;
|
|
480
|
+
const middlewareDirective = await runMiddleware(this.middlewares, "onToolCallError", context, toolCall, currentError);
|
|
481
|
+
const directive = middlewareDirective ||
|
|
482
|
+
(await this.options.onToolCallError?.(toolCall, currentError));
|
|
483
|
+
if (directive === "STOP")
|
|
484
|
+
throw currentError;
|
|
485
|
+
if (directive === "RETRY") {
|
|
486
|
+
try {
|
|
487
|
+
const toolResult = await ToolHandler.execute(toolCall, this.options.tools, this.options.onToolCallStart, this.options.onToolCallEnd);
|
|
488
|
+
await runMiddleware(this.middlewares, "onToolCallEnd", context, toolCall, toolResult.content);
|
|
489
|
+
this.messages.push(this.provider.formatToolResultMessage(toolResult.tool_call_id, toolResult.content));
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
catch (retryError) {
|
|
493
|
+
currentError = retryError;
|
|
494
|
+
await runMiddleware(this.middlewares, "onToolCallError", context, toolCall, currentError);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
this.messages.push(this.provider.formatToolResultMessage(toolCall.id, `Fatal error executing tool '${toolCall.function.name}': ${currentError.message}`, { isError: true }));
|
|
498
|
+
if (directive === "CONTINUE")
|
|
499
|
+
continue;
|
|
500
|
+
const errorObj = currentError;
|
|
501
|
+
if (errorObj.fatal || errorObj.status === 401 || errorObj.status === 403)
|
|
502
|
+
throw currentError;
|
|
503
|
+
logger.error(`Tool execution failed:`, currentError);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (haltTriggered)
|
|
507
|
+
break;
|
|
508
|
+
response = await this.executor.executeChat({
|
|
509
|
+
model: this.model,
|
|
510
|
+
messages: [...this.systemMessages, ...this.messages],
|
|
511
|
+
tools: this.options.tools,
|
|
512
|
+
temperature: options?.temperature ?? this.options.temperature,
|
|
513
|
+
max_tokens: options?.maxTokens ?? this.options.maxTokens ?? config.maxTokens,
|
|
514
|
+
headers: this.options.headers,
|
|
515
|
+
response_format: responseFormat,
|
|
516
|
+
requestTimeout: options?.requestTimeout ?? this.options.requestTimeout ?? config.requestTimeout,
|
|
517
|
+
prediction: options?.prediction ?? this.options.prediction,
|
|
518
|
+
signal: options?.signal,
|
|
519
|
+
...this.options.params
|
|
520
|
+
});
|
|
521
|
+
trackUsage(response.usage);
|
|
522
|
+
assistantMessage = new ChatResponseString(response.content ?? "", response.usage ?? { input_tokens: 0, output_tokens: 0, total_tokens: 0 }, this.model, this.provider.id, response.thinking, response.reasoning, response.tool_calls, response.finish_reason, this.options.schema);
|
|
523
|
+
if (this.options.onAfterResponse) {
|
|
524
|
+
const result = await this.options.onAfterResponse(assistantMessage);
|
|
525
|
+
if (result)
|
|
526
|
+
assistantMessage = result;
|
|
527
|
+
}
|
|
528
|
+
this.messages.push({
|
|
529
|
+
role: "assistant",
|
|
530
|
+
content: assistantMessage?.toString() || null,
|
|
531
|
+
tool_calls: response.tool_calls,
|
|
532
|
+
usage: response.usage
|
|
533
|
+
});
|
|
534
|
+
if (this.options.onEndMessage &&
|
|
535
|
+
(!response.tool_calls || response.tool_calls.length === 0)) {
|
|
536
|
+
this.options.onEndMessage(assistantMessage);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
finalResponse = new ChatResponseString(assistantMessage.toString() || "", totalUsage, this.model, this.provider.id, assistantMessage.thinking, assistantMessage.reasoning, response.tool_calls, assistantMessage.finish_reason, this.options.schema);
|
|
540
|
+
// 5. onResponse Hook
|
|
541
|
+
const requestDirective = await runMiddleware(this.middlewares, "onResponse", context, finalResponse);
|
|
542
|
+
if (requestDirective && typeof requestDirective === "object") {
|
|
543
|
+
if (requestDirective.action === "RETRY") {
|
|
544
|
+
// Push feedback to history and try again
|
|
545
|
+
this.messages.push({
|
|
546
|
+
role: "user",
|
|
547
|
+
content: requestDirective.message
|
|
548
|
+
});
|
|
549
|
+
correctionAttempt++;
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
if (requestDirective.action === "REPLACE") {
|
|
553
|
+
return requestDirective.response;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (requestDirective === "STOP") {
|
|
557
|
+
throw new Error("[NodeLLM] Execution stopped by middleware.");
|
|
558
|
+
}
|
|
559
|
+
return finalResponse;
|
|
536
560
|
}
|
|
537
|
-
const finalResponse = new ChatResponseString(assistantMessage.toString() || "", totalUsage, this.model, this.provider.id, assistantMessage.thinking, assistantMessage.reasoning, response.tool_calls, assistantMessage.finish_reason, this.options.schema);
|
|
538
|
-
// 5. onResponse Hook
|
|
539
|
-
await runMiddleware(this.middlewares, "onResponse", context, finalResponse);
|
|
540
|
-
return finalResponse;
|
|
541
561
|
}
|
|
542
562
|
catch (err) {
|
|
543
563
|
// 6. onError Hook
|
|
544
|
-
await runMiddleware(this.middlewares, "onError", context, err);
|
|
564
|
+
const errorDirective = await runMiddleware(this.middlewares, "onError", context, err);
|
|
565
|
+
if (errorDirective &&
|
|
566
|
+
typeof errorDirective === "object" &&
|
|
567
|
+
errorDirective.action === "RETRY") {
|
|
568
|
+
// ... handled by retry loop?
|
|
569
|
+
// For now, only onResponse triggers self-correction for simplicity.
|
|
570
|
+
}
|
|
545
571
|
throw err;
|
|
546
572
|
}
|
|
547
573
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Middleware } from "../types/Middleware.js";
|
|
2
2
|
import { Message } from "./Message.js";
|
|
3
3
|
import { ToolResolvable } from "./Tool.js";
|
|
4
|
+
import { ContentPart } from "./Content.js";
|
|
4
5
|
import { Schema } from "../schema/Schema.js";
|
|
5
6
|
import { ChatResponseString } from "./ChatResponse.js";
|
|
6
7
|
import { ToolExecutionMode } from "../constants.js";
|
|
@@ -18,14 +19,15 @@ export interface ChatOptions {
|
|
|
18
19
|
onToolCallEnd?: (toolCall: unknown, result: unknown) => void;
|
|
19
20
|
onToolCallError?: (toolCall: unknown, error: Error) => "STOP" | "CONTINUE" | "RETRY" | void | Promise<"STOP" | "CONTINUE" | "RETRY" | void>;
|
|
20
21
|
headers?: Record<string, string>;
|
|
21
|
-
schema?: Schema;
|
|
22
22
|
responseFormat?: ResponseFormat;
|
|
23
|
+
thinking?: ThinkingConfig;
|
|
24
|
+
prediction?: string | ContentPart[];
|
|
25
|
+
schema?: Schema;
|
|
23
26
|
params?: Record<string, unknown>;
|
|
24
27
|
assumeModelExists?: boolean;
|
|
25
28
|
provider?: string;
|
|
26
29
|
maxToolCalls?: number;
|
|
27
30
|
requestTimeout?: number;
|
|
28
|
-
thinking?: ThinkingConfig;
|
|
29
31
|
toolExecution?: ToolExecutionMode;
|
|
30
32
|
onConfirmToolCall?: (toolCall: unknown) => Promise<boolean> | boolean;
|
|
31
33
|
onBeforeRequest?: (messages: Message[]) => Promise<Message[] | void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,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,kBAAkB,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,eAAe,CAAC,EAAE,CAChB,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,KAAK,KACT,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,
|
|
1
|
+
{"version":3,"file":"ChatOptions.d.ts","sourceRoot":"","sources":["../../src/chat/ChatOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,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,kBAAkB,KAAK,IAAI,CAAC;IACrD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,eAAe,CAAC,EAAE,CAChB,QAAQ,EAAE,OAAO,EACjB,KAAK,EAAE,KAAK,KACT,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,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,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACtE,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 +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,EACL,WAAW,EAIZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAyB,MAAM,0BAA0B,CAAC;AAEtF,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAavC;;;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;
|
|
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,EACL,WAAW,EAIZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAyB,MAAM,0BAA0B,CAAC;AAEtF,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAavC;;;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;CAqXrF"}
|
package/dist/chat/ChatStream.js
CHANGED
|
@@ -149,7 +149,7 @@ export class ChatStream {
|
|
|
149
149
|
requestMessages = result;
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
|
|
152
|
+
const streamRequest = {
|
|
153
153
|
model,
|
|
154
154
|
messages: requestMessages,
|
|
155
155
|
tools: options.tools,
|
|
@@ -159,9 +159,14 @@ export class ChatStream {
|
|
|
159
159
|
headers: options.headers,
|
|
160
160
|
requestTimeout: options.requestTimeout ?? config.requestTimeout,
|
|
161
161
|
thinking: options.thinking,
|
|
162
|
+
prediction: options.prediction,
|
|
162
163
|
signal: abortController.signal,
|
|
163
164
|
...options.params
|
|
164
|
-
}
|
|
165
|
+
};
|
|
166
|
+
if (streamRequest.prediction && !provider.capabilities?.supportsPrediction?.(model)) {
|
|
167
|
+
delete streamRequest.prediction;
|
|
168
|
+
}
|
|
169
|
+
for await (const chunk of provider.stream(streamRequest)) {
|
|
165
170
|
if (isFirst) {
|
|
166
171
|
if (options.onNewMessage)
|
|
167
172
|
options.onNewMessage();
|
package/dist/chat/Tool.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface ToolDefinition {
|
|
|
12
12
|
function: {
|
|
13
13
|
name: string;
|
|
14
14
|
description?: string;
|
|
15
|
+
strict?: boolean;
|
|
15
16
|
parameters: Record<string, unknown>;
|
|
16
17
|
};
|
|
17
18
|
handler?: (args: unknown) => Promise<string | ToolHalt>;
|
|
@@ -64,6 +65,11 @@ export declare abstract class Tool<T = Record<string, unknown>> {
|
|
|
64
65
|
* Can be a Zod object (for auto-schema + type safety) or a raw JSON Schema.
|
|
65
66
|
*/
|
|
66
67
|
abstract schema: z.ZodObject<z.ZodRawShape> | Record<string, unknown>;
|
|
68
|
+
/**
|
|
69
|
+
* Whether to enforce strict JSON schema constraints for OpenAI and similar providers.
|
|
70
|
+
* When true, additionalProperties: false and full required arrays are automatically applied.
|
|
71
|
+
*/
|
|
72
|
+
strict?: boolean;
|
|
67
73
|
/**
|
|
68
74
|
* The core logic for the tool.
|
|
69
75
|
* 'args' will be parsed and validated based on 'schema'.
|
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,OAAO,CAAC,CAAC;KACrC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,QAAQ;aACS,OAAO,EAAE,MAAM;gBAAf,OAAO,EAAE,MAAM;IAE3C,QAAQ,IAAI,MAAM;IAIlB,MAAM,IAAI;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAG1C;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG;IAAE,QAAQ,IAAI,CAAA;CAAE,GAAG,cAAc,CAAC;AAEtE;;GAEG;AACH,8BAAsB,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpD;;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,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE7E;;;OAGG;aACa,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAElD;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IAIzC;;;;OAIG;IACU,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;
|
|
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,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACrC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,QAAQ;aACS,OAAO,EAAE,MAAM;gBAAf,OAAO,EAAE,MAAM;IAE3C,QAAQ,IAAI,MAAM;IAIlB,MAAM,IAAI;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAG1C;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG;IAAE,QAAQ,IAAI,CAAA;CAAE,GAAG,cAAc,CAAC;AAEtE;;GAEG;AACH,8BAAsB,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpD;;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,CAAC,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE7E;;;OAGG;IACI,MAAM,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;aACa,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAElD;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IAIzC;;;;OAIG;IACU,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC;IAkBzD;;;OAGG;IACI,SAAS,IAAI,cAAc;CAwBnC"}
|
package/dist/chat/Tool.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { toJsonSchema } from "../schema/to-json-schema.js";
|
|
2
3
|
/**
|
|
3
4
|
* Stops the agentic tool execution loop and returns the content as the final response.
|
|
@@ -31,6 +32,11 @@ export class ToolHalt {
|
|
|
31
32
|
* Subclass this to create tools with auto-generated schemas and type safety.
|
|
32
33
|
*/
|
|
33
34
|
export class Tool {
|
|
35
|
+
/**
|
|
36
|
+
* Whether to enforce strict JSON schema constraints for OpenAI and similar providers.
|
|
37
|
+
* When true, additionalProperties: false and full required arrays are automatically applied.
|
|
38
|
+
*/
|
|
39
|
+
strict;
|
|
34
40
|
/**
|
|
35
41
|
* Stop the agentic loop and return this message as the final tool result.
|
|
36
42
|
* Use this when you want to end the conversation turn immediately.
|
|
@@ -54,7 +60,12 @@ export class Tool {
|
|
|
54
60
|
* Preserves ToolHalt instances for the execution loop to detect.
|
|
55
61
|
*/
|
|
56
62
|
async handler(args) {
|
|
57
|
-
|
|
63
|
+
// 1. Runtime validation if Zod schema is provided
|
|
64
|
+
let validatedArgs = args;
|
|
65
|
+
if (this.schema instanceof z.ZodType) {
|
|
66
|
+
validatedArgs = this.schema.parse(args);
|
|
67
|
+
}
|
|
68
|
+
const result = await this.execute(validatedArgs);
|
|
58
69
|
// Preserve ToolHalt for the execution loop to handle
|
|
59
70
|
if (result instanceof ToolHalt) {
|
|
60
71
|
return result;
|
|
@@ -82,6 +93,7 @@ export class Tool {
|
|
|
82
93
|
function: {
|
|
83
94
|
name: this.name,
|
|
84
95
|
description: this.description,
|
|
96
|
+
strict: this.strict,
|
|
85
97
|
parameters: parameters
|
|
86
98
|
},
|
|
87
99
|
handler: (args) => this.handler(args)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Executor.d.ts","sourceRoot":"","sources":["../../src/executor/Executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG/E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAGzD,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Executor.d.ts","sourceRoot":"","sources":["../../src/executor/Executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG/E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAGzD,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CA4B/D"}
|
|
@@ -8,6 +8,9 @@ export class Executor {
|
|
|
8
8
|
}
|
|
9
9
|
async executeChat(request) {
|
|
10
10
|
let lastError;
|
|
11
|
+
if (request.prediction && !this.provider.capabilities?.supportsPrediction?.(request.model)) {
|
|
12
|
+
delete request.prediction;
|
|
13
|
+
}
|
|
11
14
|
for (let attempt = 1; attempt <= this.retry.attempts; attempt++) {
|
|
12
15
|
try {
|
|
13
16
|
return await this.provider.chat(request);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Middleware, MiddlewareContext } from "../types/Middleware.js";
|
|
1
|
+
import { Middleware, MiddlewareContext, RequestDirective } from "../types/Middleware.js";
|
|
2
2
|
import { ChatResponseString } from "../chat/ChatResponse.js";
|
|
3
3
|
export interface CostGuardOptions {
|
|
4
4
|
/**
|
|
@@ -19,6 +19,10 @@ export declare class CostGuardMiddleware implements Middleware {
|
|
|
19
19
|
readonly name = "CostGuard";
|
|
20
20
|
private accumulatedCost;
|
|
21
21
|
constructor(options: CostGuardOptions);
|
|
22
|
-
onResponse(ctx: MiddlewareContext, result: ChatResponseString): Promise<
|
|
22
|
+
onResponse(ctx: MiddlewareContext, result: ChatResponseString): Promise<RequestDirective>;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Factory function for creating the cost guard middleware.
|
|
26
|
+
*/
|
|
27
|
+
export declare function CostGuard(options: CostGuardOptions): CostGuardMiddleware;
|
|
24
28
|
//# sourceMappingURL=CostGuardMiddleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CostGuardMiddleware.d.ts","sourceRoot":"","sources":["../../src/middlewares/CostGuardMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"CostGuardMiddleware.d.ts","sourceRoot":"","sources":["../../src/middlewares/CostGuardMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACzE;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,UAAU;IAIxC,OAAO,CAAC,OAAO;IAH3B,SAAgB,IAAI,eAAe;IACnC,OAAO,CAAC,eAAe,CAAa;gBAEhB,OAAO,EAAE,gBAAgB;IAMvC,UAAU,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAWhG;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,mBAAmB,CAExE"}
|