| 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 |