TestToWireParseErrorArgsStayValidJSON: when resolve() stamps _parse_error for a truncated tool call and that assistant message round-trips into the next request, toWire must still emit VALID JSON for arguments. Otherwise every later turn re-sends corrupt JSON and the backend 400s forever (session po
(t *testing.T)
| 937 | } |
| 938 | if content.String() != "AB" { |
| 939 | t.Fatalf("content = %q, want AB (slow-but-alive stream must complete)", content.String()) |
| 940 | } |
| 941 | } |
| 942 | |
| 943 | // TestToWireParseErrorArgsStayValidJSON: when resolve() stamps _parse_error for a |
| 944 | // truncated tool call and that assistant message round-trips into the next |
| 945 | // request, toWire must still emit VALID JSON for arguments. Otherwise every |
| 946 | // later turn re-sends corrupt JSON and the backend 400s forever (session |
| 947 | // poisoning). The protection is re-marshalling the parsed map, never raw bytes. |
| 948 | func TestToWireParseErrorArgsStayValidJSON(t *testing.T) { |
| 949 | msgs := []chmctx.Message{{ |
| 950 | Role: chmctx.RoleAssistant, |
| 951 | ToolCalls: []chmctx.ToolCall{{ |
| 952 | ID: "c1", |
| 953 | Name: "write_file", |
| 954 | Arguments: map[string]any{"_parse_error": "unexpected end of JSON input"}, |
| 955 | }}, |