( toolUse: ToolUseBlock, assistantMessage: AssistantMessage, canUseTool: CanUseToolFn, toolUseContext: ToolUseContext, )
| 335 | } |
| 336 | |
| 337 | export async function* runToolUse( |
| 338 | toolUse: ToolUseBlock, |
| 339 | assistantMessage: AssistantMessage, |
| 340 | canUseTool: CanUseToolFn, |
| 341 | toolUseContext: ToolUseContext, |
| 342 | ): AsyncGenerator<MessageUpdateLazy, void> { |
| 343 | const toolName = toolUse.name |
| 344 | // First try to find in the available tools (what the model sees) |
| 345 | let tool = findToolByName(toolUseContext.options.tools, toolName) |
| 346 | |
| 347 | // If not found, check if it's a deprecated tool being called by alias |
| 348 | // (e.g., old transcripts calling "KillShell" which is now an alias for "TaskStop") |
| 349 | // Only fall back for tools where the name matches an alias, not the primary name |
| 350 | if (!tool) { |
| 351 | const fallbackTool = findToolByName(getAllBaseTools(), toolName) |
| 352 | // Only use fallback if the tool was found via alias (deprecated name) |
| 353 | if (fallbackTool && fallbackTool.aliases?.includes(toolName)) { |
| 354 | tool = fallbackTool |
| 355 | } |
| 356 | } |
| 357 | const messageId = assistantMessage.message.id |
| 358 | const requestId = assistantMessage.requestId |
| 359 | const mcpServerType = getMcpServerType( |
| 360 | toolName, |
| 361 | toolUseContext.options.mcpClients, |
| 362 | ) |
| 363 | const mcpServerBaseUrl = getMcpServerBaseUrlFromToolName( |
| 364 | toolName, |
| 365 | toolUseContext.options.mcpClients, |
| 366 | ) |
| 367 | |
| 368 | // Check if the tool exists |
| 369 | if (!tool) { |
| 370 | const sanitizedToolName = sanitizeToolNameForAnalytics(toolName) |
| 371 | logForDebugging(`Unknown tool ${toolName}: ${toolUse.id}`) |
| 372 | logEvent('tengu_tool_use_error', { |
| 373 | error: |
| 374 | `No such tool available: ${sanitizedToolName}` as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 375 | toolName: sanitizedToolName, |
| 376 | toolUseID: |
| 377 | toolUse.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 378 | isMcp: toolName.startsWith('mcp__'), |
| 379 | queryChainId: toolUseContext.queryTracking |
| 380 | ?.chainId as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 381 | queryDepth: toolUseContext.queryTracking?.depth, |
| 382 | ...(mcpServerType && { |
| 383 | mcpServerType: |
| 384 | mcpServerType as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 385 | }), |
| 386 | ...(mcpServerBaseUrl && { |
| 387 | mcpServerBaseUrl: |
| 388 | mcpServerBaseUrl as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 389 | }), |
| 390 | ...(requestId && { |
| 391 | requestId: |
| 392 | requestId as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 393 | }), |
| 394 | ...mcpToolDetailsForAnalytics(toolName, mcpServerType, mcpServerBaseUrl), |
no test coverage detected