TestReasoningChunksAreEmitted: reasoning models stream chain-of-thought in `delta.reasoning`. The decoder must surface these as EventReasoning (else the UI freezes for the whole reasoning phase) and must NOT fold them into the assistant content: reasoning has no business in history.
(t *testing.T)
| 593 | t.Fatalf("error should include status and message: %v", evs[0].Err) |
| 594 | } |
| 595 | if strings.Contains(evs[0].Err.Error(), `{"error"`) { |
| 596 | t.Fatalf("raw envelope JSON must not leak through to the user: %v", evs[0].Err) |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | // TestReasoningChunksAreEmitted: reasoning models stream chain-of-thought in |
| 601 | // `delta.reasoning`. The decoder must surface these as EventReasoning (else the |
| 602 | // UI freezes for the whole reasoning phase) and must NOT fold them into the |
| 603 | // assistant content: reasoning has no business in history. |
| 604 | func TestReasoningChunksAreEmitted(t *testing.T) { |
| 605 | chunks := []string{ |
| 606 | `{"choices":[{"delta":{"reasoning":"Hmm"},"finish_reason":null}]}`, |
| 607 | `{"choices":[{"delta":{"reasoning":" OK"},"finish_reason":null}]}`, |
| 608 | `{"choices":[{"delta":{"content":"hi"},"finish_reason":null}]}`, |
| 609 | `{"choices":[{"delta":{},"finish_reason":"stop"}],"usage":{"completion_tokens":3}}`, |
| 610 | } |
| 611 | srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 612 | sseOK(w, chunks) |
| 613 | })) |
| 614 | defer srv.Close() |
| 615 | |
| 616 | evs := collect(New(srv.URL, "m", "").Chat(context.Background(), nil, nil)) |
| 617 | var reasoning, content string |
| 618 | var done Event |
| 619 | for _, e := range evs { |
| 620 | switch e.Kind { |
| 621 | case EventReasoning: |
| 622 | reasoning += e.Content |
| 623 | case EventContent: |
| 624 | content += e.Content |
| 625 | case EventDone: |
| 626 | done = e |
| 627 | } |
| 628 | } |
| 629 | if reasoning != "Hmm OK" { |
| 630 | t.Fatalf("want reasoning %q, got %q", "Hmm OK", reasoning) |
| 631 | } |
| 632 | if content != "hi" { |
| 633 | t.Fatalf("want content %q, got %q", "hi", content) |
| 634 | } |
| 635 | if done.Final == nil || done.Final.Content != "hi" { |