mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-23 10:57:44 +08:00
feat: expand DSML tool-call alias and fence handling
Add support for DSML wrapper aliases (<dsml|tool_calls>, <|tool_calls>, <|tool_calls>) alongside canonical XML. Normalize mixed DSML/canonical tags instead of rejecting them. Add tilde fence (~~~) support, fix nested fence and unclosed fence handling, support CDATA-protected fence content, and skip prose mentions when scanning for real tool blocks. Mirror all changes between Go and Node.js runtimes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -93,7 +93,11 @@ func filterToolCallsDetailed(parsed []ParsedToolCall) ([]ParsedToolCall, []strin
|
||||
|
||||
func looksLikeToolCallSyntax(text string) bool {
|
||||
lower := strings.ToLower(text)
|
||||
return strings.Contains(lower, "<|dsml|tool_calls") || strings.Contains(lower, "<tool_calls")
|
||||
return strings.Contains(lower, "<|dsml|tool_calls") ||
|
||||
strings.Contains(lower, "<dsml|tool_calls") ||
|
||||
strings.Contains(lower, "<|tool_calls") ||
|
||||
strings.Contains(lower, "<|tool_calls") ||
|
||||
strings.Contains(lower, "<tool_calls")
|
||||
}
|
||||
|
||||
func stripFencedCodeBlocks(text string) string {
|
||||
@@ -107,6 +111,9 @@ func stripFencedCodeBlocks(text string) string {
|
||||
inFence := false
|
||||
fenceMarker := ""
|
||||
inCDATA := false
|
||||
// Track builder length when a fence opens so we can preserve content
|
||||
// collected before the unclosed fence.
|
||||
beforeFenceLen := 0
|
||||
for _, line := range lines {
|
||||
if inCDATA || cdataStartsBeforeFence(line) {
|
||||
b.WriteString(line)
|
||||
@@ -118,6 +125,7 @@ func stripFencedCodeBlocks(text string) string {
|
||||
if marker, ok := parseFenceOpen(trimmed); ok {
|
||||
inFence = true
|
||||
fenceMarker = marker
|
||||
beforeFenceLen = b.Len()
|
||||
continue
|
||||
}
|
||||
b.WriteString(line)
|
||||
@@ -131,6 +139,12 @@ func stripFencedCodeBlocks(text string) string {
|
||||
}
|
||||
|
||||
if inFence {
|
||||
// Unclosed fence: preserve content that was collected before the
|
||||
// fence started rather than dropping everything.
|
||||
result := b.String()
|
||||
if beforeFenceLen > 0 && beforeFenceLen <= len(result) {
|
||||
return result[:beforeFenceLen]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return b.String()
|
||||
|
||||
Reference in New Issue
Block a user