@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.
Files changed (54) hide show
  1. package/dist/agent/Agent.d.ts +13 -9
  2. package/dist/agent/Agent.d.ts.map +1 -1
  3. package/dist/agent/Agent.js +4 -1
  4. package/dist/aliases.d.ts +123 -215
  5. package/dist/aliases.d.ts.map +1 -1
  6. package/dist/aliases.js +177 -269
  7. package/dist/chat/Chat.d.ts +6 -0
  8. package/dist/chat/Chat.d.ts.map +1 -1
  9. package/dist/chat/Chat.js +189 -163
  10. package/dist/chat/ChatOptions.d.ts +4 -2
  11. package/dist/chat/ChatOptions.d.ts.map +1 -1
  12. package/dist/chat/ChatStream.d.ts.map +1 -1
  13. package/dist/chat/ChatStream.js +7 -2
  14. package/dist/chat/Tool.d.ts +6 -0
  15. package/dist/chat/Tool.d.ts.map +1 -1
  16. package/dist/chat/Tool.js +13 -1
  17. package/dist/executor/Executor.d.ts.map +1 -1
  18. package/dist/executor/Executor.js +3 -0
  19. package/dist/middlewares/CostGuardMiddleware.d.ts +6 -2
  20. package/dist/middlewares/CostGuardMiddleware.d.ts.map +1 -1
  21. package/dist/middlewares/CostGuardMiddleware.js +6 -0
  22. package/dist/middlewares/SchemaSelfCorrection.d.ts +26 -0
  23. package/dist/middlewares/SchemaSelfCorrection.d.ts.map +1 -0
  24. package/dist/middlewares/SchemaSelfCorrection.js +70 -0
  25. package/dist/middlewares/UsageLoggerMiddleware.d.ts +6 -2
  26. package/dist/middlewares/UsageLoggerMiddleware.d.ts.map +1 -1
  27. package/dist/middlewares/UsageLoggerMiddleware.js +6 -0
  28. package/dist/middlewares/index.d.ts +1 -0
  29. package/dist/middlewares/index.d.ts.map +1 -1
  30. package/dist/middlewares/index.js +1 -0
  31. package/dist/models/models.json +1057 -2007
  32. package/dist/providers/Provider.d.ts +3 -0
  33. package/dist/providers/Provider.d.ts.map +1 -1
  34. package/dist/providers/ollama/OllamaProvider.d.ts.map +1 -1
  35. package/dist/providers/ollama/OllamaProvider.js +1 -0
  36. package/dist/providers/openai/Capabilities.d.ts +1 -0
  37. package/dist/providers/openai/Capabilities.d.ts.map +1 -1
  38. package/dist/providers/openai/Capabilities.js +3 -0
  39. package/dist/providers/openai/Chat.d.ts.map +1 -1
  40. package/dist/providers/openai/Chat.js +38 -5
  41. package/dist/providers/openai/OpenAIProvider.d.ts +2 -1
  42. package/dist/providers/openai/OpenAIProvider.d.ts.map +1 -1
  43. package/dist/providers/openai/OpenAIProvider.js +2 -1
  44. package/dist/providers/openai/Streaming.d.ts.map +1 -1
  45. package/dist/providers/openai/Streaming.js +33 -2
  46. package/dist/providers/openrouter/OpenRouterProvider.d.ts +1 -0
  47. package/dist/providers/openrouter/OpenRouterProvider.d.ts.map +1 -1
  48. package/dist/providers/openrouter/OpenRouterProvider.js +1 -0
  49. package/dist/schema/strict.d.ts +2 -0
  50. package/dist/schema/strict.d.ts.map +1 -0
  51. package/dist/schema/strict.js +39 -0
  52. package/dist/types/Middleware.d.ts +16 -2
  53. package/dist/types/Middleware.d.ts.map +1 -1
  54. package/package.json +1 -1
@@ -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
  */
@@ -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;AAQpD,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,IAAI,CAAC,CAAC,GAAG,OAAO;IAOzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,WAAW,CAAoB;gBAGpB,QAAQ,EAAE,QAAQ,EAC3B,KAAK,EAAE,MAAM,EACJ,OAAO,GAAE,WAAgB,EAC1C,WAAW,GAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAgC;IA8BlF;;OAEG;IACH,IAAI,OAAO,IAAI,SAAS,OAAO,EAAE,CAEhC;IAED,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,KAAK,CAuBtB;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAIpC;;;;;;;OAOG;IACH,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAkBzE;;;;OAIG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAW5E;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAI5E;;OAEG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI;IAIlE;;;OAGG;IACH,GAAG,CACD,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,EAC5D,OAAO,EAAE,MAAM,GAAG,cAAc,GAC/B,IAAI;IAYP;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASlC;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK9B;;;OAGG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,cAAc,CAAC,EAAE,OAAO,CAAC;KAC1B,GAAG,IAAI;IAUR;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAKjD;;;OAGG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;IAgBtF;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAK1C;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;IAM5D,YAAY,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAKvC,YAAY,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI;IAKlE,UAAU,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAItD,YAAY,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAItD;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAK3D;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAK1E,eAAe,CACb,OAAO,EAAE,CACP,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,GACxF,IAAI;IAKP;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAKhD;;;OAGG;IACH,iBAAiB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI;IAKnF;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI;IAKhF;;;OAGG;IACH,aAAa,CACX,OAAO,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAC5E,IAAI;IAKP;;OAEG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA2X7F;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,EAAE,OAAO,GAAE,UAAe,GAAG,MAAM,CAAC,SAAS,CAAC;IAWpF;;OAEG;IACH,OAAO,CAAC,aAAa;CAoDtB"}
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
- // Re-read mutable context
354
- const messagesToUse = context.messages || [];
355
- const executeOptions = {
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
- const trackUsage = (u) => {
377
- if (u) {
378
- // Fallback cost calculation if provider didn't return it
379
- if (u.cost === undefined) {
380
- const withCost = ModelRegistry.calculateCost(u, this.model, this.provider.id);
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: [...this.systemMessages, ...this.messages], // Use updated history
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,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,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,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,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
+ {"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;CA8WrF"}
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"}
@@ -149,7 +149,7 @@ export class ChatStream {
149
149
  requestMessages = result;
150
150
  }
151
151
  }
152
- for await (const chunk of provider.stream({
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();
@@ -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'.
@@ -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;IAYzD;;;OAGG;IACI,SAAS,IAAI,cAAc;CAuBnC"}
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
- const result = await this.execute(args);
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;CAwB/D"}
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<void>;
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;AACvE,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,IAAI,CAAC;CAWpF"}
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"}
@@ -21,3 +21,9 @@ export class CostGuardMiddleware {
21
21
  }
22
22
  }
23
23
  }
24
+ /**
25
+ * Factory function for creating the cost guard middleware.
26
+ */
27
+ export function CostGuard(options) {
28
+ return new CostGuardMiddleware(options);
29
+ }