Files
Agent-Squad/squad/planner_mock.go
weichenandCursor bfec3c8930
ci / vet-and-test (push) Failing after 3s
ci / docker-checkout-hostgateway (push) Failing after 3s
Import agent-squad as a standalone repository.
Pin Agent-Native as a submodule so the module builds without the multi-repo sibling path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-29 12:38:35 +00:00

80 lines
2.1 KiB
Go

package squad
import (
"context"
"fmt"
)
// MockPlanner 脚本化规划器:离线演示/测试用。
// Script 非空时按脚本步骤产出计划(不查注册表);否则退化为 RulePlanner。
type MockPlanner struct {
// Script 预置计划步骤(角色需调用方保证已注册)。
Script []StepSpec
// ClarifyReason 非空时总是请求澄清(测试 HITL 澄清路径)。
ClarifyReason string
// NeedsConfirm 强制计划进入确认。
NeedsConfirm bool
// ConfirmReason 确认原因文案。
ConfirmReason string
// Agents 编制;缺省时按脚本步骤收集角色。
Agents []RoleSpec
}
// NewMockPlanner 创建 mock 规划器。
func NewMockPlanner() *MockPlanner { return &MockPlanner{} }
func (p *MockPlanner) Name() string { return "mock" }
func (p *MockPlanner) Plan(ctx context.Context, input PlanInput) (*PlanOutput, error) {
if p.ClarifyReason != "" {
return &PlanOutput{Clarification: &Clarification{
Reason: p.ClarifyReason,
Questions: []Question{{
ID: "q_mock",
Text: p.ClarifyReason,
Options: []HumanOption{
{Value: "continue", Label: "按当前信息继续"},
{Value: "abort", Label: "中止"},
},
}},
}}, nil
}
if len(p.Script) == 0 {
return NewRulePlanner().Plan(ctx, input)
}
steps := make([]StepSpec, len(p.Script))
copy(steps, p.Script)
for i := range steps {
if steps[i].Targets == nil {
steps[i].Targets = []string{"output.md"}
}
steps[i].Status = "pending"
}
agents := p.Agents
if agents == nil {
seen := map[string]bool{}
for _, st := range steps {
if !seen[st.Role] {
if spec, ok := input.Registry.Get(st.Role); ok {
agents = append(agents, spec)
seen[st.Role] = true
}
}
}
}
return &PlanOutput{
Plan: &SquadPlan{
Squad: SquadConfig{SquadName: "mock_squad", Version: "1", Agents: agents},
Workflow: WorkflowPlan{
WorkflowID: NewPlanID(),
Title: fmt.Sprintf("mock plan for %s", truncate(input.Goal.Text, 40)),
PlanningMode: PlanModeAutonomous,
Status: "pending",
Steps: steps,
},
},
NeedsConfirmation: p.NeedsConfirm,
ConfirmReason: p.ConfirmReason,
}, nil
}