返回 DeepSeek-Reasonix
auxiliary_recovery.go
根目录 / internal / provider / auxiliary_recovery.go
1 package provider
2
3 import (
4 "context"
5 "errors"
6 )
7
8 // StreamAuxiliary makes one search or summarization request. It buffers the
9 // response so failed partial summaries never leak into their caller.
10 func StreamAuxiliary(ctx context.Context, p Provider, req Request) (<-chan Chunk, error) {
11 ctx = WithManagedRecovery(WithIndependentRequestAttemptCounter(ctx))
12 out := make(chan Chunk)
13 var aggregate Usage
14 go func() {
15 defer close(out)
16 send := func(c Chunk) bool {
17 select {
18 case out <- c:
19 return true
20 case <-ctx.Done():
21 return false
22 }
23 }
24 attemptCtx, cancel := context.WithCancel(ctx)
25 ch, err := Stream(attemptCtx, p, req)
26 var latest *Usage
27 var chunks []Chunk
28 complete := false
29 bytes := 0
30 if err == nil {
31 loop:
32 for {
33 select {
34 case <-ctx.Done():
35 cancel()
36 return
37 case c, ok := <-ch:
38 if !ok {
39 break loop
40 }
41 if c.Type == ChunkError {
42 err = c.Err
43 if err == nil {
44 err = errors.New("auxiliary provider error")
45 }
46 break loop
47 }
48 bytes += len(c.Text)
49 if bytes > 16*1024*1024 {
50 err = errors.New("auxiliary response exceeds local limit")
51 break loop
52 }
53 if c.Type == ChunkUsage {
54 latest = c.Usage
55 continue
56 }
57 complete = complete || c.Type == ChunkDone
58 chunks = append(chunks, c)
59 }
60 }
61 if err == nil && !complete {
62 err = StreamInterrupt(errors.New("auxiliary response ended before terminal event"), "unexpected_eof")
63 }
64 }
65 cancel()
66 if latest == nil {
67 aggregate.Unknown = true
68 }
69 if latest != nil {
70 aggregate = *latest
71 }
72 aggregate.RequestCount = RequestAttemptCount(ctx)
73 if aggregate.RequestCount == 0 {
74 aggregate.RequestCount = 1
75 }
76 if err == nil {
77 send(Chunk{Type: ChunkUsage, Usage: &aggregate})
78 for _, c := range chunks {
79 if !send(c) {
80 return
81 }
82 }
83 return
84 }
85 send(Chunk{Type: ChunkUsage, Usage: &aggregate})
86 send(Chunk{Type: ChunkError, Err: err})
87 }()
88 return out, nil
89 }
90
90 lines GO