Wire the squad native adapter instead of the core registration
Why: Backend has to keep the same squad runs after the core stopped importing agent-native. The adapter module owns the concrete client. Evidence: GOWORK=off go test -count=1 ./internal/... passed. Impact: AgentNativeOptions now returns the adapter config. Default roles still use the agent-system backend. Refs: D1 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
+1
-1
Submodule deps/agent-intent updated: 05e74d8e32...65aaebca1e
Vendored
+1
-1
Submodule deps/agent-native updated: 855fe41152...4a10818535
Vendored
+1
-1
Submodule deps/agent-squad updated: 31ee395895...a182d7662b
@@ -6,17 +6,19 @@ require (
|
||||
agent-command v0.0.0
|
||||
agent-intent v0.0.0
|
||||
agent-native v0.0.0
|
||||
agent-squad v0.0.0-00010101000000-000000000000
|
||||
agent-squad v0.0.0
|
||||
agent-squad/adapters/native v0.0.0
|
||||
agent-system-core v0.0.0
|
||||
error-code-system v0.0.0
|
||||
github.com/jackc/pgx/v5 v5.9.2
|
||||
github.com/ledongthuc/pdf v0.0.0-20260907135840-6c8c28e0e8a0
|
||||
github.com/redis/go-redis/v9 v9.14.0
|
||||
golang.org/x/crypto v0.56.0
|
||||
logging-system v0.0.0
|
||||
modernc.org/sqlite v1.60.1
|
||||
)
|
||||
|
||||
require (
|
||||
error-code-system v0.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
@@ -30,7 +32,6 @@ require (
|
||||
golang.org/x/sync v0.23.0 // indirect
|
||||
golang.org/x/sys v0.48.0 // indirect
|
||||
golang.org/x/text v0.41.0 // indirect
|
||||
logging-system v0.0.0 // indirect
|
||||
modernc.org/libc v1.77.1 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.12.1 // indirect
|
||||
@@ -40,6 +41,8 @@ replace agent-intent => ./deps/agent-intent
|
||||
|
||||
replace agent-squad => ./deps/agent-squad
|
||||
|
||||
replace agent-squad/adapters/native => ./deps/agent-squad/adapters/native
|
||||
|
||||
replace agent-native => ./deps/agent-native
|
||||
|
||||
replace agent-system-core => ./deps/agent-system-core
|
||||
|
||||
+4
-4
@@ -26,7 +26,7 @@ import (
|
||||
agentllm "agent-native/runtime/llm"
|
||||
agentmcp "agent-native/runtime/mcp"
|
||||
agenttools "agent-native/runtime/tools"
|
||||
squad "agent-squad/squad"
|
||||
nativeadp "agent-squad/adapters/native"
|
||||
"agent-system-backend/internal/bus"
|
||||
"agent-system-backend/internal/cardsvc"
|
||||
"agent-system-backend/internal/cmdbus"
|
||||
@@ -142,13 +142,13 @@ func Run(opt Options) error {
|
||||
// 模型走 settings.models.chat 同一路由;搜索/解释器/MCP/技能根复用产品配置;
|
||||
// 委派桥接产品 SpawnSubagent。主模型未配置时返回未启用(不阻塞产品)。
|
||||
var pluginHost *plugins.Host
|
||||
squadadapter.AgentNativeOptions = func(rc squadadapter.Ctx) (squad.AgentNativeConfig, bool) {
|
||||
squadadapter.AgentNativeOptions = func(rc squadadapter.Ctx) (nativeadp.Config, bool) {
|
||||
effNow := setSvc.Effective(store.OwnerDefault, "")
|
||||
route := runtime.ResolveChatModel(core.AgentProfile{}, effNow)
|
||||
if route.Model == "" || route.Base == "" {
|
||||
return squad.AgentNativeConfig{}, false
|
||||
return nativeadp.Config{}, false
|
||||
}
|
||||
cfg := squad.AgentNativeConfig{
|
||||
cfg := nativeadp.Config{
|
||||
Client: &agentllm.Client{BaseURL: route.Base, APIKey: route.Key, HTTPClient: &http.Client{}},
|
||||
DefaultModel: route.Model,
|
||||
MaxTurns: 0,
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"agent-native/exec"
|
||||
agentllm "agent-native/runtime/llm"
|
||||
"agent-squad/squad"
|
||||
"agent-system-backend/internal/squadadapter"
|
||||
@@ -34,7 +33,7 @@ func (s *SquadRunner) Execute(rc RunCtx) error {
|
||||
var streamed strings.Builder
|
||||
var toolParts []core.Part
|
||||
textIdx := 0
|
||||
onEvent := func(ev exec.ProcessEvent) {
|
||||
onEvent := func(ev squad.ProcessEvent) {
|
||||
switch ev.Type {
|
||||
case "text_delta":
|
||||
if ev.Text == "" {
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"agent-native/exec"
|
||||
"agent-native/runtime/subagent"
|
||||
nativeadp "agent-squad/adapters/native"
|
||||
"agent-squad/squad"
|
||||
"agent-system-backend/internal/quality"
|
||||
core "agent-system-core"
|
||||
@@ -171,7 +171,7 @@ func profileForRole(role string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *stepBackend) Execute(ctx context.Context, req exec.Request) (*exec.Result, error) {
|
||||
func (b *stepBackend) Execute(ctx context.Context, req squad.ExecRequest) (*squad.ExecResult, error) {
|
||||
task := strings.TrimSpace(req.Prompt)
|
||||
if task == "" {
|
||||
task = req.Instructions
|
||||
@@ -187,7 +187,7 @@ func (b *stepBackend) Execute(ctx context.Context, req exec.Request) (*exec.Resu
|
||||
} else {
|
||||
out, err = b.rc.SpawnSubagent(name, task, hint)
|
||||
}
|
||||
res := &exec.Result{Success: err == nil, Logs: firstNonEmpty(out.Summary, "子代理完成")}
|
||||
res := &squad.ExecResult{Success: err == nil, Logs: firstNonEmpty(out.Summary, "子代理完成")}
|
||||
if err != nil {
|
||||
res.ErrorReason = err.Error()
|
||||
return res, nil
|
||||
@@ -290,7 +290,7 @@ func isHoldStatus(s string) bool {
|
||||
// AgentNativeOptions 可选组合根注入:返回配置且启用时,为每次小队运行注册
|
||||
// "agent-native" 内核后端工厂(模型/搜索/执行/MCP/技能根由组合根从 settings
|
||||
// 解析;Subagent 工厂经 rc 桥接产品 SpawnSubagent)。
|
||||
var AgentNativeOptions func(rc Ctx) (squad.AgentNativeConfig, bool)
|
||||
var AgentNativeOptions func(rc Ctx) (nativeadp.Config, bool)
|
||||
|
||||
// SubagentFactory 把内核委派端口(delegate_task)桥接到产品 SpawnSubagent:
|
||||
// 委派信息集(目标/输入/写范围/非目标/完成判据/交付物)拼装为任务书,
|
||||
@@ -334,12 +334,12 @@ func SubagentFactory(rc Ctx) subagent.Factory {
|
||||
// 不因工厂注册而切换(对齐 parity 渐进启用条款)。
|
||||
func buildBackends(rc Ctx) *squad.BackendResolver {
|
||||
backends := squad.NewBackendResolver()
|
||||
backends.Register("agent-system", func(role squad.RoleSpec) (exec.Backend, error) {
|
||||
backends.Register("agent-system", func(role squad.RoleSpec) (squad.Executor, error) {
|
||||
return &stepBackend{rc: rc, role: role}, nil
|
||||
})
|
||||
if AgentNativeOptions != nil {
|
||||
if cfg, ok := AgentNativeOptions(rc); ok {
|
||||
backends.RegisterAgentNativeFull(cfg)
|
||||
nativeadp.RegisterFull(backends, cfg)
|
||||
}
|
||||
}
|
||||
return backends
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"agent-native/exec"
|
||||
"agent-native/runtime/subagent"
|
||||
"agent-squad/squad"
|
||||
core "agent-system-core"
|
||||
@@ -145,7 +144,7 @@ func TestStepRoleMapsToProfile(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
rc := &agentFakeRc{subagentFakeRc: subagentFakeRc{payload: core.AgentResultPayload{Text: "ok"}}}
|
||||
b := &stepBackend{rc: rc, role: squad.RoleSpec{Role: tc.role, Name: "显示名"}}
|
||||
res, err := b.Execute(context.Background(), exec.Request{Prompt: "做这件事", WorkDir: dir, Targets: []string{"output.md"}})
|
||||
res, err := b.Execute(context.Background(), squad.ExecRequest{Prompt: "做这件事", WorkDir: dir, Targets: []string{"output.md"}})
|
||||
if err != nil || !res.Success {
|
||||
t.Fatalf("%s: %+v %v", tc.role, res, err)
|
||||
}
|
||||
@@ -155,7 +154,7 @@ func TestStepRoleMapsToProfile(t *testing.T) {
|
||||
}
|
||||
plain := &subagentFakeRc{payload: core.AgentResultPayload{Text: "ok"}}
|
||||
b := &stepBackend{rc: plain, role: squad.RoleSpec{Role: "writer", Name: "撰稿"}}
|
||||
if _, err := b.Execute(context.Background(), exec.Request{Prompt: "写", WorkDir: dir}); err != nil {
|
||||
if _, err := b.Execute(context.Background(), squad.ExecRequest{Prompt: "写", WorkDir: dir}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if plain.gotName != "撰稿" {
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"agent-native/exec"
|
||||
agentllm "agent-native/runtime/llm"
|
||||
"agent-native/runtime/tools"
|
||||
nativeadp "agent-squad/adapters/native"
|
||||
"agent-squad/squad"
|
||||
"agent-system-backend/internal/quality"
|
||||
)
|
||||
@@ -19,7 +19,7 @@ type EntryOptions struct {
|
||||
DataDir string
|
||||
Goal string
|
||||
HostTools []tools.Tool
|
||||
OnEvent func(ev exec.ProcessEvent)
|
||||
OnEvent func(ev squad.ProcessEvent)
|
||||
Stream agentllm.StreamFunc
|
||||
Router squad.Router
|
||||
Checker squad.Checker
|
||||
@@ -43,7 +43,7 @@ func RunEntry(rc Ctx, opt EntryOptions) (EntryResult, error) {
|
||||
if strings.TrimSpace(opt.Goal) == "" {
|
||||
return EntryResult{}, fmt.Errorf("squad entry: goal text is empty")
|
||||
}
|
||||
cfg, enabled := squad.AgentNativeConfig{}, false
|
||||
cfg, enabled := nativeadp.Config{}, false
|
||||
if AgentNativeOptions != nil {
|
||||
cfg, enabled = AgentNativeOptions(rc)
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func RunEntry(rc Ctx, opt EntryOptions) (EntryResult, error) {
|
||||
}
|
||||
}
|
||||
backends := buildBackends(rc)
|
||||
backends.RegisterAgentNativeFull(cfg)
|
||||
nativeadp.RegisterFull(backends, cfg)
|
||||
|
||||
checker := opt.Checker
|
||||
if checker == nil {
|
||||
|
||||
Reference in New Issue
Block a user