agent

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PipelineGreen = "green" // build new from scratch (TDD)
	PipelineBrown = "brown" // existing codebase: research → discuss → TDD
	PipelineFix   = "fix"   // bug/repair: research → short coder-first fix loop
	PipelineRnD   = "rnd"   // proof-of-concept: short PM↔user loop, quick PoC
)

Pipeline identifiers PM selects to route a task through the right execution strategy. Empty defaults to PipelineGreen after resolution.

Variables

This section is empty.

Functions

func FilterSourceFiles

func FilterSourceFiles(files []string) []string

FilterSourceFiles returns only source code files, using an allowlist of recognized extensions. This prevents binaries and non-text files from corrupting LLM context.

func IsBuildFixStuck

func IsBuildFixStuck(err error) bool

IsBuildFixStuck reports whether err represents an aborted fix loop caused by repeated identical validation failures.

func SeedsFromSemanticSearch

func SeedsFromSemanticSearch(ctx context.Context, pc pkgcontext.ProjectContext, stagePrompt string, k int) []string

SeedsFromSemanticSearch derives seed file paths for buildCompactSourceContext using the semantic index attached to pc, when available. Returns nil when the index is disabled, the query is empty, or the search fails — callers can fall back to passing no seeds.

Types

type Agent

type Agent interface {
	Role() bus.AgentRole
	Run(ctx context.Context, msg bus.Message) (bus.Message, error)
}

Agent is implemented by every specialized agent in the pipeline.

type ArbitrateAllResult

type ArbitrateAllResult struct {
	Pass        bool      // true = all clear, nothing to fix
	SubTasks    []SubTask // new beads for real issues (empty when Pass)
	ReviewScope string    // "full", "partial", or "none"
	NiceToHave  []string  // issues PM decided to skip
}

ArbitrateAllResult is the PM's decision on combined review feedback.

type ArbitrateResult

type ArbitrateResult struct {
	MustFix []string
	Pass    bool
}

ArbitrateResult is the PM's decision on an unparseable review response.

type BaseAgent

type BaseAgent struct {
	Bus *bus.Bus
	// contains filtered or unexported fields
}

BaseAgent holds shared state and helpers for all agents.

func NewBase

func NewBase(role bus.AgentRole, b *bus.Bus) BaseAgent

NewBase creates a BaseAgent for the given role.

func (*BaseAgent) Gate

func (a *BaseAgent) Gate(msg string)

Gate publishes a human_gate event (exported so decsr can call it if needed).

type BuildFixStuckError

type BuildFixStuckError struct {
	RepeatCount int
}

BuildFixStuckError indicates that the build/test fix loop is repeating the same failure and was aborted to avoid an infinite cycle.

func (BuildFixStuckError) Error

func (e BuildFixStuckError) Error() string

type CoderAgent

type CoderAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

CoderAgent generates code and writes files to disk one by one.

func NewCoderAgent

func NewCoderAgent(b *bus.Bus, r runner.LLMRunner, ws artifacts.Workspace, root string, cfg config.Config, skills []string, model string) *CoderAgent

func (*CoderAgent) BuildAndFix

func (a *CoderAgent) BuildAndFix(ctx context.Context, files []string) ([]string, error)

BuildAndFix compiles the project and iteratively fixes build/test errors. MaxFixAttempts is the number of attempts allowed at the SAME error before giving up — a different error resets the counter. This way the LLM gets the configured number of tries to repair each distinct problem rather than burning the budget across unrelated failures. Returns the updated file list after all fixes. Token usage across all fix iterations is accumulated and emitted at the end.

func (*CoderAgent) Research

func (a *CoderAgent) Research(ctx context.Context, p CoderResearchPayload) (string, error)

Research performs a read-only review of the existing codebase against the user's requirements and returns the coder's analysis as text. It writes no files; it is used as Phase 0 of the brown and fix pipelines.

func (*CoderAgent) Role

func (a *CoderAgent) Role() bus.AgentRole

func (*CoderAgent) Run

func (a *CoderAgent) Run(ctx context.Context, msg bus.Message) (bus.Message, error)

func (*CoderAgent) SetFixerRunner

func (a *CoderAgent) SetFixerRunner(r runner.LLMRunner, model string)

SetFixerRunner configures an optional separate runner/model used for fix iterations (BuildAndFix, CoderFixPayload). When not set, fixes use the primary runner/model.

