Skip to content

Commit 1a7a3c0

Browse files
authored
feat: handle partial/malformed tool call detection for claude-code (#184)
1 parent c8502fb commit 1a7a3c0

File tree

3 files changed

+43
-10
lines changed

3 files changed

+43
-10
lines changed

lib/msgfmt/format_tool_call.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,51 @@ import (
44
"strings"
55
)
66

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

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

1319
toolCallStartIdx := -1
20+
newLineAfterToolCall := -1
1421

1522
// Store all tool call start and end indices [[start, end], ...]
16-
var toolCallIdxs [][]int
23+
var toolCallIdxs []toolCallRange
1724

1825
for i := 1; i < len(lines)-1; i++ {
1926
prevLine := strings.TrimSpace(lines[i-1])
20-
line := strings.TrimSpace(lines[i])
27+
line := strings.Trim(strings.TrimSpace(lines[i]), "\n")
2128
nextLine := strings.TrimSpace(lines[i+1])
2229

2330
if strings.Contains(line, "coder - coder_report_task (MCP)") {
2431
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)})
32+
} else if toolCallStartIdx != -1 {
33+
if line == "\"message\": \"Thanks for reporting!\"" && nextLine == "}" && strings.HasSuffix(prevLine, "{") {
34+
// Store [start, end] pair
35+
toolCallIdxs = append(toolCallIdxs, toolCallRange{toolCallStartIdx, min(len(lines), i+2), false})
36+
37+
// Reset to find the next tool call
38+
toolCallStartIdx = -1
39+
newLineAfterToolCall = -1
40+
} else if len(line) == 0 {
41+
newLineAfterToolCall = i + 1
42+
}
43+
}
44+
}
2845

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

@@ -40,10 +61,12 @@ func removeClaudeReportTaskToolCall(msg string) (string, []string) {
4061

4162
// Remove tool calls from the message
4263
for i := len(toolCallIdxs) - 1; i >= 0; i-- {
43-
idxPair := toolCallIdxs[i]
44-
start, end := idxPair[0], idxPair[1]
64+
start, end := toolCallIdxs[i].start, toolCallIdxs[i].end
4565

46-
toolCallMessages = append(toolCallMessages, strings.Join(lines[start:end], "\n"))
66+
// If the toolCall is malformed, we don't want to log it
67+
if !toolCallIdxs[i].malformed {
68+
toolCallMessages = append(toolCallMessages, strings.Join(lines[start:end], "\n"))
69+
}
4770

4871
lines = append(lines[:start], lines[end:]...)
4972
}

lib/msgfmt/testdata/format/claude/remove-task-tool-call/expected.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@
4040
Open the HTML file in your web browser and use the arrow keys
4141
to move the snake. Collect the red food to grow and increase
4242
your score!
43+
44+
45+
Above is a malformed tool call message

lib/msgfmt/testdata/format/claude/remove-task-tool-call/msg.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@
7272
"message": "Thanks for reporting!"
7373
}
7474

75+
coder - coder_report_task (MCP)(summary: "Snake game created
76+
successfully at snake-game.html",
77+
link: "file:///home/coder/snake-ga
78+
me.html", state: "working")
79+
80+
Above is a malformed tool call message
81+
7582

7683
───────────────────────────────────────────────────────────────────
7784

0 commit comments

Comments
 (0)