77 "strings"
88
99 "github.com/compozy/compozy/internal/api/contract"
10- "github.com/compozy/compozy/internal/store"
1110 toolspkg "github.com/compozy/compozy/internal/tools"
1211 "github.com/gin-gonic/gin"
1312)
@@ -25,7 +24,11 @@ func (h *BaseHandlers) ListTools(c *gin.Context) {
2524 h .respondError (c , http .StatusServiceUnavailable , errors .New ("tool registry is not configured" ))
2625 return
2726 }
28- scope := h .operatorToolScope (c )
27+ scope , err := h .resolveOperatorToolScope (c )
28+ if err != nil {
29+ h .respondProfileReadScopeError (c , err )
30+ return
31+ }
2932 views , err := h .Tools .List (c .Request .Context (), scope )
3033 if err != nil {
3134 h .respondToolError (c , err )
@@ -44,7 +47,12 @@ func (h *BaseHandlers) SearchTools(c *gin.Context) {
4447 h .respondError (c , http .StatusServiceUnavailable , errors .New ("tool registry is not configured" ))
4548 return
4649 }
47- scope := toolScopeFromSearch (h .operatorToolScope (c ), req )
50+ scope , err := h .resolveOperatorToolScope (c )
51+ if err != nil {
52+ h .respondProfileReadScopeError (c , err )
53+ return
54+ }
55+ scope = toolScopeFromSearch (scope , req )
4856 views , err := h .Tools .Search (c .Request .Context (), scope , toolspkg.SearchQuery {
4957 Query : req .Query ,
5058 Limit : req .Limit ,
@@ -66,7 +74,12 @@ func (h *BaseHandlers) GetTool(c *gin.Context) {
6674 if ! ok {
6775 return
6876 }
69- view , err := h .Tools .Get (c .Request .Context (), h .operatorToolScope (c ), id )
77+ scope , err := h .resolveOperatorToolScope (c )
78+ if err != nil {
79+ h .respondProfileReadScopeError (c , err )
80+ return
81+ }
82+ view , err := h .Tools .Get (c .Request .Context (), scope , id )
7083 if err != nil {
7184 h .respondToolError (c , err )
7285 return
@@ -95,7 +108,11 @@ func (h *BaseHandlers) CreateToolApproval(c *gin.Context) {
95108 ))
96109 return
97110 }
98- scope := h .operatorToolScope (c )
111+ scope , err := h .resolveOperatorToolScope (c )
112+ if err != nil {
113+ h .respondProfileReadScopeError (c , err )
114+ return
115+ }
99116 effectiveScope , err := approvalScopeFromRequest (scope , req )
100117 if err != nil {
101118 h .respondToolError (c , err )
@@ -147,7 +164,11 @@ func (h *BaseHandlers) InvokeTool(c *gin.Context) {
147164 ))
148165 return
149166 }
150- scope := h .operatorToolScope (c )
167+ scope , err := h .resolveOperatorToolScope (c )
168+ if err != nil {
169+ h .respondProfileReadScopeError (c , err )
170+ return
171+ }
151172 scope .SessionID = firstNonEmpty (req .SessionID , scope .SessionID )
152173 scope .WorkspaceID = firstNonEmpty (req .WorkspaceID , scope .WorkspaceID )
153174 scope .AgentName = firstNonEmpty (req .AgentName , scope .AgentName )
@@ -234,39 +255,6 @@ func (h *BaseHandlers) SearchSessionTools(c *gin.Context) {
234255 c .JSON (http .StatusOK , contract.ToolsResponse {Tools : ToolPayloadsFromViews (views )})
235256}
236257
237- // ListToolsets returns named toolsets with expansion diagnostics.
238- func (h * BaseHandlers ) ListToolsets (c * gin.Context ) {
239- if h .Toolsets == nil {
240- h .respondError (c , http .StatusServiceUnavailable , errors .New ("toolset registry is not configured" ))
241- return
242- }
243- views , err := h .Toolsets .ListToolsets (c .Request .Context (), h .operatorToolScope (c ))
244- if err != nil {
245- h .respondToolError (c , err )
246- return
247- }
248- c .JSON (http .StatusOK , contract.ToolsetsResponse {Toolsets : ToolsetPayloadsFromViews (views )})
249- }
250-
251- // GetToolset returns one named toolset with expansion diagnostics.
252- func (h * BaseHandlers ) GetToolset (c * gin.Context ) {
253- if h .Toolsets == nil {
254- h .respondError (c , http .StatusServiceUnavailable , errors .New ("toolset registry is not configured" ))
255- return
256- }
257- id := toolspkg .ToolsetID (strings .TrimSpace (c .Param ("id" )))
258- if err := id .Validate (); err != nil {
259- h .respondToolError (c , err )
260- return
261- }
262- view , err := h .Toolsets .GetToolset (c .Request .Context (), h .operatorToolScope (c ), id )
263- if err != nil {
264- h .respondToolError (c , err )
265- return
266- }
267- c .JSON (http .StatusOK , contract.ToolsetResponse {Toolset : ToolsetPayloadFromView (view )})
268- }
269-
270258// ToolPayloadsFromViews converts registry views into public DTOs.
271259func ToolPayloadsFromViews (views []toolspkg.ToolView ) []contract.ToolPayload {
272260 payloads := make ([]contract.ToolPayload , 0 , len (views ))
@@ -423,17 +411,6 @@ func (h *BaseHandlers) toolIDParam(c *gin.Context) (toolspkg.ToolID, bool) {
423411 return id , true
424412}
425413
426- // operatorToolScope builds privileged projections from query parameters only.
427- func (h * BaseHandlers ) operatorToolScope (c * gin.Context ) toolspkg.Scope {
428- return toolspkg.Scope {
429- ProfileID : store .DefaultProfileID ,
430- WorkspaceID : strings .TrimSpace (firstNonEmpty (c .Query ("workspace_id" ), c .Query ("workspace" ))),
431- SessionID : strings .TrimSpace (c .Query ("session_id" )),
432- AgentName : strings .TrimSpace (c .Query ("agent_name" )),
433- Operator : true ,
434- }
435- }
436-
437414// sessionToolScope anchors session projections to the resolved route workspace and session IDs.
438415func (h * BaseHandlers ) sessionToolScope (c * gin.Context , workspaceID string , sessionID string ) toolspkg.Scope {
439416 return toolspkg.Scope {
0 commit comments