Files
Agent-Squad/cmd/agent-squad/cli/platform_cmd.go
weichenandCursor a182d7662b Move cross-library squad code into adapter modules
Why: the squad core has to compile without agent-native or agent-intent. Ports stay in the core; adapters and the CLI own the concrete clients.
Evidence: GOWORK=off go test -count=1 ./squad/ ./store/ ./textextract/ ./schema/ passed, and the intent, sqlite, native, and cmd modules passed their own go test.
Impact: core go.mod keeps error-code-system only. Nested gitlinks stay. Callers register the native backend through agent-squad/adapters/native.
Refs: D1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 13:40:58 +00:00

131 lines
3.9 KiB
Go

package cli
import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
"time"
"agent-native/runtime/llm"
platform "agent-squad/adapters/sqlite"
)
func cmdPlatform(args []string) int {
if len(args) < 2 {
fmt.Fprintln(os.Stderr, "用法: agent-squad", args[0], "create|import|assign|claim|fire ...")
return 2
}
fs := flag.NewFlagSet(args[0], flag.ContinueOnError)
data := fs.String("data", dataDir(), "数据目录")
workspace := fs.String("workspace", "", "workspace id")
name := fs.String("name", "", "名称")
if err := fs.Parse(args[2:]); err != nil {
return 2
}
st, err := platform.Open(filepath.Join(*data, "orchestration.db"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
defer st.Close()
switch args[0] + " " + args[1] {
case "agent create":
a, err := st.CreateAgent(platform.Agent{WorkspaceID: *workspace, Name: *name})
return printPlatform(a, err)
case "skill import":
if fs.NArg() < 1 {
fmt.Fprintln(os.Stderr, "skill import 需要目录或 zip 路径")
return 2
}
sk, err := st.ImportSkill(*workspace, fs.Arg(0), "rename")
return printPlatform(sk, err)
case "squad create":
if fs.NArg() < 1 {
fmt.Fprintln(os.Stderr, "squad create 需要 leader agent id")
return 2
}
sq, err := st.CreateSquad(platform.Squad{WorkspaceID: *workspace, Name: *name, LeaderAgentID: fs.Arg(0)}, nil)
return printPlatform(sq, err)
case "issue create":
issue, err := st.CreateIssue(platform.Issue{WorkspaceID: *workspace, Title: *name, Status: "todo"})
return printPlatform(issue, err)
case "issue assign":
if fs.NArg() < 3 {
fmt.Fprintln(os.Stderr, "issue assign <issue> <agent|squad> <id>")
return 2
}
err := st.AssignIssue(fs.Arg(0), fs.Arg(1), fs.Arg(2), true)
return printPlatform(map[string]bool{"ok": err == nil}, err)
case "autopilot create":
if fs.NArg() < 2 {
fmt.Fprintln(os.Stderr, "autopilot create <agent-id> <create_issue|run_only>")
return 2
}
a, err := st.CreateAutopilot(platform.Autopilot{
WorkspaceID: *workspace, Title: *name, Runbook: *name,
AssigneeKind: "agent", AssigneeID: fs.Arg(0), ExecutionMode: fs.Arg(1),
})
return printPlatform(a, err)
case "runtime probe":
rts, err := st.RegisterProbed(*workspace)
return printPlatform(rts, err)
case "daemon claim":
if fs.NArg() < 1 {
fmt.Fprintln(os.Stderr, "daemon claim <runtime-id>")
return 2
}
task, ok, err := st.Claim(fs.Arg(0), time.Now())
return printPlatform(map[string]any{"ok": ok, "task": task}, err)
case "chat create":
c, err := st.CreateChat(platform.ChatSession{WorkspaceID: *workspace, OwnerID: *name})
return printPlatform(c, err)
case "project create":
p, err := st.CreateProject(platform.Project{WorkspaceID: *workspace, Name: *name})
return printPlatform(p, err)
case "daemon run-native":
if fs.NArg() < 2 {
fmt.Fprintln(os.Stderr, "daemon run-native <task-id> <workdir>")
return 2
}
task, err := st.TaskByToken(fs.Arg(0))
if err != nil {
var idErr error
task, idErr = taskByID(st, fs.Arg(0))
if idErr != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
}
text, err := st.RunInProcess(context.Background(), task, fs.Arg(1), scriptedOK)
return printPlatform(map[string]string{"text": text}, err)
default:
fmt.Fprintln(os.Stderr, "未知编排命令", args[0], args[1])
return 2
}
}
func taskByID(st *platform.Store, id string) (platform.Task, error) {
return st.TaskByToken(id)
}
func scriptedOK(ctx context.Context, model string, messages []llm.Message, td []llm.ToolDecl, opts llm.StreamOptions) <-chan llm.Event {
ch := make(chan llm.Event, 1)
ch <- llm.Event{Kind: llm.KindMessageEnd, Message: llm.Message{Role: llm.RoleAssistant, Content: "ok", StopReason: llm.StopEnd}}
close(ch)
return ch
}
func printPlatform(v any, err error) int {
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
_ = enc.Encode(v)
return 0
}