toolpack-sdk 0.1.1 → 1.1.0-SNAPSHOT

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 (192) hide show
  1. package/README.md +115 -4
  2. package/dist/client/index.d.ts +1 -0
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +82 -79
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/knowledge/embedders/gemini-embedder.d.ts +21 -0
  11. package/dist/knowledge/embedders/gemini-embedder.d.ts.map +1 -0
  12. package/dist/knowledge/embedders/gemini-embedder.js +93 -0
  13. package/dist/knowledge/embedders/gemini-embedder.js.map +1 -0
  14. package/dist/knowledge/embedders/ollama-embedder.d.ts +12 -0
  15. package/dist/knowledge/embedders/ollama-embedder.d.ts.map +1 -0
  16. package/dist/knowledge/embedders/ollama-embedder.js +68 -0
  17. package/dist/knowledge/embedders/ollama-embedder.js.map +1 -0
  18. package/dist/knowledge/embedders/openai-embedder.d.ts +14 -0
  19. package/dist/knowledge/embedders/openai-embedder.d.ts.map +1 -0
  20. package/dist/knowledge/embedders/openai-embedder.js +94 -0
  21. package/dist/knowledge/embedders/openai-embedder.js.map +1 -0
  22. package/dist/knowledge/errors.d.ts +22 -0
  23. package/dist/knowledge/errors.d.ts.map +1 -0
  24. package/dist/knowledge/errors.js +51 -0
  25. package/dist/knowledge/errors.js.map +1 -0
  26. package/dist/knowledge/index.d.ts +12 -0
  27. package/dist/knowledge/index.d.ts.map +1 -0
  28. package/dist/knowledge/index.js +26 -0
  29. package/dist/knowledge/index.js.map +1 -0
  30. package/dist/knowledge/knowledge.d.ts +38 -0
  31. package/dist/knowledge/knowledge.d.ts.map +1 -0
  32. package/dist/knowledge/knowledge.js +287 -0
  33. package/dist/knowledge/knowledge.js.map +1 -0
  34. package/dist/knowledge/providers/memory-provider.d.ts +15 -0
  35. package/dist/knowledge/providers/memory-provider.d.ts.map +1 -0
  36. package/dist/knowledge/providers/memory-provider.js +113 -0
  37. package/dist/knowledge/providers/memory-provider.js.map +1 -0
  38. package/dist/knowledge/sources/json-source.d.ts +18 -0
  39. package/dist/knowledge/sources/json-source.d.ts.map +1 -0
  40. package/dist/knowledge/sources/json-source.js +224 -0
  41. package/dist/knowledge/sources/json-source.js.map +1 -0
  42. package/dist/knowledge/sources/markdown-source.d.ts +27 -0
  43. package/dist/knowledge/sources/markdown-source.d.ts.map +1 -0
  44. package/dist/knowledge/sources/markdown-source.js +410 -0
  45. package/dist/knowledge/sources/markdown-source.js.map +1 -0
  46. package/dist/knowledge/sources/sqlite-text-source.d.ts +18 -0
  47. package/dist/knowledge/sources/sqlite-text-source.d.ts.map +1 -0
  48. package/dist/knowledge/sources/sqlite-text-source.js +201 -0
  49. package/dist/knowledge/sources/sqlite-text-source.js.map +1 -0
  50. package/dist/knowledge/types.d.ts +130 -0
  51. package/dist/knowledge/types.d.ts.map +1 -0
  52. package/dist/knowledge/types.js +3 -0
  53. package/dist/knowledge/types.js.map +1 -0
  54. package/dist/mcp/client.js +1 -1
  55. package/dist/mcp/client.js.map +1 -1
  56. package/dist/providers/anthropic/index.js +13 -13
  57. package/dist/providers/anthropic/index.js.map +1 -1
  58. package/dist/providers/config.d.ts +0 -2
  59. package/dist/providers/config.d.ts.map +1 -1
  60. package/dist/providers/config.js.map +1 -1
  61. package/dist/providers/gemini/index.js +10 -10
  62. package/dist/providers/gemini/index.js.map +1 -1
  63. package/dist/providers/ollama/adapter.d.ts.map +1 -1
  64. package/dist/providers/ollama/adapter.js +14 -18
  65. package/dist/providers/ollama/adapter.js.map +1 -1
  66. package/dist/providers/ollama/slm-healer.js +7 -7
  67. package/dist/providers/ollama/slm-healer.js.map +1 -1
  68. package/dist/providers/openai/index.d.ts.map +1 -1
  69. package/dist/providers/openai/index.js +15 -21
  70. package/dist/providers/openai/index.js.map +1 -1
  71. package/dist/providers/provider-logger.d.ts +17 -9
  72. package/dist/providers/provider-logger.d.ts.map +1 -1
  73. package/dist/providers/provider-logger.js +68 -26
  74. package/dist/providers/provider-logger.js.map +1 -1
  75. package/dist/toolpack.d.ts +12 -0
  76. package/dist/toolpack.d.ts.map +1 -1
  77. package/dist/toolpack.js +36 -34
  78. package/dist/toolpack.js.map +1 -1
  79. package/dist/tools/cloud-tools/tools/deploy/index.d.ts.map +1 -1
  80. package/dist/tools/cloud-tools/tools/deploy/index.js +2 -0
  81. package/dist/tools/cloud-tools/tools/deploy/index.js.map +1 -1
  82. package/dist/tools/cloud-tools/tools/list/index.d.ts.map +1 -1
  83. package/dist/tools/cloud-tools/tools/list/index.js +2 -0
  84. package/dist/tools/cloud-tools/tools/list/index.js.map +1 -1
  85. package/dist/tools/coding-tools/tools/find-references/index.d.ts.map +1 -1
  86. package/dist/tools/coding-tools/tools/find-references/index.js +2 -0
  87. package/dist/tools/coding-tools/tools/find-references/index.js.map +1 -1
  88. package/dist/tools/coding-tools/tools/find-symbol/index.d.ts.map +1 -1
  89. package/dist/tools/coding-tools/tools/find-symbol/index.js +2 -0
  90. package/dist/tools/coding-tools/tools/find-symbol/index.js.map +1 -1
  91. package/dist/tools/coding-tools/tools/get-exports/index.d.ts.map +1 -1
  92. package/dist/tools/coding-tools/tools/get-exports/index.js +2 -0
  93. package/dist/tools/coding-tools/tools/get-exports/index.js.map +1 -1
  94. package/dist/tools/coding-tools/tools/get-imports/index.d.ts.map +1 -1
  95. package/dist/tools/coding-tools/tools/get-imports/index.js +2 -0
  96. package/dist/tools/coding-tools/tools/get-imports/index.js.map +1 -1
  97. package/dist/tools/coding-tools/tools/get-outline/index.d.ts.map +1 -1
  98. package/dist/tools/coding-tools/tools/get-outline/index.js +2 -0
  99. package/dist/tools/coding-tools/tools/get-outline/index.js.map +1 -1
  100. package/dist/tools/coding-tools/tools/get-symbols/index.d.ts.map +1 -1
  101. package/dist/tools/coding-tools/tools/get-symbols/index.js +2 -0
  102. package/dist/tools/coding-tools/tools/get-symbols/index.js.map +1 -1
  103. package/dist/tools/config-loader.d.ts +13 -0
  104. package/dist/tools/config-loader.d.ts.map +1 -1
  105. package/dist/tools/config-loader.js +20 -8
  106. package/dist/tools/config-loader.js.map +1 -1
  107. package/dist/tools/create-tool-project.d.ts.map +1 -1
  108. package/dist/tools/create-tool-project.js +2 -1
  109. package/dist/tools/create-tool-project.js.map +1 -1
  110. package/dist/tools/db-tools/tools/query/index.d.ts.map +1 -1
  111. package/dist/tools/db-tools/tools/query/index.js +2 -0
  112. package/dist/tools/db-tools/tools/query/index.js.map +1 -1
  113. package/dist/tools/diff-tools/tools/apply/index.d.ts.map +1 -1
  114. package/dist/tools/diff-tools/tools/apply/index.js +2 -0
  115. package/dist/tools/diff-tools/tools/apply/index.js.map +1 -1
  116. package/dist/tools/diff-tools/tools/create/index.d.ts.map +1 -1
  117. package/dist/tools/diff-tools/tools/create/index.js +2 -0
  118. package/dist/tools/diff-tools/tools/create/index.js.map +1 -1
  119. package/dist/tools/exec-tools/tools/run/index.d.ts.map +1 -1
  120. package/dist/tools/exec-tools/tools/run/index.js +2 -0
  121. package/dist/tools/exec-tools/tools/run/index.js.map +1 -1
  122. package/dist/tools/exec-tools/tools/run-background/index.d.ts.map +1 -1
  123. package/dist/tools/exec-tools/tools/run-background/index.js +5 -0
  124. package/dist/tools/exec-tools/tools/run-background/index.js.map +1 -1
  125. package/dist/tools/exec-tools/tools/run-shell/index.d.ts.map +1 -1
  126. package/dist/tools/exec-tools/tools/run-shell/index.js +2 -0
  127. package/dist/tools/exec-tools/tools/run-shell/index.js.map +1 -1
  128. package/dist/tools/fs-tools/tools/delete-file/index.d.ts.map +1 -1
  129. package/dist/tools/fs-tools/tools/delete-file/index.js +2 -0
  130. package/dist/tools/fs-tools/tools/delete-file/index.js.map +1 -1
  131. package/dist/tools/fs-tools/tools/read-file/index.d.ts.map +1 -1
  132. package/dist/tools/fs-tools/tools/read-file/index.js +2 -0
  133. package/dist/tools/fs-tools/tools/read-file/index.js.map +1 -1
  134. package/dist/tools/fs-tools/tools/search/index.d.ts.map +1 -1
  135. package/dist/tools/fs-tools/tools/search/index.js +2 -0
  136. package/dist/tools/fs-tools/tools/search/index.js.map +1 -1
  137. package/dist/tools/fs-tools/tools/write-file/index.d.ts.map +1 -1
  138. package/dist/tools/fs-tools/tools/write-file/index.js +2 -0
  139. package/dist/tools/fs-tools/tools/write-file/index.js.map +1 -1
  140. package/dist/tools/http-tools/tools/delete/index.d.ts.map +1 -1
  141. package/dist/tools/http-tools/tools/delete/index.js +2 -0
  142. package/dist/tools/http-tools/tools/delete/index.js.map +1 -1
  143. package/dist/tools/http-tools/tools/download/index.d.ts.map +1 -1
  144. package/dist/tools/http-tools/tools/download/index.js +2 -0
  145. package/dist/tools/http-tools/tools/download/index.js.map +1 -1
  146. package/dist/tools/http-tools/tools/get/index.d.ts.map +1 -1
  147. package/dist/tools/http-tools/tools/get/index.js +2 -0
  148. package/dist/tools/http-tools/tools/get/index.js.map +1 -1
  149. package/dist/tools/http-tools/tools/post/index.d.ts.map +1 -1
  150. package/dist/tools/http-tools/tools/post/index.js +2 -0
  151. package/dist/tools/http-tools/tools/post/index.js.map +1 -1
  152. package/dist/tools/http-tools/tools/put/index.d.ts.map +1 -1
  153. package/dist/tools/http-tools/tools/put/index.js +2 -0
  154. package/dist/tools/http-tools/tools/put/index.js.map +1 -1
  155. package/dist/tools/index.d.ts +1 -1
  156. package/dist/tools/index.d.ts.map +1 -1
  157. package/dist/tools/index.js +3 -2
  158. package/dist/tools/index.js.map +1 -1
  159. package/dist/tools/system-tools/tools/cwd/index.d.ts.map +1 -1
  160. package/dist/tools/system-tools/tools/cwd/index.js +2 -0
  161. package/dist/tools/system-tools/tools/cwd/index.js.map +1 -1
  162. package/dist/tools/system-tools/tools/env/index.d.ts.map +1 -1
  163. package/dist/tools/system-tools/tools/env/index.js +2 -0
  164. package/dist/tools/system-tools/tools/env/index.js.map +1 -1
  165. package/dist/tools/system-tools/tools/info/index.d.ts.map +1 -1
  166. package/dist/tools/system-tools/tools/info/index.js +2 -0
  167. package/dist/tools/system-tools/tools/info/index.js.map +1 -1
  168. package/dist/tools/types.d.ts +1 -0
  169. package/dist/tools/types.d.ts.map +1 -1
  170. package/dist/tools/types.js +1 -0
  171. package/dist/tools/types.js.map +1 -1
  172. package/dist/tools/web-tools/tools/fetch/index.d.ts.map +1 -1
  173. package/dist/tools/web-tools/tools/fetch/index.js +2 -0
  174. package/dist/tools/web-tools/tools/fetch/index.js.map +1 -1
  175. package/dist/tools/web-tools/tools/scrape/index.d.ts.map +1 -1
  176. package/dist/tools/web-tools/tools/scrape/index.js +2 -0
  177. package/dist/tools/web-tools/tools/scrape/index.js.map +1 -1
  178. package/dist/tools/web-tools/tools/search/index.d.ts.map +1 -1
  179. package/dist/tools/web-tools/tools/search/index.js +44 -7
  180. package/dist/tools/web-tools/tools/search/index.js.map +1 -1
  181. package/dist/tools/web-tools/tools/search/schema.js +1 -1
  182. package/dist/tools/web-tools/tools/search/schema.js.map +1 -1
  183. package/dist/workflows/planning/planner.d.ts.map +1 -1
  184. package/dist/workflows/planning/planner.js +16 -2
  185. package/dist/workflows/planning/planner.js.map +1 -1
  186. package/dist/workflows/steps/step-executor.d.ts.map +1 -1
  187. package/dist/workflows/steps/step-executor.js +17 -5
  188. package/dist/workflows/steps/step-executor.js.map +1 -1
  189. package/dist/workflows/workflow-executor.d.ts.map +1 -1
  190. package/dist/workflows/workflow-executor.js +32 -2
  191. package/dist/workflows/workflow-executor.js.map +1 -1
  192. package/package.json +4 -4