type CoderFixPayload

type CoderFixPayload struct {
	Failure        string
	ProjectContext string
	Files          []string // source files to include as context (read from disk)
	// Targets maps file -> symbol names for ADDITIVE scoped related context.
	// Files here that are not already in Files are appended, rendered scoped.
	// Never removes Files from context. Set by the runner when enabled.
	Targets map[string][]string
}

CoderFixPayload is the request for fixing code based on test/review failures.

type CoderPayload

type CoderPayload struct {
	Plan           string
	ProjectContext string
	Scope          []string
	StageName      string   // human-readable stage label (e.g. "Stage 2/5: Must Have — Auth")
	StageIndex     int      // 1-based stage number (0 = monolithic)
	TotalStages    int      // total number of stages
	PriorFiles     []string // files written by previous stages (read from disk for context)
}

CoderPayload is the request for initial code generation.

type CoderResearchPayload

type CoderResearchPayload struct {
	Requirements   string
	ProjectContext string
}

CoderResearchPayload requests a read-only codebase review for the brown and fix pipelines. The coder analyses existing code against the requirements and returns prose findings; it writes no files.

type CoderResult

type CoderResult struct {
	Files []string
}

CoderResult holds the list of files written by the coder.

type ExecutionPlan

type ExecutionPlan struct {
	NeedsArchitecture bool   `json:"needs_architecture"`
	NeedsDetailedPlan bool   `json:"needs_detailed_plan"`
	CoderInstructions string `json:"coder_instructions"`
}

ExecutionPlan is the PM's strategy for implementing a task.

type FileBlock

type FileBlock struct {
	Path    string
	Content string
}

FileBlock is a single file extracted from LLM output.

func ExtractFileBlocks

func ExtractFileBlocks(output string) []FileBlock

ExtractFileBlocks parses LLM output for code blocks with associated file paths.

type PMAgent

type PMAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

PMAgent creates product vision and MoSCoW-prioritized feature list.

func NewPMAgent

func NewPMAgent(b *bus.Bus, r runner.LLMRunner, ws artifacts.Workspace, skills []string, model string) *PMAgent

func (*PMAgent) Arbitrate

func (a *PMAgent) Arbitrate(ctx context.Context, phase, rawReviewOutput string) (ArbitrateResult, error)

Arbitrate asks the PM to interpret a raw, unparseable review output and decide whether the coder needs to fix something. This is the "default" fallback when review parsers cannot extract structured data from the LLM.

func (*PMAgent) ArbitrateAll

func (a *PMAgent) ArbitrateAll(ctx context.Context, qaFeedback, uxFeedback, securityFeedback string) (ArbitrateAllResult, error)

ArbitrateAll asks the PM to evaluate combined feedback from QA, UX, and Security review phases in a single call. PM decides what is real, creates sub-tasks for blockers, and determines the scope of re-review.

func (*PMAgent) CompactRepository

func (a *PMAgent) CompactRepository(ctx context.Context, projectCtx string, maxTokens int) (string, error)

CompactRepository turns the collected repository context into a Markdown context pack. The pack is user-editable: the USER-CONTEXT block is preserved verbatim across regenerations.

func (*PMAgent) DecomposeTask

func (a *PMAgent) DecomposeTask(ctx context.Context, spec TaskSpec, architecture, projectCtx string, brownfield bool) ([]SubTask, error)

DecomposeTask asks the PM to break the approved TaskSpec into ordered, dependency-aware sub-tasks. Each returned sub-task becomes a Beads issue and drives one coder pass downstream. `architecture` is optional approved-design context (empty for surgical changes that skip the architect step).

func (*PMAgent) GatherRequirements

func (a *PMAgent) GatherRequirements(ctx context.Context, projectCtx string, humanCh <-chan string) (summary string, requirements string, err error)

GatherRequirements conducts a multi-turn conversation with the user to produce project requirements. The flow is:

  1. PM asks clarifying questions until it has enough information
  2. PM produces a ===SUMMARY=== — caller publishes it and waits for approval
  3. User confirms summary (via humanCh)
  4. PM produces ===REQUIREMENTS=== — returned to caller

The caller (Pipeline/TaskRunner) is responsible for the approval gates.

func (*PMAgent) NegotiateTask

func (a *PMAgent) NegotiateTask(ctx context.Context, input, projectCtx string, humanCh <-chan string) (TaskSpec, error)

