TestToWireAlwaysSendsContent: silent tool results (empty stdout) must still serialize "content":"". Ollama's /v1 shim 400s if the field is absent or null.
(t *testing.T)
| 321 | // TestToWireAlwaysSendsContent: silent tool results (empty stdout) must still |
| 322 | // serialize "content":"". Ollama's /v1 shim 400s if the field is absent or null. |
| 323 | func TestToWireAlwaysSendsContent(t *testing.T) { |
| 324 | msgs := []chmctx.Message{ |
| 325 | {Role: chmctx.RoleAssistant, Content: "", ToolCalls: []chmctx.ToolCall{ |
| 326 | {ID: "c1", Name: "bash", Arguments: map[string]any{"cmd": "true"}}, |
| 327 | }}, |
| 328 | {Role: chmctx.RoleTool, Content: "", ToolCallID: "c1", ToolName: "bash"}, |
| 329 | } |
| 330 | buf, err := json.Marshal(toWire(msgs)) |
| 331 | if err != nil { |
| 332 | t.Fatalf("marshal: %v", err) |
| 333 | } |
| 334 | got := string(buf) |
| 335 | if !strings.Contains(got, `"role":"assistant","content":""`) { |
| 336 | t.Errorf("assistant with tool_calls must keep content field: %s", got) |
| 337 | } |
| 338 | if !strings.Contains(got, `"role":"tool","content":""`) { |
| 339 | t.Errorf("tool message with empty output must keep content field: %s", got) |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | // TestChatSendsStreamIncludeUsage: servers emit the usage block only when |
| 344 | // `stream_options.include_usage:true` is in the request; without it the per-turn |