返回 DeepSeek-Reasonix
replay_compatibility.go
根目录 / internal / provider / anthropic / replay_compatibility.go
1 package anthropic
2
3 import (
4 "strings"
5
6 "reasonix/internal/provider"
7 )
8
9 func (c *client) requiresReceivedReasoning(m provider.Message) bool {
10 if !c.replaysReceivedThinking() {
11 return false
12 }
13 observed := m.ReasoningContent != "" || m.ReasoningSignature != ""
14 for _, b := range m.ThinkingBlocks {
15 observed = observed || b.Thinking != "" || b.Signature != "" || b.Data != ""
16 }
17 unsafe := m.ReasoningStatus == "in_progress" || m.ReasoningStatus == "incomplete"
18 switch m.ReasoningState {
19 case "", provider.ReasoningEmpty, provider.ReasoningComplete:
20 default:
21 unsafe = true
22 }
23 if !c.nativeAnthropic {
24 // Receiving the Anthropic envelope is not evidence that a gateway
25 // requires Claude signatures. Preserve its actual blocks instead.
26 return observed || unsafe
27 }
28 activity := len(m.ToolCalls) > 0 || len(m.ServerSearch) > 0
29 return c.replaysSignedThinking() && (observed || unsafe || activity)
30 }
31
32 // ConvertReasoningReplay uses Anthropic's ordinary assistant-text representation
33 // only for complete, unsigned, non-tool history. Tool continuations still need
34 // their original proof; DeepSeek and unknown gateways keep their own blocks.
35 func (c *client) ConvertReasoningReplay(m provider.Message) (provider.Message, bool) {
36 if !c.nativeAnthropic || c.deepseek || !c.replaysSignedThinking() ||
37 m.Role != provider.RoleAssistant || len(m.ToolCalls) > 0 || len(m.ServerSearch) > 0 ||
38 m.ReasoningSignature != "" || len(m.ResponsesItems) > 0 {
39 return m, false
40 }
41 var text []string
42 if len(m.ThinkingBlocks) > 0 {
43 for _, b := range m.ThinkingBlocks {
44 if b.Type != "thinking" || b.Signature != "" || b.Data != "" {
45 return m, false
46 }
47 if b.Thinking != "" {
48 text = append(text, b.Thinking)
49 }
50 }
51 } else if m.ReasoningContent != "" {
52 text = append(text, m.ReasoningContent)
53 }
54 if len(text) == 0 || strings.TrimSpace(strings.Join(text, "")) == "" {
55 return m, false
56 }
57 if m.Content != "" {
58 text = append(text, m.Content)
59 }
60 m.Content = strings.Join(text, "\n\n")
61 m.ReasoningContent, m.ReasoningSignature, m.ReasoningID, m.ReasoningStatus = "", "", "", ""
62 m.ReasoningState, m.ThinkingBlocks = "", nil
63 return m, true
64 }
65
65 lines GO