返回 DeepSeek-Reasonix
dispatch_generation.go
根目录 / internal / agent / dispatch_generation.go
1 package agent
2
3 import (
4 "context"
5 "encoding/json"
6 "fmt"
7
8 "reasonix/internal/provider"
9 "reasonix/internal/tool"
10 )
11
12 func (a *Agent) prepareToolBatch(ctx context.Context, calls []provider.ToolCall) error {
13 a.snapshotDispatchClasses(calls)
14 for _, c := range calls {
15 if err := a.emitFullToolDispatch(ctx, c, false); err != nil {
16 return fmt.Errorf("persist tool dispatch %s: %w", c.ID, err)
17 }
18 }
19 return nil
20 }
21
22 func (a *Agent) snapshotDispatchClasses(calls []provider.ToolCall) {
23 if a == nil || len(calls) == 0 || a.svc.tools == nil {
24 return
25 }
26 classes := make(map[string]tool.CallClass, len(calls))
27 for _, call := range calls {
28 target, _, ambiguous := a.svc.tools.ResolveCall(call.Name)
29 if target == nil || len(ambiguous) != 0 {
30 continue
31 }
32 classifier, ok := target.(tool.BatchClassifier)
33 if !ok {
34 continue
35 }
36 classes[call.ID] = classifier.ClassifyCall(json.RawMessage(call.Arguments))
37 }
38 a.turn.loop.setDispatchClasses(classes)
39 }
40
41 func (a *Agent) applyDispatchGenerationGate(plan *toolCallPlan) (toolOutcome, bool) {
42 if plan == nil || plan.tool == nil {
43 return toolOutcome{}, false
44 }
45 scheduled, ok := a.turn.loop.dispatchClass(plan.call.ID)
46 if !ok || scheduled.Generation == "" {
47 return toolOutcome{}, false
48 }
49 classifier, ok := plan.tool.(tool.BatchClassifier)
50 if !ok {
51 return toolOutcome{}, false
52 }
53 live := classifier.ClassifyCall(json.RawMessage(plan.call.Arguments))
54 if live.Generation == scheduled.Generation && live.ReadOnly == scheduled.ReadOnly && live.ParallelSafe == scheduled.ParallelSafe {
55 return toolOutcome{}, false
56 }
57 msg := "blocked: tool safety or schema generation changed after scheduling; the call was not dispatched with a stale read-only classification. Retry so Reasonix can apply the current contract."
58 return toolOutcome{output: msg, blocked: true, errMsg: firstLine(msg)}, true
59 }
60
60 lines GO