mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-04 00:15:28 +08:00
Handle variable-length markdown fences in toolcall parser
This commit is contained in:
@@ -124,19 +124,40 @@ func stripFencedCodeBlocks(text string) string {
|
||||
}
|
||||
|
||||
func parseFenceOpen(line string) (string, bool) {
|
||||
if strings.HasPrefix(line, "```") {
|
||||
return "```", true
|
||||
if len(line) < 3 {
|
||||
return "", false
|
||||
}
|
||||
if strings.HasPrefix(line, "~~~") {
|
||||
return "~~~", true
|
||||
ch := line[0]
|
||||
if ch != '`' && ch != '~' {
|
||||
return "", false
|
||||
}
|
||||
return "", false
|
||||
count := countLeadingFenceChars(line, ch)
|
||||
if count < 3 {
|
||||
return "", false
|
||||
}
|
||||
return strings.Repeat(string(ch), count), true
|
||||
}
|
||||
|
||||
func isFenceClose(line, marker string) bool {
|
||||
if marker == "" || !strings.HasPrefix(line, marker) {
|
||||
if marker == "" {
|
||||
return false
|
||||
}
|
||||
rest := strings.TrimSpace(strings.TrimPrefix(line, marker))
|
||||
ch := marker[0]
|
||||
if line == "" || line[0] != ch {
|
||||
return false
|
||||
}
|
||||
count := countLeadingFenceChars(line, ch)
|
||||
if count < len(marker) {
|
||||
return false
|
||||
}
|
||||
rest := strings.TrimSpace(line[count:])
|
||||
return rest == ""
|
||||
}
|
||||
|
||||
func countLeadingFenceChars(line string, ch byte) int {
|
||||
count := 0
|
||||
for count < len(line) && line[count] == ch {
|
||||
count++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
@@ -474,3 +474,14 @@ func TestParseToolCallsParsesOnlyNonFencedXMLToolCall(t *testing.T) {
|
||||
t.Fatalf("expected non-fenced tool call to be parsed, got %#v", res.Calls[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseToolCallsParsesAfterFourBacktickFence(t *testing.T) {
|
||||
text := "````markdown\n```xml\n<tool_call><tool_name>read_file</tool_name><parameters>{\"path\":\"README.md\"}</parameters></tool_call>\n```\n````\n<tool_call><tool_name>search</tool_name><parameters>{\"q\":\"outside\"}</parameters></tool_call>"
|
||||
res := ParseToolCallsDetailed(text, []string{"read_file", "search"})
|
||||
if len(res.Calls) != 1 {
|
||||
t.Fatalf("expected exactly one parsed call outside four-backtick fence, got %#v", res.Calls)
|
||||
}
|
||||
if res.Calls[0].Name != "search" {
|
||||
t.Fatalf("expected non-fenced tool call to be parsed, got %#v", res.Calls[0])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user