返回 DeepSeek-Reasonix
responses_reasoning.go
根目录 / internal / provider / responses_reasoning.go
1 package provider
2
3 import "encoding/json"
4
5 func IsReplayableResponsesReasoning(raw json.RawMessage) bool {
6 var item struct {
7 Type string `json:"type"`
8 Status string `json:"status"`
9 Content json.RawMessage `json:"content"`
10 Summary json.RawMessage `json:"summary"`
11 Encrypted string `json:"encrypted_content"`
12 }
13 if json.Unmarshal(raw, &item) != nil || item.Type != "reasoning" || item.Status == "in_progress" || item.Status == "incomplete" {
14 return false
15 }
16 return item.Encrypted != "" || len(item.Content) > 0 && string(item.Content) != "null" || len(item.Summary) > 0 && string(item.Summary) != "null"
17 }
18
19 // UpsertResponsesItem lets a completed response replace an earlier item snapshot
20 // without replaying two copies of the same provider-issued reasoning ID.
21 func UpsertResponsesItem(items []json.RawMessage, raw json.RawMessage) []json.RawMessage {
22 var item struct {
23 ID string `json:"id"`
24 }
25 _ = json.Unmarshal(raw, &item)
26 if item.ID != "" {
27 for i, old := range items {
28 var previous struct {
29 ID string `json:"id"`
30 }
31 _ = json.Unmarshal(old, &previous)
32 if previous.ID == item.ID {
33 items[i] = append(json.RawMessage(nil), raw...)
34 return items
35 }
36 }
37 }
38 return append(items, append(json.RawMessage(nil), raw...))
39 }
40
41 // WithoutResponsesReasoning detaches opaque proofs after an extension replaces
42 // the reasoning they authenticated; server-search replay items remain intact.
43 func WithoutResponsesReasoning(items []json.RawMessage) []json.RawMessage {
44 var out []json.RawMessage
45 for _, item := range items {
46 var header struct {
47 Type string `json:"type"`
48 }
49 _ = json.Unmarshal(item, &header)
50 if header.Type != "reasoning" {
51 out = append(out, item)
52 }
53 }
54 return out
55 }
56
56 lines GO