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