(messages: Message[])
| 545 | * @returns Set of tool names that have been discovered via tool_reference blocks |
| 546 | */ |
| 547 | export function extractDiscoveredToolNames(messages: Message[]): Set<string> { |
| 548 | const discoveredTools = new Set<string>() |
| 549 | let carriedFromBoundary = 0 |
| 550 | |
| 551 | for (const msg of messages) { |
| 552 | // Compact boundary carries the pre-compact discovered set. Inline type |
| 553 | // check rather than isCompactBoundaryMessage — utils/messages.ts imports |
| 554 | // from this file, so importing back would be circular. |
| 555 | if (msg.type === 'system' && msg.subtype === 'compact_boundary') { |
| 556 | const carried = msg.compactMetadata?.preCompactDiscoveredTools |
| 557 | if (carried) { |
| 558 | for (const name of carried) discoveredTools.add(name) |
| 559 | carriedFromBoundary += carried.length |
| 560 | } |
| 561 | continue |
| 562 | } |
| 563 | |
| 564 | // Only user messages contain tool_result blocks (responses to tool_use) |
| 565 | if (msg.type !== 'user') continue |
| 566 | |
| 567 | const content = msg.message?.content |
| 568 | if (!Array.isArray(content)) continue |
| 569 | |
| 570 | for (const block of content) { |
| 571 | // tool_reference blocks only appear inside tool_result content, specifically |
| 572 | // in results from ToolSearchTool. The API expands these references into full |
| 573 | // tool definitions in the model's context. |
| 574 | if (isToolResultBlockWithContent(block)) { |
| 575 | for (const item of block.content) { |
| 576 | if (isToolReferenceWithName(item)) { |
| 577 | discoveredTools.add(item.tool_name) |
| 578 | } |
| 579 | } |
| 580 | } |
| 581 | } |
| 582 | } |
| 583 | |
| 584 | if (discoveredTools.size > 0) { |
| 585 | logForDebugging( |
| 586 | `Dynamic tool loading: found ${discoveredTools.size} discovered tools in message history` + |
| 587 | (carriedFromBoundary > 0 |
| 588 | ? ` (${carriedFromBoundary} carried from compact boundary)` |
| 589 | : ''), |
| 590 | ) |
| 591 | } |
| 592 | |
| 593 | return discoveredTools |
| 594 | } |
| 595 | |
| 596 | export type DeferredToolsDelta = { |
| 597 | addedNames: string[] |
no test coverage detected