Add a script host, deferred tools, and background MCP connect
Why: models need a capped way to call several tools from one script, and a slow MCP server must not block the first prompt. Evidence: GOWORK=off go test ./runtime/codeorch/ ./runtime/tools/ ./runtime/mcp/ ./runtime/policy/ ./adapters/native/ Impact: run_tool_script stays unregistered until the caller turns it on. Deferred tools stay out of the model list. An unready MCP server connects in the background. Refs: feature/code-orchestration Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -49,6 +49,8 @@ type ToolOptions struct {
|
||||
HostTools []tools.Tool
|
||||
Checkpoints *checkpoint.Log
|
||||
CheckpointAnchor func() string
|
||||
// CodeOrchestration 为真时注册 run_tool_script。默认关。
|
||||
CodeOrchestration bool
|
||||
}
|
||||
|
||||
// SessionOptions 是单次执行的会话预算与压缩。
|
||||
@@ -73,6 +75,8 @@ type GateOptions struct {
|
||||
Reminders func(turn int) []string
|
||||
RepeatGuard bool
|
||||
Hooks *hooks.Bus
|
||||
// Ask 在 MCP 工具要求用户输入时调用。nil 则把问题作为错误返回。
|
||||
Ask func(ctx context.Context, question string) (string, error)
|
||||
}
|
||||
|
||||
// Options 构造后端所需的模型接入与执行参数(由组合根注入,无产品依赖)。
|
||||
@@ -147,6 +151,9 @@ func (b *Backend) Execute(ctx context.Context, req exec.Request) (*exec.Result,
|
||||
if b.opts.Stream == nil && (strings.TrimSpace(b.opts.APIBase) == "" || strings.TrimSpace(b.opts.APIKey) == "") {
|
||||
return &exec.Result{Success: false, ErrorReason: "agent-native backend requires api base/key (or injected stream)"}, nil
|
||||
}
|
||||
if b.opts.Ask != nil {
|
||||
ctx = mcp.WithAsk(ctx, b.opts.Ask)
|
||||
}
|
||||
model := strings.TrimSpace(b.opts.Model)
|
||||
if strings.TrimSpace(req.Model) != "" {
|
||||
model = strings.TrimSpace(req.Model)
|
||||
@@ -204,9 +211,19 @@ func (b *Backend) Execute(ctx context.Context, req exec.Request) (*exec.Result,
|
||||
}
|
||||
tools.RegisterExecTools(reg, workDir, execCfg)
|
||||
}
|
||||
if b.opts.CodeOrchestration {
|
||||
tools.RegisterCodeTool(reg)
|
||||
}
|
||||
reg.SetActivationFile(filepath.Join(workDir, ".agentx", "activated-tools.json"))
|
||||
_ = reg.RestoreActivated()
|
||||
if b.opts.MCP != nil {
|
||||
if err := b.opts.MCP.RegisterInto(ctx, reg); err != nil {
|
||||
return &exec.Result{Success: false, ErrorReason: err.Error()}, nil
|
||||
switch {
|
||||
case len(req.ToolAllowlist) > 0 || b.opts.MCP.Ready():
|
||||
if err := b.opts.MCP.RegisterInto(ctx, reg); err != nil {
|
||||
return &exec.Result{Success: false, ErrorReason: err.Error()}, nil
|
||||
}
|
||||
default:
|
||||
b.opts.MCP.StartBackground(ctx, reg)
|
||||
}
|
||||
}
|
||||
subagent.Register(reg, b.opts.Subagent)
|
||||
|
||||
@@ -212,6 +212,9 @@ func TestBackendMCPToolsWiredViaOptions(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer mgr.Close()
|
||||
if err := mgr.RegisterInto(context.Background(), tools.NewRegistry(t.TempDir())); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stream, c := captureStream(
|
||||
llm.Message{Role: llm.RoleAssistant, StopReason: llm.StopToolCalls, ToolCalls: []llm.ToolCall{{
|
||||
ID: "c1", Name: "mcp__fake__echo", Arguments: `{"text":"via-backend"}`,
|
||||
|
||||
Reference in New Issue
Block a user