返回 DeepSeek-Reasonix
model_application_submit.go
根目录 / desktop / model_application_submit.go
1 package main
2
3 import (
4 "fmt"
5
6 "reasonix/internal/control"
7 "reasonix/internal/event"
8 )
9
10 // StartTurnWithModelApplication is an additive host entry point. The choice is
11 // admission metadata, never part of the model input or submission fingerprint.
12 func (a *App) StartTurnWithModelApplication(tabID, submissionID string, req control.SubmissionRequest, choice control.ModelApplicationChoice) (TurnStartView, error) {
13 return a.startModelApplicationTurn(tabID, submissionID, req, &choice, nil)
14 }
15
16 func (a *App) startModelApplicationTurn(tabID, submissionID string, req control.SubmissionRequest, choice *control.ModelApplicationChoice, target *attachmentTarget) (TurnStartView, error) {
17 if submissionID == "" {
18 return TurnStartView{}, fmt.Errorf("submissionId is required")
19 }
20 req.ID = submissionID
21 if receipt, found, err := a.knownSubmissionReceipt(tabID, req); found || err != nil {
22 return TurnStartView{TurnID: receipt.TurnID, SubmissionID: submissionID, Status: event.TurnQueued, Disposition: control.SubmitTurnStarted}, err
23 }
24 admission, ctrl, err := a.beginRuntimeTurnWithModelChoice(tabID, true, false, identifiedSubmissionCheck([]string{submissionID}), choice, submissionID)
25 if err != nil {
26 return TurnStartView{}, a.submissionAdmissionError(tabID, req, err)
27 }
28 defer admission.abort()
29 c, ok := ctrl.(*control.Controller)
30 if !ok {
31 return TurnStartView{}, a.submissionAdmissionError(tabID, req, fmt.Errorf("structured submission is unsupported"))
32 }
33 if target != nil && ctrl == target.ctrl && !a.attachmentTargetCurrent(*target) {
34 return TurnStartView{}, a.submissionAdmissionError(tabID, req, fmt.Errorf("attachment target changed; please retry"))
35 }
36 if target != nil && ctrl != target.ctrl {
37 _, before, exclusiveBefore := exclusiveSessionBinding(target.ctrl)
38 _, after, exclusiveAfter := exclusiveSessionBinding(ctrl)
39 if !exclusiveBefore || !exclusiveAfter || before != after || admission.tab != target.tab {
40 return TurnStartView{}, a.submissionAdmissionError(tabID, req, fmt.Errorf("attachment target changed; please retry"))
41 }
42 }
43 prepared, err := c.PrepareSubmission(a.reqCtx(), req)
44 if err != nil {
45 return TurnStartView{}, a.submissionAdmissionError(tabID, req, err)
46 }
47 setup := func() error {
48 if req.Goal != "" {
49 if err := syncTabGoalToController(ctrl, req.Goal); err != nil {
50 return err
51 }
52 a.mu.Lock()
53 admission.tab.goal = req.Goal
54 admission.tab.toolApprovalMode = normalizeToolApprovalMode(req.ToolApprovalMode)
55 admission.tab.mode = tabModeFromAxes(false, admission.tab.toolApprovalMode == control.ToolApprovalYolo)
56 a.saveTabsLocked()
57 a.mu.Unlock()
58 ctrl.SetPlanMode(false)
59 applyTabToolApprovalModeToController(ctrl, normalizeToolApprovalMode(req.ToolApprovalMode))
60 }
61 return a.ensureTabTopicIndexedForUserTurn(admission.tab)
62 }
63 receipt, err := c.SubmitPreparedWithSetup(a.reqCtx(), prepared, setup)
64 if err != nil {
65 return TurnStartView{}, err
66 }
67 admission.finish(ctrl)
68 return TurnStartView{TurnID: receipt.TurnID, SubmissionID: submissionID, Status: event.TurnQueued, Disposition: control.SubmitTurnStarted}, nil
69 }
70
71 func validateModelApplicationChoice(ctrl control.SessionAPI, choice *control.ModelApplicationChoice) (bool, error) {
72 if choice == nil || choice.Mode == "latest" {
73 return false, nil
74 }
75 if choice.Mode != "applied_once" {
76 return false, fmt.Errorf("unsupported model application choice")
77 }
78 concrete, ok := ctrl.(*control.Controller)
79 if !ok {
80 return false, fmt.Errorf("model application choice is unsupported")
81 }
82 if err := concrete.ValidateModelApplicationChoice(*choice); err != nil {
83 return false, newModelApplicationError(ctrl, err)
84 }
85 return true, nil
86 }
87
87 lines GO