* Strip tool search-specific fields from messages before sending for token counting. * This removes 'caller' from tool_use blocks and 'tool_reference' from tool_result content. * These fields are only valid with the tool search beta and will cause errors otherwise. * * Note: We use 'as unknown a
( messages: Anthropic.Beta.Messages.BetaMessageParam[], )
| 64 | * but at runtime these fields may exist from API responses when tool search was enabled. |
| 65 | */ |
| 66 | function stripToolSearchFieldsFromMessages( |
| 67 | messages: Anthropic.Beta.Messages.BetaMessageParam[], |
| 68 | ): Anthropic.Beta.Messages.BetaMessageParam[] { |
| 69 | return messages.map(message => { |
| 70 | if (!Array.isArray(message.content)) { |
| 71 | return message |
| 72 | } |
| 73 | |
| 74 | const normalizedContent = message.content.map(block => { |
| 75 | // Strip 'caller' from tool_use blocks (assistant messages) |
| 76 | if (block.type === 'tool_use') { |
| 77 | // Destructure to exclude any extra fields like 'caller' |
| 78 | const toolUse = |
| 79 | block as Anthropic.Beta.Messages.BetaToolUseBlockParam & { |
| 80 | caller?: unknown |
| 81 | } |
| 82 | return { |
| 83 | type: 'tool_use' as const, |
| 84 | id: toolUse.id, |
| 85 | name: toolUse.name, |
| 86 | input: toolUse.input, |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | // Strip tool_reference blocks from tool_result content (user messages) |
| 91 | if (block.type === 'tool_result') { |
| 92 | const toolResult = |
| 93 | block as Anthropic.Beta.Messages.BetaToolResultBlockParam |
| 94 | if (Array.isArray(toolResult.content)) { |
| 95 | const filteredContent = (toolResult.content as unknown[]).filter( |
| 96 | c => !isToolReferenceBlock(c), |
| 97 | ) as typeof toolResult.content |
| 98 | |
| 99 | if (filteredContent.length === 0) { |
| 100 | return { |
| 101 | ...toolResult, |
| 102 | content: [{ type: 'text' as const, text: '[tool references]' }], |
| 103 | } |
| 104 | } |
| 105 | if (filteredContent.length !== toolResult.content.length) { |
| 106 | return { |
| 107 | ...toolResult, |
| 108 | content: filteredContent, |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return block |
| 115 | }) |
| 116 | |
| 117 | return { |
| 118 | ...message, |
| 119 | content: normalizedContent, |
| 120 | } |
| 121 | }) |
| 122 | } |
| 123 |
no test coverage detected