Files
yhh 12b5ba6279 refactor(usecap): the use_capability proxy leaves the agent package
UseCapabilityTool, the MCP capability runtime, on-demand connects,
capability listing and search, and the argument-contract reading they
share move from internal/runtime/agent to internal/runtime/usecap. They
were already their own types rather than agent methods, and they need
nothing from the agent. usecap depends on the agent not at all; the
agent imports it.

- The two MCP checks both sides make are now tool.HasMCPDestructiveHint
  and tool.IsMCPServerAuthorized. They live in contract/tool/mcp_server.go
  beside the interfaces they read.
- The agent's call-contract gate and the proxy's hints share
  usecap.ReadArgumentContract, with its Hint and Broken.
- FilterCapabilityListResult, FilterCapabilitySearchResult,
  ParseMCPServerCapabilityID and WithContractHint are exported for the
  child registry and the dispatch path.

The integration tests that drive a real agent through the proxy stay in
agent. The runtime's own tests move to usecap. Tests that check the
proxy's judgements against agent or delegation types run as usecap_test
through export_test.go. No test was added or removed.

Baseline: usecapability.go carries its debt unchanged under the new path,
and delegation/task.go and control/controller.go each gain one import
line (-allow-widen).
2026-09-24 00:51:59 -07:00

65 lines
1.3 KiB
Go

package usecap
import (
"strings"
"reasonix/internal/ext/plugin"
)
// The live-connection view every frontend on one session observes. It is
// deliberately shared: the Host and its processes are shared at the same scope.
func (s *mcpProxySharedState) markConnected(server string) {
if s == nil {
return
}
s.mu.Lock()
defer s.mu.Unlock()
if s.connected == nil {
s.connected = map[string]bool{}
}
s.connected[server] = true
}
func (s *mcpProxySharedState) setLiveTools(server string, snap []plugin.CachedTool) {
if s == nil {
return
}
s.mu.Lock()
defer s.mu.Unlock()
if s.liveTools == nil {
s.liveTools = map[string][]plugin.CachedTool{}
}
s.liveTools[server] = snap
if s.connected == nil {
s.connected = map[string]bool{}
}
s.connected[server] = true
}
func (s *mcpProxySharedState) snapshotLiveTools() map[string][]plugin.CachedTool {
if s == nil {
return nil
}
s.mu.Lock()
defer s.mu.Unlock()
if len(s.liveTools) == 0 {
return nil
}
out := make(map[string][]plugin.CachedTool, len(s.liveTools))
for k, v := range s.liveTools {
out[k] = append([]plugin.CachedTool(nil), v...)
}
return out
}
func (s *mcpProxySharedState) clearServer(server string) {
if s == nil {
return
}
s.mu.Lock()
delete(s.connected, strings.TrimSpace(server))
delete(s.liveTools, strings.TrimSpace(server))
s.mu.Unlock()
}