@@ -806,6 +806,82 @@ describe("claudeCliSessionTranscriptHasOrphanedToolUse", () => {
|
806 | 806 | ).toBe(true); |
807 | 807 | }); |
808 | 808 | |
| 809 | +it("returns true when a Claude server tool use is unanswered", async () => { |
| 810 | +await writeJsonlSession("server-tool-orphan", [ |
| 811 | +{ |
| 812 | +type: "assistant", |
| 813 | +message: { |
| 814 | +role: "assistant", |
| 815 | +content: [ |
| 816 | +{ type: "server_tool_use", id: "srvtoolu_unanswered", name: "web_search", input: {} }, |
| 817 | +], |
| 818 | +}, |
| 819 | +}, |
| 820 | +]); |
| 821 | +expect( |
| 822 | +await claudeCliSessionTranscriptHasOrphanedToolUse({ |
| 823 | +sessionId: "server-tool-orphan", |
| 824 | + workspaceDir, |
| 825 | +homeDir: tmpDir, |
| 826 | +}), |
| 827 | +).toBe(true); |
| 828 | +}); |
| 829 | + |
| 830 | +it("returns false when Claude-specific tool uses have matching tool results", async () => { |
| 831 | +await writeJsonlSession("claude-specific-answered", [ |
| 832 | +{ |
| 833 | +type: "assistant", |
| 834 | +message: { |
| 835 | +role: "assistant", |
| 836 | +content: [ |
| 837 | +{ type: "server_tool_use", id: "srvtoolu_1", name: "web_search", input: {} }, |
| 838 | +{ type: "mcp_tool_use", id: "mcptoolu_1", name: "mcp__demo", input: {} }, |
| 839 | +], |
| 840 | +}, |
| 841 | +}, |
| 842 | +{ |
| 843 | +type: "user", |
| 844 | +message: { |
| 845 | +role: "user", |
| 846 | +content: [ |
| 847 | +{ type: "web_search_tool_result", tool_use_id: "srvtoolu_1", content: [] }, |
| 848 | +{ type: "mcp_tool_result", tool_use_id: "mcptoolu_1", content: "ok" }, |
| 849 | +], |
| 850 | +}, |
| 851 | +}, |
| 852 | +]); |
| 853 | +expect( |
| 854 | +await claudeCliSessionTranscriptHasOrphanedToolUse({ |
| 855 | +sessionId: "claude-specific-answered", |
| 856 | + workspaceDir, |
| 857 | +homeDir: tmpDir, |
| 858 | +}), |
| 859 | +).toBe(false); |
| 860 | +}); |
| 861 | + |
| 862 | +it("returns false when Claude hosted tool results are in the assistant message", async () => { |
| 863 | +await writeJsonlSession("assistant-hosted-tool-result", [ |
| 864 | +{ |
| 865 | +type: "assistant", |
| 866 | +message: { |
| 867 | +role: "assistant", |
| 868 | +content: [ |
| 869 | +{ type: "server_tool_use", id: "srvtoolu_inline", name: "web_search", input: {} }, |
| 870 | +{ type: "web_search_tool_result", tool_use_id: "srvtoolu_inline", content: [] }, |
| 871 | +{ type: "text", text: "found it" }, |
| 872 | +], |
| 873 | +}, |
| 874 | +}, |
| 875 | +]); |
| 876 | +expect( |
| 877 | +await claudeCliSessionTranscriptHasOrphanedToolUse({ |
| 878 | +sessionId: "assistant-hosted-tool-result", |
| 879 | + workspaceDir, |
| 880 | +homeDir: tmpDir, |
| 881 | +}), |
| 882 | +).toBe(false); |
| 883 | +}); |
| 884 | + |
809 | 885 | it("returns true when the last assistant has multiple tool_use and at least one is orphaned", async () => { |
810 | 886 | await writeJsonlSession("partial", [ |
811 | 887 | { |
|