返回 DeepSeek-Reasonix
composer_profile.go
根目录 / internal / serve / composer_profile.go
1 package serve
2
3 import (
4 "encoding/json"
5 "net/http"
6 "strings"
7
8 "reasonix/internal/control"
9 )
10
11 // composerProfile applies every controller-facing composer axis in one request.
12 // bindMu serializes it with submit and controller/session replacement, while the
13 // controller commits durable Goal state before the infallible runtime axes.
14 func (s *Server) composerProfile(w http.ResponseWriter, r *http.Request) {
15 var body struct {
16 CollaborationMode string `json:"collaborationMode"`
17 ToolApprovalMode string `json:"toolApprovalMode"`
18 Goal string `json:"goal"`
19 ExpectedPermissionRevision *uint64 `json:"expectedPermissionRevision,omitempty"`
20 }
21 if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
22 http.Error(w, "bad body", http.StatusBadRequest)
23 return
24 }
25 collaborationMode := strings.ToLower(strings.TrimSpace(body.CollaborationMode))
26 switch collaborationMode {
27 case "normal", "plan", "goal":
28 default:
29 http.Error(w, "collaboration mode must be normal, plan, or goal", http.StatusBadRequest)
30 return
31 }
32 s.bindMu.Lock()
33 defer s.bindMu.Unlock()
34 if !s.validateExpectedSessionLocked(w, r) {
35 return
36 }
37 var drained []string
38 var err error
39 if ctrl, ok := s.ctl().(*control.Controller); ok && ctrl.UsesExclusiveSession() {
40 if _, bound := ctrl.SessionRef(); !bound {
41 if body.ExpectedPermissionRevision != nil {
42 drained, err = ctrl.ApplyComposerProfileAt(collaborationMode == "plan", body.ToolApprovalMode, body.Goal, *body.ExpectedPermissionRevision)
43 } else {
44 drained, err = ctrl.ApplyComposerProfile(collaborationMode == "plan", body.ToolApprovalMode, body.Goal)
45 }
46 } else {
47 revision := ctrl.PermissionSnapshot().Revision
48 if body.ExpectedPermissionRevision != nil {
49 revision = *body.ExpectedPermissionRevision
50 }
51 drained, err = ctrl.ApplyComposerProfileAtDurable(r.Context(), collaborationMode == "plan", body.ToolApprovalMode, body.Goal, revision)
52 }
53 } else if body.ExpectedPermissionRevision != nil {
54 ctrl, ok := s.ctl().(*control.Controller)
55 if !ok {
56 http.Error(w, "revision-checked permission profiles are unavailable", http.StatusNotImplemented)
57 return
58 }
59 drained, err = ctrl.ApplyComposerProfileAt(collaborationMode == "plan", body.ToolApprovalMode, body.Goal, *body.ExpectedPermissionRevision)
60 } else {
61 drained, err = s.ctl().ApplyComposerProfile(collaborationMode == "plan", body.ToolApprovalMode, body.Goal)
62 }
63 if err != nil {
64 http.Error(w, err.Error(), http.StatusServiceUnavailable)
65 return
66 }
67 w.Header().Set("Content-Type", "application/json")
68 _ = json.NewEncoder(w).Encode(map[string]any{"drainedApprovalIDs": drained})
69 }
70
70 lines GO