@@ -16,12 +16,12 @@ function newRequestId() {
16
16
  return `${Date.now()}-${REQUEST_SEQ}`;
17
17
  }
18
18
  function logRequestMessages(requestId, messages) {
19
- if (!(0, provider_logger_1.isVerbose)())
19
+ if (!(0, provider_logger_1.shouldLog)('debug'))
20
20
  return;
21
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Messages (${messages.length}):`);
21
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] Messages (${messages.length}):`);
22
22
  messages.forEach((m, i) => {
23
23
  const preview = (0, provider_logger_1.safePreview)(m.content, 300);
24
- (0, provider_logger_1.log)(`[AIClient][${requestId}] #${i} role=${m.role} content=${preview}`);
24
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] #${i} role=${m.role} content=${preview}`);
25
25
  });
26
26
  }
27
27
  function extractLastUserText(messages) {
@@ -124,7 +124,7 @@ function extractToolContext(messages) {
124
124
  }
125
125
  async function inferNeedsToolsWithAI(provider, providerName, messages, fastModel) {
126
126
  const requestId = newRequestId();
127
- (0, provider_logger_1.log)(`[AIClient][${requestId}] inferNeedsToolsWithAI() provider=${providerName} model=${fastModel}`);
127
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] inferNeedsToolsWithAI() provider=${providerName} model=${fastModel}`);
128
128
  // Extract tool context from recent tool calls
129
129
  const toolContext = extractToolContext(messages);
130
130
  // Get the last user message
@@ -152,11 +152,11 @@ Answer only: YES or NO`;
152
152
  });
