mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-06 17:35:30 +08:00
- Add shared ToolMarkupTag scanner (toolcalls_scan.go) replacing hardcoded alias tables - Support DSML collapsed tag names (<DSMLtool_calls>, <DSMLinvoke>, <DSMLparameter>) - Parse JSON literal values from parameter bodies (123→number, true→bool, null) - Recover unclosed CDATA in final parse/flush via SanitizeLooseCDATA - Align Go and Node implementations (scanToolMarkupTagAt, findMatchingToolMarkupClose) - Reject bare <invoke> as unsupported syntax, only tool_calls wrapper triggers tool path - Update API.md and toolcall-semantics.md documentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
55 lines
1.1 KiB
Go
55 lines
1.1 KiB
Go
package toolcall
|
|
|
|
import "strings"
|
|
|
|
func normalizeDSMLToolCallMarkup(text string) (string, bool) {
|
|
if text == "" {
|
|
return "", true
|
|
}
|
|
hasAliasLikeMarkup, _ := ContainsToolMarkupSyntaxOutsideIgnored(text)
|
|
if !hasAliasLikeMarkup {
|
|
return text, true
|
|
}
|
|
return rewriteDSMLToolMarkupOutsideIgnored(text), true
|
|
}
|
|
|
|
func rewriteDSMLToolMarkupOutsideIgnored(text string) string {
|
|
if text == "" {
|
|
return ""
|
|
}
|
|
lower := strings.ToLower(text)
|
|
var b strings.Builder
|
|
b.Grow(len(text))
|
|
for i := 0; i < len(text); {
|
|
next, advanced, blocked := skipXMLIgnoredSection(lower, i)
|
|
if blocked {
|
|
b.WriteString(text[i:])
|
|
break
|
|
}
|
|
if advanced {
|
|
b.WriteString(text[i:next])
|
|
i = next
|
|
continue
|
|
}
|
|
tag, ok := scanToolMarkupTagAt(text, i)
|
|
if !ok {
|
|
b.WriteByte(text[i])
|
|
i++
|
|
continue
|
|
}
|
|
if tag.DSMLLike {
|
|
b.WriteByte('<')
|
|
if tag.Closing {
|
|
b.WriteByte('/')
|
|
}
|
|
b.WriteString(tag.Name)
|
|
b.WriteString(text[tag.NameEnd : tag.End+1])
|
|
i = tag.End + 1
|
|
continue
|
|
}
|
|
b.WriteString(text[tag.Start : tag.End+1])
|
|
i = tag.End + 1
|
|
}
|
|
return b.String()
|
|
}
|