(messages: Message[])
| 864 | * This prevents API errors when sending messages with orphaned tool calls. |
| 865 | */ |
| 866 | export function filterIncompleteToolCalls(messages: Message[]): Message[] { |
| 867 | // Build a set of tool use IDs that have results |
| 868 | const toolUseIdsWithResults = new Set<string>() |
| 869 | |
| 870 | for (const message of messages) { |
| 871 | if (message?.type === 'user') { |
| 872 | const userMessage = message as UserMessage |
| 873 | const content = userMessage.message.content |
| 874 | if (Array.isArray(content)) { |
| 875 | for (const block of content) { |
| 876 | if (block.type === 'tool_result' && block.tool_use_id) { |
| 877 | toolUseIdsWithResults.add(block.tool_use_id) |
| 878 | } |
| 879 | } |
| 880 | } |
| 881 | } |
| 882 | } |
| 883 | |
| 884 | // Filter out assistant messages that contain tool calls without results |
| 885 | return messages.filter(message => { |
| 886 | if (message?.type === 'assistant') { |
| 887 | const assistantMessage = message as AssistantMessage |
| 888 | const content = assistantMessage.message.content |
| 889 | if (Array.isArray(content)) { |
| 890 | // Check if this assistant message has any tool uses without results |
| 891 | const hasIncompleteToolCall = content.some( |
| 892 | block => |
| 893 | block.type === 'tool_use' && |
| 894 | block.id && |
| 895 | !toolUseIdsWithResults.has(block.id), |
| 896 | ) |
| 897 | // Exclude messages with incomplete tool calls |
| 898 | return !hasIncompleteToolCall |
| 899 | } |
| 900 | } |
| 901 | // Keep all non-assistant messages and assistant messages without tool calls |
| 902 | return true |
| 903 | }) |
| 904 | } |
| 905 | |
| 906 | async function getAgentSystemPrompt( |
| 907 | agentDefinition: AgentDefinition, |
no test coverage detected