返回 DeepSeek-Reasonix
missing_reasoning_provider_test.go
根目录 / internal / agent / missing_reasoning_provider_test.go
1 package agent
2
3 import (
4 "context"
5 "errors"
6 "sync/atomic"
7
8 "reasonix/internal/agent/testutil"
9 "reasonix/internal/provider"
10 )
11
12 type toolCallReasoningRequiredProvider struct{ *testutil.MockProvider }
13
14 func (p toolCallReasoningRequiredProvider) RequiresToolCallReasoning() bool { return true }
15 func (p toolCallReasoningRequiredProvider) AllowsEmptyReasoningFallback() bool { return true }
16
17 type configuredToolCallReasoningProvider struct {
18 *testutil.MockProvider
19 identity string
20 }
21
22 func (p configuredToolCallReasoningProvider) RequiresToolCallReasoning() bool { return true }
23 func (p configuredToolCallReasoningProvider) AllowsEmptyReasoningFallback() bool { return false }
24 func (p configuredToolCallReasoningProvider) MissingToolCallReasoningWarningIdentity() string {
25 return p.identity
26 }
27
28 type cancelMissingReasoningRetryProvider struct {
29 calls atomic.Int32
30 retryUsageSent chan struct{}
31 }
32
33 func (p *cancelMissingReasoningRetryProvider) Name() string { return "deepseek-cancel-retry" }
34 func (p *cancelMissingReasoningRetryProvider) RequiresToolCallReasoning() bool {
35 return true
36 }
37 func (p *cancelMissingReasoningRetryProvider) AllowsEmptyReasoningFallback() bool { return false }
38
39 func (p *cancelMissingReasoningRetryProvider) Stream(ctx context.Context, _ provider.Request) (<-chan provider.Chunk, error) {
40 call := p.calls.Add(1)
41 ch := make(chan provider.Chunk)
42 go func() {
43 defer close(ch)
44 send := func(chunk provider.Chunk) bool {
45 select {
46 case <-ctx.Done():
47 return false
48 case ch <- chunk:
49 return true
50 }
51 }
52 if call == 1 {
53 toolCall := provider.ToolCall{ID: "discarded", Name: "echo", Arguments: `{"text":"must not run"}`}
54 if !send(provider.Chunk{Type: provider.ChunkToolCall, ToolCall: &toolCall}) {
55 return
56 }
57 if !send(provider.Chunk{Type: provider.ChunkUsage, Usage: &provider.Usage{PromptTokens: 10, CompletionTokens: 2, TotalTokens: 12}}) {
58 return
59 }
60 send(provider.Chunk{Type: provider.ChunkDone})
61 return
62 }
63 if !send(provider.Chunk{Type: provider.ChunkUsage, Usage: &provider.Usage{PromptTokens: 10, CompletionTokens: 1, TotalTokens: 11}}) {
64 return
65 }
66 close(p.retryUsageSent)
67 <-ctx.Done()
68 }()
69 return ch, nil
70 }
71
72 type strictToolCallReasoningProvider struct{ *testutil.MockProvider }
73
74 func (strictToolCallReasoningProvider) RequiresToolCallReasoning() bool { return true }
75 func (strictToolCallReasoningProvider) AllowsEmptyReasoningFallback() bool { return false }
76
77 func isReplayFailureForTest(err error) bool {
78 var target *ReasoningReplayError
79 return errors.As(err, &target)
80 }
81
81 lines GO