返回 DeepSeek-Reasonix
interrupted_tool_recovery.go
根目录 / internal / control / interrupted_tool_recovery.go
1 package control
2
3 import "reasonix/internal/provider"
4
5 type interruptedTailEvidence struct {
6 turnID string
7 states map[string]provider.ToolRunState
8 }
9
10 func (c *Controller) ledgerTailEvidence() *interruptedTailEvidence {
11 if c == nil || c.turnEventLedger() == nil {
12 return nil
13 }
14 o := c.turnEventLedger().OrphanRecovery()
15 if o == nil {
16 return nil
17 }
18 e := &interruptedTailEvidence{turnID: o.TurnID, states: map[string]provider.ToolRunState{}}
19 for _, t := range o.Tools {
20 if t.Started {
21 e.states[t.ID] = provider.ToolRunUnknown
22 } else {
23 e.states[t.ID] = provider.ToolRunCancelled
24 }
25 }
26 return e
27 }
28
29 func recordInterruptedAssistantRecovery(r *provider.InterruptedTurnRecovery, msgs []provider.Message, i int, evidence ...*interruptedTailEvidence) {
30 results := make(map[string]provider.Message)
31 for j := i + 1; j < len(msgs) && msgs[j].Role == provider.RoleTool && !msgs[j].LocalOnly; j++ {
32 result := msgs[j]
33 results[result.ToolCallID+"\x00"+result.Name] = result
34 }
35 for _, call := range msgs[i].ToolCalls {
36 state := provider.ToolRunUnknown
37 if result, ok := results[call.ID+"\x00"+call.Name]; ok && !provider.IsInterruptedPlaceholder(result) {
38 state = provider.ToolResultRunState(result)
39 } else if len(evidence) > 0 && evidence[0] != nil {
40 if proven, ok := evidence[0].states[call.ID]; ok {
41 state = proven
42 }
43 }
44 provider.RecordToolRecovery(r, interruptedToolSummary(call), state)
45 r.ToolCalls = append(r.ToolCalls, provider.ToolCallRecord{Identity: provider.ActionIdentity{CallID: call.ID, CanonicalTool: call.Name}, Arguments: []byte(call.Arguments), State: state})
46 }
47 }
48
48 lines GO