mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
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).
51 lines
1.5 KiB
Go
51 lines
1.5 KiB
Go
// usecapability_batching.go — whether a proxied call may share a batch.
|
|
package usecap
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"reasonix/internal/contract/tool"
|
|
)
|
|
|
|
// Sequential answers for whatever this call proxies rather than for the proxy.
|
|
// Reading the directory can share a batch; an inspect may start a server and a
|
|
// decline writes the ledger, so those keep their place in provider order.
|
|
func (t *UseCapabilityTool) Sequential(ctx context.Context, args json.RawMessage) bool {
|
|
var p struct {
|
|
Action string `json:"action"`
|
|
CapabilityID string `json:"capability_id"`
|
|
Arguments json.RawMessage `json:"arguments"`
|
|
}
|
|
if err := json.Unmarshal(args, &p); err != nil {
|
|
return true
|
|
}
|
|
switch strings.ToLower(strings.TrimSpace(p.Action)) {
|
|
case "list":
|
|
return false
|
|
case "call":
|
|
return t.proxiedSequential(ctx, strings.TrimSpace(p.CapabilityID), p.Arguments)
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
// proxiedSequential reads the target's own contract out of the catalog the call
|
|
// named it by. An id the catalog cannot resolve keeps its own place: an unknown
|
|
// target is exactly the one whose effects cannot be assumed.
|
|
func (t *UseCapabilityTool) proxiedSequential(ctx context.Context, id string, inner json.RawMessage) bool {
|
|
e, ok := t.currentCatalog().Lookup(id)
|
|
if !ok || !e.ReadOnly {
|
|
return true
|
|
}
|
|
if e.ToolName == "" || t.registry == nil {
|
|
return false
|
|
}
|
|
target, ok := t.registry.Get(e.ToolName)
|
|
if !ok {
|
|
return true
|
|
}
|
|
return tool.RunsSequentially(ctx, target, inner)
|
|
}
|