| 1 | package responses |
| 2 | |
| 3 | import ( |
| 4 | "encoding/json" |
| 5 | "net/http" |
| 6 | "net/http/httptest" |
| 7 | "reasonix/internal/provider" |
| 8 | "reflect" |
| 9 | "strings" |
| 10 | "testing" |
| 11 | ) |
| 12 | |
| 13 | func TestTerminalReasoningSnapshotReplacesEarlierOpaqueItem(t *testing.T) { |
| 14 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { |
| 15 | writeEvents(w, |
| 16 | `{"type":"response.output_item.done","item":{"id":"rs_1","type":"reasoning","status":"completed","summary":[]}}`, |
| 17 | `{"type":"response.completed","response":{"id":"resp_1","output":[{"id":"rs_1","type":"reasoning","status":"completed","summary":[],"encrypted_content":"opaque-final"}],"usage":{"input_tokens":4,"output_tokens":2,"total_tokens":6}}}`, |
| 18 | ) |
| 19 | })) |
| 20 | defer server.Close() |
| 21 | chunks := collect(t, New(Config{Name: "compatible", APIKey: "key", BaseURL: server.URL, Model: "reasoner", Mode: "stateless"}), provider.Request{Messages: []provider.Message{{Role: provider.RoleUser, Content: "hi"}}}) |
| 22 | var items []json.RawMessage |
| 23 | for _, chunk := range chunks { |
| 24 | if chunk.Type == provider.ChunkResponsesItem { |
| 25 | items = append(items, chunk.ResponsesItem) |
| 26 | } |
| 27 | } |
| 28 | if len(items) != 1 || !strings.Contains(string(items[0]), "opaque-final") { |
| 29 | t.Fatalf("terminal items=%s", items) |
| 30 | } |
| 31 | input := messagesToInput([]provider.Message{{Role: provider.RoleAssistant, ReasoningContent: "legacy summary", ResponsesItems: items}}, false, false, true) |
| 32 | raw, _ := json.Marshal(input) |
| 33 | if strings.Count(string(raw), `"type":"reasoning"`) != 1 || !strings.Contains(string(raw), "opaque-final") || strings.Contains(string(raw), "legacy summary") { |
| 34 | t.Fatalf("replay=%s", raw) |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | func TestDeepSeekPlainReasoningItemRemainsUnmodified(t *testing.T) { |
| 39 | raw := json.RawMessage(`{"id":"rs_1","type":"reasoning","status":"completed","content":[{"type":"reasoning_text","text":"original"}]}`) |
| 40 | input := messagesToInput([]provider.Message{{Role: provider.RoleAssistant, ResponsesItems: []json.RawMessage{raw}}}, false, false, false) |
| 41 | encoded, _ := json.Marshal(input[0]) |
| 42 | var got, want any |
| 43 | _ = json.Unmarshal(encoded, &got) |
| 44 | _ = json.Unmarshal(raw, &want) |
| 45 | if !reflect.DeepEqual(got, want) { |
| 46 | t.Fatalf("got=%s want=%s", encoded, raw) |
| 47 | } |
| 48 | } |
| 49 |