153
153
  const answer = (response.content || '').trim().toUpperCase();
154
154
  const needsTools = answer.startsWith('YES');
155
- (0, provider_logger_1.log)(`[AIClient][${requestId}] inferNeedsToolsWithAI() context="${toolContext}" message="${userMessage.substring(0, 50)}" result=${needsTools} (raw: ${answer})`);
155
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] inferNeedsToolsWithAI() context="${toolContext}" message="${userMessage.substring(0, 50)}" result=${needsTools} (raw: ${answer})`);
156
156
  return needsTools;
157
157
  }
158
158
  catch (error) {
159
- (0, provider_logger_1.log)(`[AIClient][${requestId}] inferNeedsToolsWithAI() error=${error} - falling back to false`);
159
+ (0, provider_logger_1.logWarn)(`[AIClient][${requestId}] inferNeedsToolsWithAI() error=${error} - falling back to false`);
160
160
  return false;
161
161
  }
162
162
  }
@@ -177,11 +177,6 @@ function inferLookupOnly(messages) {
177
177
  ];
178
178
  return lookupPatterns.some(r => r.test(text)) && !mutatingPatterns.some(r => r.test(text));
179
179
  }
180
- const TOOL_RESULT_MAX_CHARS = (() => {
181
- const raw = process.env.TOOLPACK_SDK_TOOL_RESULT_MAX_CHARS;
182
- const n = raw ? Number(raw) : NaN;
183
- return Number.isFinite(n) && n > 0 ? n : 20_000;
184
- })();
185
180
  class AIClient extends events_1.EventEmitter {
186
181
  providers;
187
182
  defaultProvider;
@@ -194,6 +189,7 @@ class AIClient extends events_1.EventEmitter {
194
189
  activeMode = null;
195
190
  overrideSystemPrompt;
196
191
  disableBaseContext;
192
+ toolResultMaxChars;
197
193
  constructor(config) {
198
194
  super();
199
195
  this.providers = new Map(Object.entries(config.providers));
@@ -206,6 +202,8 @@ class AIClient extends events_1.EventEmitter {
206
202
  this.toolOrchestrator = new tool_orchestrator_js_1.ToolOrchestrator();
207
203
  this.overrideSystemPrompt = config.systemPrompt;
208
204
  this.disableBaseContext = config.disableBaseContext || false;
205
+ const configuredMax = this.toolsConfig.resultMaxChars ?? types_js_1.DEFAULT_TOOLS_CONFIG.resultMaxChars ?? 20_000;
206
+ this.toolResultMaxChars = Number.isFinite(configuredMax) && configuredMax > 0 ? configuredMax : 20_000;
209
207
  // Index tools for BM25 search if registry is provided
210
208
  if (this.toolRegistry) {
211
209
  this.bm25Engine.index(this.toolRegistry.getAll());
@@ -276,7 +274,7 @@ class AIClient extends events_1.EventEmitter {
276
274
  */
277
275
  setMode(mode) {
278
276
  this.activeMode = mode;
279
- (0, provider_logger_1.log)(`[AIClient] Mode set to: ${mode ? mode.displayName : 'none (cleared)'}`);
277
+ (0, provider_logger_1.logInfo)(`[AIClient] Mode set to: ${mode ? mode.displayName : 'none (cleared)'}`);
280
278
  }
281
279
  /**
282
280
  * Get the currently active mode.
@@ -291,7 +289,7 @@ class AIClient extends events_1.EventEmitter {
291
289
  reindexTools() {
292
290
  if (this.toolRegistry) {
293
291
  this.bm25Engine.index(this.toolRegistry.getAll());
294
- (0, provider_logger_1.log)(`[AIClient] Re-indexed ${this.bm25Engine.getIndexedCount()} tools for BM25 search`);
292
+ (0, provider_logger_1.logInfo)(`[AIClient] Re-indexed ${this.bm25Engine.getIndexedCount()} tools for BM25 search`);
295
293
  }
296
294
  }
297
295
  /**
@@ -326,7 +324,7 @@ class AIClient extends events_1.EventEmitter {
326
324
  if (!needsTools && intelligentDetection?.enabled && hasTools) {
327
325
  const afterToolCall = isAfterToolCall(enrichedRequest.messages, intelligentDetection.maxFollowUpMessages);
328
326
  if (afterToolCall) {
329
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Message is after tool call, using AI to infer tool needs`);
327
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Message is after tool call, using AI to infer tool needs`);
330
328
  const fastModel = getFastModelForProvider(resolvedProviderName || 'openai');
331
329
  needsTools = await inferNeedsToolsWithAI(provider, resolvedProviderName || 'openai', enrichedRequest.messages, fastModel);
332
330
  aiInferenceUsed = true;
@@ -340,14 +338,14 @@ class AIClient extends events_1.EventEmitter {
340
338
  }
341
339
  else if (shouldForceNone) {
342
340
  enrichedRequest.tool_choice = 'none';
343
- (0, provider_logger_1.log)(`[AIClient][${requestId}] AI inference determined no tools needed, setting tool_choice=none`);
341
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] AI inference determined no tools needed, setting tool_choice=none`);
344
342
  }
