feat: add support for CJK angle bracket and trailing attribute separator drift in DSML tool parsing

This commit is contained in:
CJACK
2026-05-10 01:54:31 +08:00
parent 77b6d83266
commit 61d42f8b72
12 changed files with 222 additions and 35 deletions

View File

@@ -1228,3 +1228,37 @@ func TestProcessToolSieveDSMLBarePrefixVariantDoesNotLeak(t *testing.T) {
t.Fatalf("expected one tool call from DSML bare prefix variant, got %d events=%#v", toolCalls, events)
}
}
func TestProcessToolSieveCJKAngleDSMDriftDoesNotLeak(t *testing.T) {
var state State
chunks := []string{
"<DSMtool_calls>\n",
"<DSMinvoke name=\"Bash\">\n",
"<DSMparameter name=\"description\">〈![CDATA[Check tracking branch status]]〉〈/DSMparameter〉\n",
"<DSMparameter name=\"command\">〈![CDATA[git status -b --short]]〉〈/DSMparameter〉\n",
"〈/DSMinvoke〉\n",
"〈/DSMtool_calls〉",
}
var events []Event
for _, c := range chunks {
events = append(events, ProcessChunk(&state, c, []string{"Bash"})...)
}
events = append(events, Flush(&state, []string{"Bash"})...)
var textContent string
var calls []toolcall.ParsedToolCall
for _, evt := range events {
textContent += evt.Content
calls = append(calls, evt.ToolCalls...)
}
if strings.Contains(textContent, "DSM") || strings.Contains(textContent, "git status") {
t.Fatalf("CJK-angle DSM drift leaked to text: %q events=%#v", textContent, events)
}
if len(calls) != 1 {
t.Fatalf("expected one CJK-angle DSM drift tool call, got %d events=%#v", len(calls), events)
}
if calls[0].Name != "Bash" || calls[0].Input["command"] != "git status -b --short" {
t.Fatalf("unexpected CJK-angle DSM drift call: %#v", calls[0])
}
}