Skip to content

Commit 96bda53

Browse files
committed
feat: handle partial/malformed tool call detection for claude-code
1 parent 7eb21f9 commit 96bda53

1 file changed

Lines changed: 36 additions & 10 deletions

File tree

lib/msgfmt/format_tool_call.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,55 @@
11
package msgfmt
22

33
import (
4+
"fmt"
45
"strings"
56
)
67

8+
type toolCallRange struct {
9+
start int
10+
end int
11+
malformed bool
12+
}
13+
714
func removeClaudeReportTaskToolCall(msg string) (string, []string) {
815
msg = "\n" + msg // This handles the case where the message starts with a tool call
916

1017
// Remove all tool calls that start with `● coder - coder_report_task (MCP)`
1118
lines := strings.Split(msg, "\n")
1219

1320
toolCallStartIdx := -1
21+
newLineAfterToolCall := -1
1422

1523
// Store all tool call start and end indices [[start, end], ...]
16-
var toolCallIdxs [][]int
24+
var toolCallIdxs []toolCallRange
1725

1826
for i := 1; i < len(lines)-1; i++ {
1927
prevLine := strings.TrimSpace(lines[i-1])
20-
line := strings.TrimSpace(lines[i])
28+
line := strings.Trim(strings.TrimSpace(lines[i]), "\n")
2129
nextLine := strings.TrimSpace(lines[i+1])
2230

2331
if strings.Contains(line, "coder - coder_report_task (MCP)") {
2432
toolCallStartIdx = i
25-
} else if toolCallStartIdx != -1 && line == "\"message\": \"Thanks for reporting!\"" && nextLine == "}" && strings.HasSuffix(prevLine, "{") {
26-
// Store [start, end] pair
27-
toolCallIdxs = append(toolCallIdxs, []int{toolCallStartIdx, min(len(lines), i+2)})
33+
} else if toolCallStartIdx != -1 {
34+
if line == "\"message\": \"Thanks for reporting!\"" && nextLine == "}" && strings.HasSuffix(prevLine, "{") {
35+
// Store [start, end] pair
36+
toolCallIdxs = append(toolCallIdxs, toolCallRange{toolCallStartIdx, min(len(lines), i+2), false})
37+
38+
// Reset to find the next tool call
39+
toolCallStartIdx = -1
40+
newLineAfterToolCall = -1
41+
} else if len(line) == 0 {
42+
newLineAfterToolCall = i + 1
43+
}
44+
}
45+
}
2846

29-
// Reset to find the next tool call
30-
toolCallStartIdx = -1
47+
// Handle the malformed/partially rendered tool_calls
48+
if toolCallStartIdx != -1 {
49+
if newLineAfterToolCall != -1 {
50+
toolCallIdxs = append(toolCallIdxs, toolCallRange{toolCallStartIdx, newLineAfterToolCall, true})
51+
} else {
52+
toolCallIdxs = append(toolCallIdxs, toolCallRange{toolCallStartIdx, len(lines), true})
3153
}
3254
}
3355

@@ -40,10 +62,14 @@ func removeClaudeReportTaskToolCall(msg string) (string, []string) {
4062

4163
// Remove tool calls from the message
4264
for i := len(toolCallIdxs) - 1; i >= 0; i-- {
43-
idxPair := toolCallIdxs[i]
44-
start, end := idxPair[0], idxPair[1]
65+
start, end := toolCallIdxs[i].start, toolCallIdxs[i].end
4566

46-
toolCallMessages = append(toolCallMessages, strings.Join(lines[start:end], "\n"))
67+
// If the toolCall is malformed, we don't want to log it
68+
if !toolCallIdxs[i].malformed {
69+
// [DEBUG] print, will remove before merge
70+
fmt.Printf("Found malformed toolCall with newLineAfterToolCall, start: %d, end: %d, toolcall: %s", start, end, strings.Join(lines[start:end], "\n"))
71+
toolCallMessages = append(toolCallMessages, strings.Join(lines[start:end], "\n"))
72+
}
4773

4874
lines = append(lines[:start], lines[end:]...)
4975
}

0 commit comments

Comments
 (0)