345
343
  const providerClass = provider?.constructor?.name || 'UnknownProvider';
346
344
  const outboundReq = { ...enrichedRequest, __toolpack_request_id: requestId };
347
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() start provider=${resolvedProviderName} class=${providerClass} model=${enrichedRequest.model} messages=${enrichedRequest.messages.length} tools=${enrichedRequest.tools?.length || 0} tool_choice=${enrichedRequest.tool_choice ?? 'unset'} policy=${policy} needsTools=${needsTools} autoExecute=${this.toolsConfig.enabled && this.toolsConfig.autoExecute}`);
345
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] generate() start provider=${resolvedProviderName} class=${providerClass} model=${enrichedRequest.model} messages=${enrichedRequest.messages.length} tools=${enrichedRequest.tools?.length || 0} tool_choice=${enrichedRequest.tool_choice ?? 'unset'} policy=${policy} needsTools=${needsTools} autoExecute=${this.toolsConfig.enabled && this.toolsConfig.autoExecute}`);
348
346
  logRequestMessages(requestId, enrichedRequest.messages);
349
347
  let response = await provider.generate(outboundReq);
350
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() initial response finish_reason=${response.finish_reason ?? 'unknown'} tool_calls=${response.tool_calls?.length || 0} content_preview=${(0, provider_logger_1.safePreview)(response.content || '', 200)}`);
348
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] generate() initial response finish_reason=${response.finish_reason ?? 'unknown'} tool_calls=${response.tool_calls?.length || 0} content_preview=${(0, provider_logger_1.safePreview)(response.content || '', 200)}`);
351
349
  // Auto-execute tool call loop
352
350
  if (this.toolsConfig.enabled && this.toolsConfig.autoExecute && this.toolRegistry) {
353
351
  // Classify query to adjust maxToolRounds
@@ -356,19 +354,19 @@ class AIClient extends events_1.EventEmitter {
356
354
  const baseMaxRounds = this.toolsConfig.maxToolRounds;
357
355
  const maxRounds = this.queryClassifier.getToolRoundsAdjustment(classification, baseMaxRounds);
358
356
  if (maxRounds !== baseMaxRounds) {
359
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), adjusted maxToolRounds: ${baseMaxRounds} → ${maxRounds}`);
357
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), adjusted maxToolRounds: ${baseMaxRounds} → ${maxRounds}`);
360
358
  }
361
359
  else {
362
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), keeping maxToolRounds: ${maxRounds}`);
360
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), keeping maxToolRounds: ${maxRounds}`);
363
361
  }
364
362
  let rounds = 0;
365
363
  const messages = [...enrichedRequest.messages];
366
364
  if (response.tool_calls && response.tool_calls.length > 0) {
367
- (0, provider_logger_1.log)(`[AIClient] Received ${response.tool_calls.length} tool call(s): ${response.tool_calls.map(tc => tc.name).join(', ')}`);
365
+ (0, provider_logger_1.logInfo)(`[AIClient] Received ${response.tool_calls.length} tool call(s): ${response.tool_calls.map(tc => tc.name).join(', ')}`);
368
366
  }
369
367
  while (response.tool_calls && response.tool_calls.length > 0 && rounds < maxRounds) {
370
368
  rounds++;
371
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() tool round ${rounds}/${maxRounds} tool_calls=${response.tool_calls.length}`);
369
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] generate() tool round ${rounds}/${maxRounds} tool_calls=${response.tool_calls.length}`);
372
370
  // Add assistant message with tool calls to conversation
