Skip to content

Migrate fast/ module (fast_plan_tasks) to AgentField native .harness() #28

@santoshkumarradha

Description

@santoshkumarradha

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.pyfast_plan_tasks
  • Remove from swe_af.agent_ai import AgentAI, AgentAIConfig

Acceptance criteria

  • fast_plan_tasks uses fast_router.harness() or fast_router.ai() instead of AgentAI.run()
  • No imports from swe_af.agent_ai remain in swe_af/fast/planner.py
  • Output schema FastPlanResult preserved exactly
  • Fallback plan (_fallback_plan) preserved on failure
  • max_tasks truncation logic preserved
  • Provider mapping: "claude""claude-code" (if using .harness())

Tests needed

  • Unit test: returns FastPlanResult dict on success (mock router method)
  • Unit test: returns fallback plan with fallback_used=True on LLM failure
  • Unit test: returns fallback plan when parsed response is None
  • Unit test: truncates to max_tasks when LLM returns too many tasks
  • Verify fast/executor.py and fast/verifier.py are unaffected (they use app.call(), not AgentAI directly)

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions