返回 DeepSeek-Reasonix
replay_compatibility.go
根目录 / internal / provider / replay_compatibility.go
1 package provider
2
3 import "reasonix/internal/nilutil"
4
5 // ReasoningReplayConverter is an adapter-owned, loss-aware request-view
6 // conversion. It must not mutate the input or fabricate provider proof. A true
7 // result means the converted message can be sent without protocol recovery.
8 type ReasoningReplayConverter interface {
9 ConvertReasoningReplay(Message) (Message, bool)
10 }
11
12 func completeReplayEvidence(m Message) bool {
13 if m.ReasoningStatus == "incomplete" || m.ReasoningStatus == "in_progress" {
14 return false
15 }
16 switch m.ReasoningState {
17 case "", ReasoningEmpty, ReasoningComplete:
18 return true
19 default:
20 return false
21 }
22 }
23
24 func compatibleReplayMessage(p Provider, m Message) (Message, bool) {
25 if nilutil.IsNil(p) || m.Role != RoleAssistant || !completeReplayEvidence(m) {
26 return m, false
27 }
28 converter, ok := p.(ReasoningReplayConverter)
29 if !ok {
30 return m, false
31 }
32 return converter.ConvertReasoningReplay(m)
33 }
34
35 // projectCompatibleReplay preserves the canonical history and allocates only
36 // when an adapter actually converts an otherwise unsupported historical block.
37 func projectCompatibleReplay(p Provider, msgs []Message, prefix int) ([]Message, bool) {
38 work := msgs
39 changed := false
40 for i, m := range msgs[:prefix] {
41 converted, ok := compatibleReplayMessage(p, m)
42 if !ok {
43 continue
44 }
45 if !changed {
46 work = append([]Message(nil), msgs...)
47 changed = true
48 }
49 work[i] = converted
50 }
51 return work, changed
52 }
53
53 lines GO