373
371
  messages.push({
374
372
  role: 'assistant',
@@ -389,7 +387,7 @@ class AIClient extends events_1.EventEmitter {
389
387
  let toolCallsToExecute = response.tool_calls;
390
388
  const webFetchCalls = response.tool_calls.filter(tc => tc.name === 'web.fetch');
391
389
  if (webFetchCalls.length > MAX_WEB_FETCH_CALLS) {
392
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Limiting web.fetch calls from ${webFetchCalls.length} → ${MAX_WEB_FETCH_CALLS} to prevent context overflow`);
390
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Limiting web.fetch calls from ${webFetchCalls.length} → ${MAX_WEB_FETCH_CALLS} to prevent context overflow`);
393
391
  const limitedWebFetch = webFetchCalls.slice(0, MAX_WEB_FETCH_CALLS);
394
392
  const otherCalls = response.tool_calls.filter(tc => tc.name !== 'web.fetch');
395
393
  toolCallsToExecute = [...otherCalls, ...limitedWebFetch];
@@ -407,7 +405,7 @@ class AIClient extends events_1.EventEmitter {
407
405
  const MAX_TOOL_OUTPUT_PER_ROUND = 50_000;
408
406
  let roundOutputSize = 0;
409
407
  if (useParallel) {
410
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Using parallel execution for ${toolCallsToExecute.length} tools`);
408
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Using parallel execution for ${toolCallsToExecute.length} tools`);
411
409
  const toolResults = await this.toolOrchestrator.executeWithDependencies(toolCallsToExecute, (toolCall) => this.executeTool(toolCall), 5 // maxConcurrent
412
410
  );
413
411
  // Add results in original order with budget tracking
@@ -425,7 +423,7 @@ class AIClient extends events_1.EventEmitter {
425
423
  const resultStr = typeof result === 'string' ? result : JSON.stringify(result);
426
424
  // Check budget before adding
427
425
  if (roundOutputSize + resultStr.length > MAX_TOOL_OUTPUT_PER_ROUND) {
428
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
426
+ (0, provider_logger_1.logWarn)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
429
427
  messages.push({
430
428
  role: 'tool',
431
429
  tool_call_id: toolCall.id,
@@ -434,8 +432,8 @@ class AIClient extends events_1.EventEmitter {
434
432
  parallelBudgetExceeded = true;
435
433
  continue;
436
434
  }
437
- const content = typeof result === 'string' && result.length > TOOL_RESULT_MAX_CHARS
438
- ? `${result.slice(0, TOOL_RESULT_MAX_CHARS)}\n[TRUNCATED tool result: ${result.length} chars]`
435
+ const content = typeof result === 'string' && result.length > this.toolResultMaxChars
436
+ ? `${result.slice(0, this.toolResultMaxChars)}\n[TRUNCATED tool result: ${result.length} chars]`
439
437
  : result;
440
438
  const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
441
439
  roundOutputSize += contentStr.length;
@@ -445,10 +443,10 @@ class AIClient extends events_1.EventEmitter {
445
443
  content,
446
444
  });
447
445
  }
448
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
446
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
449
447
  }
450
448
  else {
451
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Using sequential execution for ${toolCallsToExecute.length} tools`);
449
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Using sequential execution for ${toolCallsToExecute.length} tools`);
452
450
  // Sequential execution with budget tracking
453
451
  let seqBudgetExceeded = false;
454
452
  for (const toolCall of toolCallsToExecute) {
@@ -464,7 +462,7 @@ class AIClient extends events_1.EventEmitter {
464
462
  const resultStr = typeof result === 'string' ? result : JSON.stringify(result);
465
463
  // Check budget before adding
466
464
  if (roundOutputSize + resultStr.length > MAX_TOOL_OUTPUT_PER_ROUND) {
467
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
465
+ (0, provider_logger_1.logWarn)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
468
466
  messages.push({
469
467
  role: 'tool',
470
468
  tool_call_id: toolCall.id,
@@ -473,8 +471,8 @@ class AIClient extends events_1.EventEmitter {
473
471
  seqBudgetExceeded = true;
474
472
  continue;
475
473
  }
476
- const content = typeof result === 'string' && result.length > TOOL_RESULT_MAX_CHARS
477
- ? `${result.slice(0, TOOL_RESULT_MAX_CHARS)}\n[TRUNCATED tool result: ${result.length} chars]`
474
+ const content = typeof result === 'string' && result.length > this.toolResultMaxChars
475
+ ? `${result.slice(0, this.toolResultMaxChars)}\n[TRUNCATED tool result: ${result.length} chars]`
478
476
  : result;
479
477
  const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
480
478
  roundOutputSize += contentStr.length;
@@ -484,7 +482,7 @@ class AIClient extends events_1.EventEmitter {
484
482
  content,
485
483
  });
486
484
  }
487
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
485
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
488
486
  }
489
487
  // Call the model again with updated messages
490
488
  const rawFollowupReq = { ...enrichedRequest, messages, __toolpack_request_id: requestId };
@@ -492,14 +490,14 @@ class AIClient extends events_1.EventEmitter {
492
490
  const followupReq = await this.enrichRequestWithTools(rawFollowupReq);
493
491
  if (followupReq.tool_choice === 'required') {
494
492
  followupReq.tool_choice = lookupOnly ? 'none' : 'auto';
495
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() followup tool_choice override required->${followupReq.tool_choice}`);
493
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] generate() followup tool_choice override required->${followupReq.tool_choice}`);
496
494
  }
497
- if ((0, provider_logger_1.isVerbose)()) {
498
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() followup request messages=${messages.length}`);
495
+ if ((0, provider_logger_1.shouldLog)('debug')) {
496
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] generate() followup request messages=${messages.length}`);
499
497
  logRequestMessages(requestId, messages);
500
498
  }
501
499
  response = await provider.generate(followupReq);
502
- (0, provider_logger_1.log)(`[AIClient][${requestId}] generate() followup response finish_reason=${response.finish_reason ?? 'unknown'} tool_calls=${response.tool_calls?.length || 0} content_preview=${(0, provider_logger_1.safePreview)(response.content || '', 200)}`);
500
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] generate() followup response finish_reason=${response.finish_reason ?? 'unknown'} tool_calls=${response.tool_calls?.length || 0} content_preview=${(0, provider_logger_1.safePreview)(response.content || '', 200)}`);
503
501
  }
504
502
  }
505
503
  return response;
@@ -533,7 +531,7 @@ class AIClient extends events_1.EventEmitter {
533
531
  if (!needsTools && intelligentDetection?.enabled && hasTools) {
534
532
  const afterToolCall = isAfterToolCall(enrichedRequest.messages, intelligentDetection.maxFollowUpMessages);
535
533
  if (afterToolCall) {
536
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Message is after tool call, using AI to infer tool needs`);
534
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Message is after tool call, using AI to infer tool needs`);
537
535
  const fastModel = getFastModelForProvider(resolvedProviderName || 'openai');
538
536
  needsTools = await inferNeedsToolsWithAI(provider, resolvedProviderName || 'openai', enrichedRequest.messages, fastModel);
539
537
  aiInferenceUsed = true;
@@ -547,11 +545,11 @@ class AIClient extends events_1.EventEmitter {
547
545
  }
548
546
  else if (shouldForceNone) {
549
547
  enrichedRequest.tool_choice = 'none';
550
- (0, provider_logger_1.log)(`[AIClient][${requestId}] AI inference determined no tools needed, setting tool_choice=none`);
548
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] AI inference determined no tools needed, setting tool_choice=none`);
551
549
  }
552
550
  const providerClass = provider?.constructor?.name || 'UnknownProvider';
553
551
  const baseReq = { ...enrichedRequest, __toolpack_request_id: requestId };
554
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() start provider=${resolvedProviderName} class=${providerClass} model=${enrichedRequest.model} messages=${enrichedRequest.messages.length} tools=${enrichedRequest.tools?.length || 0} tool_choice=${enrichedRequest.tool_choice ?? 'unset'} policy=${policy} needsTools=${needsTools} autoExecute=${this.toolsConfig.enabled && this.toolsConfig.autoExecute}`);
552
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() start provider=${resolvedProviderName} class=${providerClass} model=${enrichedRequest.model} messages=${enrichedRequest.messages.length} tools=${enrichedRequest.tools?.length || 0} tool_choice=${enrichedRequest.tool_choice ?? 'unset'} policy=${policy} needsTools=${needsTools} autoExecute=${this.toolsConfig.enabled && this.toolsConfig.autoExecute}`);
555
553
  logRequestMessages(requestId, enrichedRequest.messages);
556
554
  if (!this.toolsConfig.enabled || !this.toolsConfig.autoExecute || !this.toolRegistry) {
557
555
  yield* provider.stream(baseReq);
@@ -565,34 +563,34 @@ class AIClient extends events_1.EventEmitter {
565
563
  const baseMaxRounds = this.toolsConfig.maxToolRounds;
566
564
  const maxRounds = this.queryClassifier.getToolRoundsAdjustment(classification, baseMaxRounds);
567
565
  if (maxRounds !== baseMaxRounds) {
568
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), adjusted maxToolRounds: ${baseMaxRounds} → ${maxRounds}`);
566
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() Query classified as ${classification.type} (confidence: ${classification.confidence.toFixed(2)}), adjusted maxToolRounds: ${baseMaxRounds} → ${maxRounds}`);
569
567
  }
570
568
  while (rounds <= maxRounds) {
571
569
  // Check for abort signal at start of each round
572
570
  if (request.signal?.aborted) {
573
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() aborted by signal`);
571
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() aborted by signal`);
574
572
  return;
575
573
  }
576
574
  let accumulatedContent = '';
577
575
  const pendingToolCalls = [];
578
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() round_start ${rounds + 1}/${maxRounds}`);
576
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() round_start ${rounds + 1}/${maxRounds}`);
579
577
  let lastFinishReason = null;
580
578
  const rawRoundReq = { ...baseReq, messages };
581
579
  // Re-enrich to include any newly discovered tools from previous rounds
582
580
  const roundReq = await this.enrichRequestWithTools(rawRoundReq);
583
581
  if (rounds > 0 && roundReq.tool_choice === 'required') {
584
582
  roundReq.tool_choice = lookupOnly ? 'none' : 'auto';
585
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() round_${rounds + 1} tool_choice override required->${roundReq.tool_choice}`);
583
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() round_${rounds + 1} tool_choice override required->${roundReq.tool_choice}`);
586
584
  }
587
585
  for await (const chunk of provider.stream(roundReq)) {
588
586
  // Check for abort signal during streaming
589
587
  if (request.signal?.aborted) {
590
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() aborted by signal during chunk processing`);
588
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() aborted by signal during chunk processing`);
591
589
  return;
592
590
  }
593
591
  if (chunk.tool_calls && chunk.tool_calls.length > 0) {
594
592
  pendingToolCalls.push(...chunk.tool_calls);
595
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() tool_calls_chunk count=${chunk.tool_calls.length} names=${chunk.tool_calls.map(tc => tc.name).join(', ')}`);
593
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] stream() tool_calls_chunk count=${chunk.tool_calls.length} names=${chunk.tool_calls.map(tc => tc.name).join(', ')}`);
596
594
  // Yield tool calls in the chunk so consumers can track them
597
595
  yield chunk;
598
596
  }
@@ -607,18 +605,18 @@ class AIClient extends events_1.EventEmitter {
607
605
  yield chunk;
608
606
  }
609
607
  }
610
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() round_end finish_reason=${lastFinishReason ?? 'unknown'} accumulated_len=${accumulatedContent.length} tool_calls_total=${pendingToolCalls.length} content_preview=${(0, provider_logger_1.safePreview)(accumulatedContent, 200)}`);
608
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] stream() round_end finish_reason=${lastFinishReason ?? 'unknown'} accumulated_len=${accumulatedContent.length} tool_calls_total=${pendingToolCalls.length} content_preview=${(0, provider_logger_1.safePreview)(accumulatedContent, 200)}`);
611
609
  // If no tool calls, we're done
612
610
  if (pendingToolCalls.length === 0) {
613
611
  break;
614
612
  }
615
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() received ${pendingToolCalls.length} tool call(s): ${pendingToolCalls.map(tc => tc.name).join(', ')}`);
613
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() received ${pendingToolCalls.length} tool call(s): ${pendingToolCalls.map(tc => tc.name).join(', ')}`);
616
614
  rounds++;
617
615
  if (rounds > maxRounds) {
618
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() max tool rounds (${maxRounds}) reached`);
616
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() max tool rounds (${maxRounds}) reached`);
619
617
  break;
620
618
  }
621
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() tool round ${rounds}/${maxRounds}`);
619
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] stream() tool round ${rounds}/${maxRounds}`);
622
620
  // Add assistant message and tool results to conversation
623
621
  messages.push({
624
622
  role: 'assistant',
@@ -637,7 +635,7 @@ class AIClient extends events_1.EventEmitter {
637
635
  let toolCallsToExecute = pendingToolCalls;
638
636
  const webFetchCalls = pendingToolCalls.filter(tc => tc.name === 'web.fetch');
639
637
  if (webFetchCalls.length > MAX_WEB_FETCH_CALLS) {
640
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Limiting web.fetch calls from ${webFetchCalls.length} → ${MAX_WEB_FETCH_CALLS} to prevent context overflow`);
638
+ (0, provider_logger_1.logInfo)(`[AIClient][${requestId}] Limiting web.fetch calls from ${webFetchCalls.length} → ${MAX_WEB_FETCH_CALLS} to prevent context overflow`);
641
639
  const limitedWebFetch = webFetchCalls.slice(0, MAX_WEB_FETCH_CALLS);
642
640
  const otherCalls = pendingToolCalls.filter(tc => tc.name !== 'web.fetch');
643
641
  toolCallsToExecute = [...otherCalls, ...limitedWebFetch];
@@ -688,7 +686,7 @@ class AIClient extends events_1.EventEmitter {
688
686
  const resultStr = typeof result === 'string' ? result : JSON.stringify(result);
689
687
  // Check budget before adding
690
688
  if (roundOutputSize + resultStr.length > MAX_TOOL_OUTPUT_PER_ROUND) {
691
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
689
+ (0, provider_logger_1.logWarn)(`[AIClient][${requestId}] Tool output budget exceeded (${MAX_TOOL_OUTPUT_PER_ROUND} chars), adding placeholder for remaining tools`);
692
690
  messages.push({
693
691
  role: 'tool',
694
692
  tool_call_id: toolCall.id,
@@ -697,8 +695,8 @@ class AIClient extends events_1.EventEmitter {
697
695
  budgetExceeded = true;
698
696
  continue;
699
697
  }
700
- const content = typeof result === 'string' && result.length > TOOL_RESULT_MAX_CHARS
701
- ? `${result.slice(0, TOOL_RESULT_MAX_CHARS)}\n[TRUNCATED tool result: ${result.length} chars]`
698
+ const content = typeof result === 'string' && result.length > this.toolResultMaxChars
699
+ ? `${result.slice(0, this.toolResultMaxChars)}\n[TRUNCATED tool result: ${result.length} chars]`
702
700
  : result;
703
701
  const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
704
702
  roundOutputSize += contentStr.length;
@@ -717,9 +715,9 @@ class AIClient extends events_1.EventEmitter {
717
715
  }],
718
716
  };
719
717
  }
720
- (0, provider_logger_1.log)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
721
- if ((0, provider_logger_1.isVerbose)()) {
722
- (0, provider_logger_1.log)(`[AIClient][${requestId}] stream() after_tools messages=${messages.length}`);
718
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] Round tool output size: ${roundOutputSize} chars (budget: ${MAX_TOOL_OUTPUT_PER_ROUND})`);
719
+ if ((0, provider_logger_1.shouldLog)('debug')) {
720
+ (0, provider_logger_1.logDebug)(`[AIClient][${requestId}] stream() after_tools messages=${messages.length}`);
723
721
  logRequestMessages(requestId, messages);
724
722
  }
725
723
  }
@@ -747,11 +745,11 @@ class AIClient extends events_1.EventEmitter {
747
745
  async enrichRequestWithTools(request) {
748
746
  // If mode blocks ALL tools, return request with no tools
749
747
  if (this.activeMode?.blockAllTools) {
750
- (0, provider_logger_1.log)(`[AIClient] Mode "${this.activeMode.displayName}" blocks all tools`);
748
+ (0, provider_logger_1.logInfo)(`[AIClient] Mode "${this.activeMode.displayName}" blocks all tools`);
751
749
  return request;
752
750
  }
753
- if (!this.toolsConfig.enabled || !this.toolRegistry) {
754
- (0, provider_logger_1.log)(`[AIClient] Tools disabled or no registry`);
751
+ if (!this.toolsConfig.enabled || (!this.toolRegistry && (request.tools?.length || 0) === 0)) {
752
+ (0, provider_logger_1.logDebug)(`[AIClient] Tools disabled or no registry`);
755
753
  return request;
756
754
  }
757
755
  // Merge mode-specific tool search config with global config
@@ -766,22 +764,22 @@ class AIClient extends events_1.EventEmitter {
766
764
  ...(this.activeMode.toolSearch.alwaysLoadedCategories ? { alwaysLoadedCategories: this.activeMode.toolSearch.alwaysLoadedCategories } : {}),
767
765
  }
768
766
  };
769
- (0, provider_logger_1.log)(`[AIClient] Merged mode toolSearch config: enabled=${resolvedToolsConfig.toolSearch?.enabled}, alwaysLoadedTools=${resolvedToolsConfig.toolSearch?.alwaysLoadedTools?.length || 0}`);
767
+ (0, provider_logger_1.logDebug)(`[AIClient] Merged mode toolSearch config: enabled=${resolvedToolsConfig.toolSearch?.enabled}, alwaysLoadedTools=${resolvedToolsConfig.toolSearch?.alwaysLoadedTools?.length || 0}`);
770
768
  }
771
769
  // If the request already has tools, only add newly discovered tools when tool.search mode is enabled
772
770
  if (request.tools && request.tools.length > 0) {
773
771
  if (!resolvedToolsConfig.toolSearch?.enabled || !this.toolRegistry) {
774
- (0, provider_logger_1.log)(`[AIClient] Request already has ${request.tools.length} tools`);
772
+ (0, provider_logger_1.logDebug)(`[AIClient] Request already has ${request.tools.length} tools`);
775
773
  return request;
776
774
  }
777
775
  let schemas = await this.toolRouter.resolve(request.messages, this.toolRegistry, resolvedToolsConfig);
778
- (0, provider_logger_1.log)(`[AIClient] Resolved ${schemas.length} tools to send: ${schemas.map(s => s.name).join(', ') || 'none'}`);
776
+ (0, provider_logger_1.logDebug)(`[AIClient] Resolved ${schemas.length} tools to send: ${schemas.map(s => s.name).join(', ') || 'none'}`);
779
777
  if (this.activeMode && schemas.length > 0) {
780
778
  const beforeCount = schemas.length;
781
779
  schemas = this.filterSchemasByMode(schemas, this.activeMode);
782
780
  const filteredCount = beforeCount - schemas.length;
783
781
  if (filteredCount > 0) {
784
- (0, provider_logger_1.log)(`[AIClient] Mode "${this.activeMode.displayName}" filtered out ${filteredCount} tools`);
782
+ (0, provider_logger_1.logInfo)(`[AIClient] Mode "${this.activeMode.displayName}" filtered out ${filteredCount} tools`);
785
783
  }
786
784
  }
787
785
  const existingToolNames = new Set(request.tools.map(tool => tool.function.name));
@@ -796,7 +794,7 @@ class AIClient extends events_1.EventEmitter {
796
794
  },
797
795
  }));
798
796
  if (newTools.length === 0) {
799
- (0, provider_logger_1.log)(`[AIClient] Request already has ${request.tools.length} tools (no new discoveries)`);
797
+ (0, provider_logger_1.logDebug)(`[AIClient] Request already has ${request.tools.length} tools (no new discoveries)`);
800
798
  return request;
801
799
  }
802
800
  let enrichedRequest = {
@@ -808,15 +806,20 @@ class AIClient extends events_1.EventEmitter {
808
806
  }
809
807
  return enrichedRequest;
810
808
  }
811
- let schemas = await this.toolRouter.resolve(request.messages, this.toolRegistry, resolvedToolsConfig);
812
- (0, provider_logger_1.log)(`[AIClient] Resolved ${schemas.length} tools to send: ${schemas.map(s => s.name).join(', ') || 'none'}`);
809
+ if (!this.toolRegistry) {
810
+ (0, provider_logger_1.logDebug)('[AIClient] Tool registry not configured, skipping tool resolution');
811
+ return request;
812
+ }
813
+ const activeRegistry = this.toolRegistry;
814
+ let schemas = await this.toolRouter.resolve(request.messages, activeRegistry, resolvedToolsConfig);
815
+ (0, provider_logger_1.logDebug)(`[AIClient] Resolved ${schemas.length} tools to send: ${schemas.map(s => s.name).join(', ') || 'none'}`);
813
816
  // Apply mode-based filtering
814
817
  if (this.activeMode && schemas.length > 0) {
815
818
  const beforeCount = schemas.length;
816
819
  schemas = this.filterSchemasByMode(schemas, this.activeMode);
817
820
  const filteredCount = beforeCount - schemas.length;
818
821
  if (filteredCount > 0) {
819
- (0, provider_logger_1.log)(`[AIClient] Mode "${this.activeMode.displayName}" filtered out ${filteredCount} tools`);
822
+ (0, provider_logger_1.logInfo)(`[AIClient] Mode "${this.activeMode.displayName}" filtered out ${filteredCount} tools`);
820
823
  }
821
824
  }
822
825
  if (schemas.length === 0) {
@@ -832,7 +835,7 @@ class AIClient extends events_1.EventEmitter {
832
835
  }));
833
836
  let enrichedRequest = { ...request, tools };
834
837
  // Inject Tool Search system prompt if enabled
835
- if (this.toolsConfig.toolSearch?.enabled && this.toolRegistry) {
838
+ if (this.toolsConfig.toolSearch?.enabled && activeRegistry) {
836
839
  enrichedRequest = this.injectToolSearchPrompt(enrichedRequest);
837
840
  }
838
841
  return enrichedRequest;
@@ -866,11 +869,11 @@ class AIClient extends events_1.EventEmitter {
866
869
  */
867
870
  injectModeSystemPrompt(request) {
868
871
  if (!this.activeMode || !this.activeMode.systemPrompt) {
869
- (0, provider_logger_1.log)(`[AIClient] injectModeSystemPrompt: No active mode or empty systemPrompt. activeMode=${this.activeMode?.name}, systemPrompt=${this.activeMode?.systemPrompt?.substring(0, 50)}`);
872
+ (0, provider_logger_1.logDebug)(`[AIClient] injectModeSystemPrompt: No active mode or empty systemPrompt. activeMode=${this.activeMode?.name}, systemPrompt=${this.activeMode?.systemPrompt?.substring(0, 50)}`);
870
873
  return request;
871
874
  }
872
875
  const modePrompt = this.activeMode.systemPrompt;
873
- (0, provider_logger_1.log)(`[AIClient] injectModeSystemPrompt: Injecting mode prompt for ${this.activeMode.name}, length=${modePrompt.length}`);
876
+ (0, provider_logger_1.logDebug)(`[AIClient] injectModeSystemPrompt: Injecting mode prompt for ${this.activeMode.name}, length=${modePrompt.length}`);
874
877
  const hasSystemMessage = request.messages.some(m => m.role === 'system');
875
878
  if (hasSystemMessage) {
876
879
  // Prepend mode prompt to existing system message
@@ -1036,7 +1039,7 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1036
1039
  status: 'started',
1037
1040
  args: toolCall.arguments,
1038
1041
  });
1039
- (0, provider_logger_1.log)(`[AIClient] Executing tool: ${toolCall.name} with args: ${(0, provider_logger_1.safePreview)(toolCall.arguments, 500)}`);
1042
+ (0, provider_logger_1.logInfo)(`[AIClient] Executing tool: ${toolCall.name} with args: ${(0, provider_logger_1.safePreview)(toolCall.arguments, 500)}`);
1040
1043
  if (!this.toolRegistry) {
1041
1044
  const error = 'No tool registry configured';
1042
1045
  this.emit('tool:failed', {
@@ -1073,7 +1076,7 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1073
1076
  }
1074
1077
  const tool = this.toolRegistry.get(toolCall.name);
1075
1078
  if (!tool) {
1076
- (0, provider_logger_1.log)(`[AIClient] Tool '${toolCall.name}' not found in registry`);
1079
+ (0, provider_logger_1.logWarn)(`[AIClient] Tool '${toolCall.name}' not found in registry`);
1077
1080
  // Fuzzy match: detect common hallucination patterns
1078
1081
  const suggestion = this.findSimilarToolName(toolCall.name);
1079
1082
  const errorMsg = suggestion
@@ -1092,7 +1095,7 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1092
1095
  const ctx = {
1093
1096
  workspaceRoot: process.cwd(),
1094
1097
  config: this.toolsConfig?.additionalConfigurations ?? {},
1095
- log: (msg) => (0, provider_logger_1.log)(`[Tool] ${msg}`),
1098
+ log: (msg) => (0, provider_logger_1.logInfo)(`[Tool] ${msg}`),
1096
1099
  };
1097
1100
  const result = await tool.execute(toolCall.arguments, ctx);
1098
1101
  const duration = Date.now() - startTime;
@@ -1114,9 +1117,9 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1114
1117
  status: 'success',
1115
1118
  timestamp: Date.now(),
1116
1119
  });
1117
- (0, provider_logger_1.log)(`[AIClient] Tool ${toolCall.name} executed successfully in ${duration}ms result_len=${result?.length ?? 0}`);
1118
- if ((0, provider_logger_1.isVerbose)()) {
1119
- (0, provider_logger_1.log)(`[AIClient] Tool ${toolCall.name} result_preview=${(0, provider_logger_1.safePreview)(result, 400)}`);
1120
+ (0, provider_logger_1.logInfo)(`[AIClient] Tool ${toolCall.name} executed successfully in ${duration}ms result_len=${result?.length ?? 0}`);
1121
+ if ((0, provider_logger_1.shouldLog)('debug')) {
1122
+ (0, provider_logger_1.logDebug)(`[AIClient] Tool ${toolCall.name} result_preview=${(0, provider_logger_1.safePreview)(result, 400)}`);
1120
1123
  }
1121
1124
  return result;
1122
1125
  }
@@ -1141,7 +1144,7 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1141
1144
  status: 'error',
1142
1145
  timestamp: Date.now(),
1143
1146
  });
1144
- (0, provider_logger_1.log)(`[AIClient] Tool ${toolCall.name} failed: ${(0, provider_logger_1.safePreview)(errorMsg, 300)}`);
1147
+ (0, provider_logger_1.logError)(`[AIClient] Tool ${toolCall.name} failed: ${(0, provider_logger_1.safePreview)(errorMsg, 300)}`);
1145
1148
  return JSON.stringify({ error: errorMsg });
1146
1149
  }
1147
1150
  }
@@ -1213,12 +1216,12 @@ NEVER guess or hallucinate tool names. ALWAYS use tool.search to discover tools
1213
1216
  executeToolSearch(args) {
1214
1217
  const { query, category } = args;
1215
1218
  const limit = this.toolsConfig.toolSearch?.searchResultLimit ?? 5;
1216
- (0, provider_logger_1.log)(`[AIClient] Executing tool.search: query="${query}" category=${category || 'all'} limit=${limit}`);
1219
+ (0, provider_logger_1.logInfo)(`[AIClient] Executing tool.search: query="${query}" category=${category || 'all'} limit=${limit}`);
1217
1220
  const results = this.bm25Engine.search(query, { limit, category });
1218
1221
  // Record discovered tools in the cache
1219
1222
  const toolNames = results.map(r => r.toolName);
1220
1223
  this.toolRouter.getDiscoveryCache().recordDiscovery(query, toolNames);
1221
- (0, provider_logger_1.log)(`[AIClient] tool.search found ${results.length} tools: ${toolNames.join(', ') || 'none'}`);
1224
+ (0, provider_logger_1.logDebug)(`[AIClient] tool.search found ${results.length} tools: ${toolNames.join(', ') || 'none'}`);
1222
1225
  return JSON.stringify({
1223
1226
  query,
1224
1227
  found: results.length,