Files
Test 11a1c1196a Add testable task descriptions: T0.1 through T0.9
Each task includes:
- Scope: what to build
- Implementation: code sketches + details
- Verification: concrete test criteria
- Done criteria: acceptance checklist
2026-08-20 22:41:54 -07:00

3.8 KiB

T0.5: LLM Agents & Prompts

Scope

Implement LLM activities (Planner, Judge, Implementer), LLM client, and prompt template registry.

Implementation

File: action/llm/client.go

type AnthropicClient struct {
    apiKey string
}

func NewClient() *AnthropicClient
    // Read ANTHROPIC_API_KEY from env
    // Return client

func (c *AnthropicClient) CreateMessage(ctx context.Context, in MessageInput) (string, error)
    // Call Anthropic API messages.create
    // Respect model.ModelID, model.Thinking, model.Effort
    // Return response text

File: action/planner.go

type PlanningInput struct {
    Config      OrchestratorConfig
    BoardState  string // JSON or markdown of task board
    Milestone   string
}

type TaskDispatch struct {
    TaskID       string
    Prompt       PromptSpec
    BaseTimeout  time.Duration // can override default
}

func PlanningActivity(ctx context.Context, in PlanningInput) ([]TaskDispatch, error)
    // Read target repo's tasks/INDEX.md + board from shared FS
    // Render prompt: in.Config.SystemPrompt + in.Config.RolePrompts["planner"] template
    // Call LLM (Planner model)
    // Parse response: which tasks to dispatch next, optional tuning overrides
    // Return task dispatch list

File: action/judge.go

type JudgeInput struct {
    Config              OrchestratorConfig
    Diff                string // git diff output
    IntegrationTestLogs string // test output
}

type JudgeOutput struct {
    Verdict  string // "pass" or "fail"
    Critique string // explanation if fail
}

func JudgeActivity(ctx context.Context, in JudgeInput) (JudgeOutput, error)
    // Render prompt: in.Config.SystemPrompt + in.Config.RolePrompts["judge"]
    // Call LLM (Judge model, reasoning)
    // Parse response: verdict + critique
    // Return JudgeOutput

File: action/implementer.go

type ImplementerInput struct {
    Config      OrchestratorConfig
    TaskID      string
    WorktreePath string
    Lessons     string // "known errors — do not repeat" section
}

type ImplementerOutput struct {
    Success bool
    Changes string // summary of changes made
}

func ImplementerActivity(ctx context.Context, in ImplementerInput) (ImplementerOutput, error)
    // Render prompt: in.Config.SystemPrompt + in.Config.RolePrompts["implementer"]
    // Inject in.Lessons into Variables
    // Start tool-call agent loop (run git/cargo/pnpm/etc as needed)
    // After each tool call, activity.RecordHeartbeat(ctx, progress)
    // Return success/changes

File: prompts/registry.go

// go:embed prompts/*.tmpl

func Render(templateRef string, variables map[string]any) (string, error)
    // Load embedded template via go:embed + text/template
    // Render with variables
    // Return rendered string

Files: prompts/planner/default.tmpl, etc.

Empty templates for now; will be filled in by Planner/Judge/Implementer activities.

You are a Planner agent. Your job: reconcile task state, dispatch work.

System prompt: {{.SystemPrompt}}

Current board:
{{.BoardState}}

Current config:
{{.Config | json}}

What tasks should we dispatch next? (respond in JSON: {"tasks": [{"id": "T0.1", "timeout_override_ms": null}, ...]})

Verification

cd /Users/rockliang/workplace/Poimen/workflows
go test -v ./tests -run TestPrompts

# Test file: tests/prompts_test.go

Test cases:

  • Render template with system prompt + variables → output includes system prompt prefix
  • Render with RawTemplate override → uses raw template, not embedded
  • Render with Variables substitution → all {{.Var}} replaced
  • Mock LLM client responses → activities parse correctly

Done Criteria

  • go test ./tests -run TestPrompts passes
  • All templates render without errors
  • LLM client reads ANTHROPIC_API_KEY from env (or uses mock in tests)
  • Activities parse LLM responses into structured output