NegotiateTask conducts a multi-turn conversation to formalize a TaskSpec. PM emits questions via bus; human responses arrive through humanCh. When PM is satisfied, it emits the final TaskSpec.

Negotiation results are cached on disk keyed by sha256(initial input + project context). When the same input is replayed (e.g. rerunning the decsr with an unchanged task description) the cached TaskSpec is returned without invoking the LLM. Cache is invalidated automatically when either the user input or the project context changes by a single byte.

func (*PMAgent) PlanTask

func (a *PMAgent) PlanTask(ctx context.Context, spec TaskSpec, projectCtx string, brownfield bool) (ExecutionPlan, error)

PlanTask asks the PM to decide the execution strategy for a task. brownfield indicates the target repository already contains source code; when true, PM is instructed to plan surgical changes instead of scaffolding.

func (*PMAgent) RnDTurn

func (a *PMAgent) RnDTurn(ctx context.Context, projectCtx string, messages []runner.ConvMessage) (RnDAction, string, error)

RnDTurn runs a single PM turn for the R&D pipeline over the running conversation. It returns the parsed action and the raw assistant output so the caller can append it to the history.

func (*PMAgent) Role

func (a *PMAgent) Role() bus.AgentRole

func (*PMAgent) Run

func (a *PMAgent) Run(ctx context.Context, msg bus.Message) (bus.Message, error)

type PMPayload

type PMPayload struct {
	Requirements   string
	ProjectContext string
}

PMPayload is the input for the Project Manager agent.

type QAAgent

type QAAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

QAAgent combines test writing (TDD), test verification, and quality review.

func NewQAAgent

func NewQAAgent(b *bus.Bus, r runner.LLMRunner, ws artifacts.Workspace, root string, cfg config.Config, skills []string, model string) *QAAgent

func (*QAAgent) GenerateTests

func (a *QAAgent) GenerateTests(ctx context.Context, payload QATestPayload) error

GenerateTests creates test files via LLM in TDD mode (tests before implementation).

func (*QAAgent) ReviewPlan

func (a *QAAgent) ReviewPlan(ctx context.Context, planText, projectCtx string) (QAReviewResult, error)

ReviewPlan audits an implementation plan (before any code exists) for quality and correctness risks. It returns the structured result so the caller can surface MUST-FIX items to the human before the plan is approved.

func (*QAAgent) Role

func (a *QAAgent) Role() bus.AgentRole

func (*QAAgent) Run

func (a *QAAgent) Run(ctx context.Context, msg bus.Message) (bus.Message, error)

Run executes a quality review (code quality, logic, corner cases).

func (*QAAgent) SetMaxContextTokens

func (a *QAAgent) SetMaxContextTokens(n int)

SetMaxContextTokens configures the token budget for review mode.

func (*QAAgent) VerifyTests

func (a *QAAgent) VerifyTests(ctx context.Context, payload QAVerifyTestsPayload) (QAVerifyResult, error)

VerifyTests checks whether existing tests are correct after repeated coder failures. Returns a verdict: either tests are OK (coder's problem) or updated test files.

type QAReviewPayload

type QAReviewPayload struct {
	Files          []string
	Root           string
	ProjectContext string
	Seeds          []string
	// Targets maps file -> symbol names for measurement-only scoped-context
	// shadow logging. Set by the runner when scoped_context_shadow is enabled.
	Targets map[string][]string
}

QAReviewPayload carries inputs for quality review.

type QAReviewResult

type QAReviewResult struct {
	Approved   bool
	MustFix    []string
	NiceToHave []string
	Unparsed   bool
	RawOutput  string
}

QAReviewResult is the structured outcome of a quality review.

type QATestPayload

type QATestPayload struct {
	Files          []string
	Plan           string
	ProjectContext string
	StageName      string
}

QATestPayload carries inputs for TDD test generation.

type QAVerifyResult

type QAVerifyResult struct {
	TestsOK      bool     // true = tests are correct, coder must try harder
	UpdatedFiles []string // test files that were rewritten (empty when TestsOK)
	Explanation  string   // brief reason for the verdict
}

QAVerifyResult is the outcome of a test verification.

type QAVerifyTestsPayload

type QAVerifyTestsPayload struct {
	Failure        string
	Files          []string // production source files (read-only context)
	TestFiles      []string // existing test files QA may modify
	ProjectContext string
}

QAVerifyTestsPayload asks QA to check whether existing tests are correct after the coder has failed multiple attempts.

type RnDAction

type RnDAction struct {
	Message    string
	CoderTask  string
	ProposeEnd bool
}

RnDAction is one PM turn in the R&D pipeline: a message to relay to the user, an optional quick coder task (proof-of-concept), and whether PM proposes ending the experiment because the concept is confirmed.

type SecurityAgent

type SecurityAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

SecurityAgent performs a dedicated security audit of the generated code.

func NewSecurityAgent

func NewSecurityAgent(b *bus.Bus, r runner.LLMRunner, ws artifacts.Workspace, skills []string, model string) *SecurityAgent

func (*SecurityAgent) ReviewPlan

func (a *SecurityAgent) ReviewPlan(ctx context.Context, planText, projectCtx string) (SecurityResult, error)

ReviewPlan audits an implementation plan (before any code exists) for security risks. It returns the structured result so the caller can surface MUST-FIX items to the human before the plan is approved.

func (*SecurityAgent) Role

func (a *SecurityAgent) Role() bus.AgentRole

func (*SecurityAgent) Run

func (a *SecurityAgent) Run(ctx context.Context, msg bus.Message) (bus.Message, error)

func (*SecurityAgent) SetMaxContextTokens

func (a *SecurityAgent) SetMaxContextTokens(n int)

SetMaxContextTokens configures the token budget for this agent.

type SecurityPayload

type SecurityPayload struct {
	Files   []string            // source files to review
	Root    string              // project root for reading files
	Seeds   []string            // optional seed paths (graph + semantic) to expand context
	Targets map[string][]string // file -> symbols for scoped-context shadow logging
}

SecurityPayload is the input for security review.

type SecurityResult

type SecurityResult struct {
	Approved   bool
	MustFix    []string
	NiceToHave []string
	Unparsed   bool
	RawOutput  string
}

SecurityResult is the structured outcome of a security review.

type SubTask

type SubTask struct {
	Key         string   `json:"key"`
	Title       string   `json:"title"`
	Description string   `json:"description"`
	Priority    int      `json:"priority"`
	DependsOn   []string `json:"depends_on,omitempty"`
}

SubTask is one decomposed unit of work that becomes a Beads issue and a single coder pass. `Key` is a local identifier (e.g. "T1") used to express ordering between sub-tasks via DependsOn before they are persisted as beads.

type TaskSpec

type TaskSpec struct {
	Title              string   `json:"title"`
	Description        string   `json:"description"`
	Scope              string   `json:"scope"`
	Pipeline           string   `json:"pipeline,omitempty"`
	AcceptanceCriteria []string `json:"acceptance_criteria"`
	Constraints        []string `json:"constraints,omitempty"`
	FilesToModify      []string `json:"files_to_modify,omitempty"`
}

TaskSpec is the PM's formalized understanding of a task.

type TestReport

type TestReport struct {
	Success  bool              `json:"success"`
	Commands []executil.Result `json:"commands"`
}

TestReport is the outcome of running a project's test suite.

type UXReviewResult

type UXReviewResult struct {
	Approved   bool
	MustFix    []string
	NiceToHave []string
	Unparsed   bool
	RawOutput  string
}

UXReviewResult is the structured outcome of a UX/UI review.

type UXReviewerAgent

type UXReviewerAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

UXReviewerAgent audits code for UX/UI quality, accessibility, and usability.

func NewUXReviewerAgent

func NewUXReviewerAgent(b *bus.Bus, r runner.LLMRunner, ws artifacts.Workspace, skills []string, model string) *UXReviewerAgent

func (*UXReviewerAgent) Role

func (a *UXReviewerAgent) Role() bus.AgentRole

func (*UXReviewerAgent) Run

func (a *UXReviewerAgent) Run(ctx context.Context, msg bus.Message) (bus.Message, error)

func (*UXReviewerAgent) SetMaxContextTokens

func (a *UXReviewerAgent) SetMaxContextTokens(n int)

SetMaxContextTokens configures the token budget for this agent.

type UXReviewerPayload

type UXReviewerPayload struct {
	Files   []string            // source files to review
	Root    string              // project root for reading files
	Seeds   []string            // optional seed paths (graph + semantic) to expand context
	Targets map[string][]string // file -> symbols for scoped-context shadow logging
}

UXReviewerPayload is the input for UX/UI review.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL