( model: string, tools: Tools, getToolPermissionContext: () => Promise<ToolPermissionContext>, agents: AgentDefinition[], source?: string, )
| 385 | * @returns true if tool search should be enabled for this request |
| 386 | */ |
| 387 | export async function isToolSearchEnabled( |
| 388 | model: string, |
| 389 | tools: Tools, |
| 390 | getToolPermissionContext: () => Promise<ToolPermissionContext>, |
| 391 | agents: AgentDefinition[], |
| 392 | source?: string, |
| 393 | ): Promise<boolean> { |
| 394 | const mcpToolCount = count(tools, t => t.isMcp) |
| 395 | |
| 396 | // Helper to log the mode decision event |
| 397 | function logModeDecision( |
| 398 | enabled: boolean, |
| 399 | mode: ToolSearchMode, |
| 400 | reason: string, |
| 401 | extraProps?: Record<string, number>, |
| 402 | ): void { |
| 403 | logEvent('ncode_tool_search_mode_decision', { |
| 404 | enabled, |
| 405 | mode: mode as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 406 | reason: |
| 407 | reason as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 408 | // Log the actual model being checked, not the session's main model. |
| 409 | // This is important for debugging subagent tool search decisions where |
| 410 | // the subagent model (e.g., haiku) differs from the session model (e.g., opus). |
| 411 | checkedModel: |
| 412 | model as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 413 | mcpToolCount, |
| 414 | userType: (process.env.USER_TYPE ?? |
| 415 | 'external') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 416 | ...extraProps, |
| 417 | }) |
| 418 | } |
| 419 | |
| 420 | // Check if model supports tool_reference |
| 421 | if (!modelSupportsToolReference(model)) { |
| 422 | logForDebugging( |
| 423 | `Tool search disabled for model '${model}': model does not support tool_reference blocks. ` + |
| 424 | `This feature is only available on balanced/reasoning families and newer models.`, |
| 425 | ) |
| 426 | logModeDecision(false, 'standard', 'model_unsupported') |
| 427 | return false |
| 428 | } |
| 429 | |
| 430 | // Check if ToolSearchTool is available (respects disallowedTools) |
| 431 | if (!isToolSearchToolAvailable(tools)) { |
| 432 | logForDebugging( |
| 433 | `Tool search disabled: ToolSearchTool is not available (may have been disallowed via disallowedTools).`, |
| 434 | ) |
| 435 | logModeDecision(false, 'standard', 'mcp_search_unavailable') |
| 436 | return false |
| 437 | } |
| 438 | |
| 439 | const mode = getToolSearchMode() |
| 440 | |
| 441 | switch (mode) { |
| 442 | case 'tst': |
| 443 | logModeDecision(true, mode, 'tst_enabled') |
| 444 | return true |
no test coverage detected