Part of epic #21
Summary
Migrate fast_plan_tasks in swe_af/fast/planner.py from custom AgentAI(...).run() to AgentField's native router.harness() (or potentially .ai() since it uses only 3 turns and no explicit tools).
AgentField now natively supports .harness() and .ai() as first-class primitives — this replaces the custom abstraction.
No dependencies — can be worked independently. Good first issue (single agent, single file).
Agent to migrate
| Agent |
File |
Current tools |
Role |
fast_plan_tasks |
swe_af/fast/planner.py |
(none specified) |
Single-pass task decomposition for FastBuild mode |
Note: This agent uses AgentAIConfig with max_turns=3 and no explicit allowed_tools, so it gets defaults. Check whether it actually needs tool access — if not, .ai() may be more appropriate.
Current pattern
from swe_af.agent_ai import AgentAI, AgentAIConfig
ai = AgentAI(
AgentAIConfig(
provider=ai_provider,
model=pm_model,
cwd=repo_path,
max_turns=3,
permission_mode=permission_mode or None,
)
)
response = await ai.run(
task_prompt,
system_prompt=FAST_PLANNER_SYSTEM_PROMPT,
output_schema=FastPlanResult,
)
Target pattern (option A — .harness())
result = await fast_router.harness(
prompt=task_prompt,
schema=FastPlanResult,
provider=provider,
model=pm_model,
max_turns=3,
permission_mode=permission_mode or None,
system_prompt=FAST_PLANNER_SYSTEM_PROMPT,
cwd=repo_path,
)
Target pattern (option B — .ai() if no tools needed)
result = await fast_router.ai(
task_prompt,
system=FAST_PLANNER_SYSTEM_PROMPT,
schema=FastPlanResult,
model=pm_model,
)
Decision: .harness() vs .ai()
- If the planner needs to read repository files to plan →
.harness()
- If it only uses the goal text and context passed in the prompt →
.ai()
- Check the prompt template in
swe_af/fast/prompts.py to determine
Files to modify
swe_af/fast/planner.py — fast_plan_tasks
- Remove
from swe_af.agent_ai import AgentAI, AgentAIConfig
Acceptance criteria
Tests needed
Notes
executor.py and verifier.py in the fast/ module use app.call() to dispatch reasoners — they don't use AgentAI directly and are NOT affected by this migration
- Only
planner.py has the direct AgentAI import
- Default model is
haiku — cheap, appropriate for fast planning
Part of epic #21
Summary
Migrate
fast_plan_tasksinswe_af/fast/planner.pyfrom customAgentAI(...).run()to AgentField's nativerouter.harness()(or potentially.ai()since it uses only 3 turns and no explicit tools).AgentField now natively supports
.harness()and.ai()as first-class primitives — this replaces the custom abstraction.No dependencies — can be worked independently. Good first issue (single agent, single file).
Agent to migrate
fast_plan_tasksswe_af/fast/planner.pyNote: This agent uses
AgentAIConfigwithmax_turns=3and no explicitallowed_tools, so it gets defaults. Check whether it actually needs tool access — if not,.ai()may be more appropriate.Current pattern
Target pattern (option A —
.harness())Target pattern (option B —
.ai()if no tools needed)Decision:
.harness()vs.ai().harness().ai()swe_af/fast/prompts.pyto determineFiles to modify
swe_af/fast/planner.py—fast_plan_tasksfrom swe_af.agent_ai import AgentAI, AgentAIConfigAcceptance criteria
fast_plan_tasksusesfast_router.harness()orfast_router.ai()instead ofAgentAI.run()swe_af.agent_airemain inswe_af/fast/planner.pyFastPlanResultpreserved exactly_fallback_plan) preserved on failuremax_taskstruncation logic preserved"claude"→"claude-code"(if using.harness())Tests needed
FastPlanResultdict on success (mock router method)fallback_used=Trueon LLM failuremax_taskswhen LLM returns too many tasksfast/executor.pyandfast/verifier.pyare unaffected (they useapp.call(), notAgentAIdirectly)Notes
executor.pyandverifier.pyin the fast/ module useapp.call()to dispatch reasoners — they don't useAgentAIdirectly and are NOT affected by this migrationplanner.pyhas the directAgentAIimporthaiku— cheap, appropriate for fast planning