orchestrator

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package orchestrator composes services into workflows.

Package orchestrator provides session orchestration services.

Index

Constants

This section is empty.

Variables

View Source
var ErrQuestionNotEscalated = errors.New("question not in escalated channels")

ErrQuestionNotEscalated is returned by ResolveEscalated and SendUserMessage when no in-flight answer channel exists for the given question ID. This happens if the Foreman was restarted after escalation, or if the question was not escalated through the Foreman at all.

View Source
var ErrSessionNotRunning = errors.New("session is not running or not registered")

ErrSessionNotRunning indicates the target session is not in the registry.

Functions

func BuildWaves

func BuildWaves(subPlans []domain.TaskPlan) [][]domain.TaskPlan

BuildWaves groups sub-plans by Order into sequential execution waves. Sub-plans within a wave run concurrently; waves execute sequentially.

Example: SubPlans with Order values [0, 0, 1] produce 2 waves:

  • Wave 0: 2 parallel sub-plans
  • Wave 1: 1 sub-plan (runs after all wave 0 sub-plans complete)

func EnsureSessionDir

func EnsureSessionDir(workspaceDir, sessionID string) (domain.SessionDirInfo, error)

EnsureSessionDir creates the session directory and returns its info.

func GenerateBranchName

func GenerateBranchName(externalID, title string) string

GenerateBranchName creates a branch name from external ID and title. Format: sub-<sanitized-externalID>-<short-slug>

Example:

  • externalID: "LIN-FOO-123"

  • title: "Fix auth flow for OAuth2"

  • result: "sub-LIN-FOO-123-fix-auth-flow-for-oauth2"

  • externalID: "gh:issue:rtk-ai/rtk#591"

  • title: "Add support for Oh My Pi"

  • result: "sub-gh-issue-rtk-ai-rtk-591-add-support-for-oh-my-pi"

func NewAnswerRouter added in v0.2.0

func NewAnswerRouter(
	registry SessionRegistry,
	questionSvc *service.QuestionService,
	sessionSvc *service.AgentSessionService,
	eventBus event.Publisher,
) *answerRouter

NewAnswerRouter creates a new AnswerRouter.

func NewSessionRegistry

func NewSessionRegistry() *sessionRegistry

func PublishQuestionAnswered added in v0.0.34

func PublishQuestionAnswered(ctx context.Context, eventBus event.Publisher, questionID, sessionID string) error

func ReadWorkspaceAgentsMd

func ReadWorkspaceAgentsMd(workspaceDir string) (string, error)

ReadWorkspaceAgentsMd reads the workspace-root AGENTS.md file if it exists.

func ValidateBranchName

func ValidateBranchName(branch string) bool

ValidateBranchName checks if a branch name is valid per git check-ref-format rules. A valid branch name: - Starts with "sub-" - Contains no sequences invalid in git ref names (/, :, #, .., @{) - Does not end with . or .lock - Has non-empty content after "sub-" with no leading or trailing dash

Types

type AgentGraphIntent added in v0.2.0

type AgentGraphIntent struct {
	SourceSessionID   string
	WorkItemID        string
	SubPlanID         string
	Trigger           AgentGraphTrigger
	Feedback          string
	CurrentInstanceID string
}

type AgentGraphRunResult added in v0.2.0

type AgentGraphRunResult struct {
	SourceSession domain.AgentSession
	NewSession    domain.AgentSession
	Trigger       AgentGraphTrigger
}

type AgentGraphTrigger added in v0.2.0

type AgentGraphTrigger string
const (
	AgentGraphTriggerResumeInterrupted AgentGraphTrigger = "resume_interrupted"
	AgentGraphTriggerRetryFailed       AgentGraphTrigger = "retry_failed"
	AgentGraphTriggerFollowUpCompleted AgentGraphTrigger = "follow_up_completed"
	AgentGraphTriggerFollowUpFailed    AgentGraphTrigger = "follow_up_failed"
	AgentGraphTriggerAutoReimpl        AgentGraphTrigger = "auto_reimpl"
)

type AgentHarnessSelector added in v0.2.0

type AgentHarnessSelector interface {
	HarnessFor(kind domain.AgentSessionKind) adapter.AgentHarness
}

type AgentRunRequest added in v0.2.0

type AgentRunRequest struct {
	Session                  domain.AgentSession
	Opts                     adapter.SessionOpts
	CompleteContinuationKind string
	AfterStart               func(context.Context, adapter.AgentSession) error
	OnCompleted              func(context.Context, domain.AgentSession) error
	OnFailed                 func(context.Context, domain.AgentSession, error) error
	OnInterrupted            func(context.Context, domain.AgentSession) error
}

type AgentRunSupervisor added in v0.2.0

type AgentRunSupervisor struct {
	// contains filtered or unexported fields
}

func (*AgentRunSupervisor) Start added in v0.2.0

type AnswerRouter added in v0.2.0

type AnswerRouter interface {
	// Answer routes an answer based on the question's phase.
	// Publishes EventAgentQuestionAnswered on success.
	Answer(ctx context.Context, questionID, answer, answeredBy string) error

	// Skip routes a skip for a question based on its phase.
	// Publishes EventAgentQuestionAnswered on success.
	Skip(ctx context.Context, questionID string) error

	// RefineAnswer sends human follow-up text to get a revised answer proposal.
	// Returns the updated proposal so the UI can refresh.
	RefineAnswer(ctx context.Context, questionID, text string) (newProposal string, uncertain bool, err error)
}

AnswerRouter routes human answers and skips back to the correct handler based on question stage. It delegates to SessionRegistry and *Foreman based on the question's phase, looking up the foreman dynamically per question.

type ContinuationContext added in v0.2.0

type ContinuationContext struct {
	CompletedImplementationID string
	SupersededLeafID          string
	Trigger                   AgentGraphTrigger
	FirstReviewParentID       string
}

type ContinuationRecoveryResult added in v0.2.0

type ContinuationRecoveryResult struct {
	Recovered int
	Skipped   []ContinuationRecoverySkipped
}

type ContinuationRecoverySkipped added in v0.2.0

type ContinuationRecoverySkipped struct {
	ContinuationID string
	SessionID      string
	Status         domain.AgentSessionContinuationStatus
	Reason         string
}

type CorrectionTemplateData

type CorrectionTemplateData struct {
	Errors           string
	DiscoveredRepos  []string
	SessionDraftPath string
}

CorrectionTemplateData is data for the correction template.

type Discoverer

type Discoverer struct {
	// contains filtered or unexported fields
}

Discoverer handles workspace scanning and repo discovery.

func NewDiscoverer

func NewDiscoverer(gitClient *gitwork.Client, cfg *config.Config) *Discoverer

NewDiscoverer creates a new Discoverer.

func (*Discoverer) DiscoverRepos

func (d *Discoverer) DiscoverRepos(ctx context.Context, _ string, repoPaths []string) ([]domain.RepoPointer, error)

DiscoverRepos discovers git-work repos and builds RepoPointers with metadata.

func (*Discoverer) PreflightCheck

func (d *Discoverer) PreflightCheck(ctx context.Context, workspaceDir string) (domain.WorkspaceHealthCheck, error)

PreflightCheck scans the workspace for health issues. It identifies git-work repos, plain git clones, and other directories.

func (*Discoverer) PullMainWorktrees

func (d *Discoverer) PullMainWorktrees(ctx context.Context, repoPaths []string) RepoUpdateResults

PullMainWorktrees pulls the main worktree of each git-work repo and then runs gw sync to prune stale worktrees whose remote branches have been deleted. Failures are recorded but don't stop the process.

Calls within pullCooldown of the previous pull are skipped; this prevents redundant network I/O when multiple sessions start in rapid succession. The cooldown gates both the pull and sync passes as a unit.

type ExecutionState

type ExecutionState struct {
	PlanID      string
	CurrentWave int
	WaveStates  []WaveState
	Executions  map[string]*SubPlanExecution // sub-plan ID -> execution
	// contains filtered or unexported fields
}

ExecutionState tracks the overall state of plan implementation.

func NewExecutionState

func NewExecutionState(planID string, subPlans []domain.TaskPlan) *ExecutionState

NewExecutionState creates a new execution state for a plan. Completed sub-plans are filtered out by BuildWaves, so the execution state only tracks sub-plans that still need work.

func (*ExecutionState) AdvanceWave

func (s *ExecutionState) AdvanceWave() bool

AdvanceWave moves to the next wave if the current one is complete. Returns true if advanced, false if no more waves or current not complete.

func (*ExecutionState) AllWavesCompleted

func (s *ExecutionState) AllWavesCompleted() bool

AllWavesCompleted returns true if all waves have completed successfully.

func (*ExecutionState) CompleteSubPlan

func (s *ExecutionState) CompleteSubPlan(subPlanID string, completedAt int64)

CompleteSubPlan marks a sub-plan as completed.

func (*ExecutionState) CompleteWave

func (s *ExecutionState) CompleteWave(waveIndex int, endedAt int64)

CompleteWave marks a wave as completed.

func (*ExecutionState) CurrentWaveComplete

func (s *ExecutionState) CurrentWaveComplete() bool

CurrentWaveComplete returns true if the current wave has completed.

func (*ExecutionState) FailSubPlan

func (s *ExecutionState) FailSubPlan(subPlanID string, completedAt int64, err error)

FailSubPlan marks a sub-plan as failed.

func (*ExecutionState) FailWave

func (s *ExecutionState) FailWave(waveIndex int, endedAt int64)

FailWave marks a wave as failed.

func (*ExecutionState) GetWaveSubPlans

func (s *ExecutionState) GetWaveSubPlans(waveIndex int) []string

GetWaveSubPlans returns the sub-plan IDs for the given wave index.

func (*ExecutionState) HasFailed

func (s *ExecutionState) HasFailed() bool

HasFailed returns true if any wave or sub-plan has failed.

func (*ExecutionState) StartSubPlan

func (s *ExecutionState) StartSubPlan(subPlanID string, startedAt int64)

StartSubPlan marks a sub-plan as in progress.

func (*ExecutionState) StartWave

func (s *ExecutionState) StartWave(waveIndex int, startedAt int64)

StartWave marks a wave as running.

type FollowUpData

type FollowUpData struct {
	Feedback            string
	CurrentPlan         string
	RepoResults         []RepoResultSummary
	NewSessionDraftPath string
}

FollowUpData provides context for the follow-up planning template.

type Foreman

type Foreman struct {
	// contains filtered or unexported fields
}

Foreman manages a persistent oh-my-pi session for answering sub-agent questions.

func NewForeman

func NewForeman(
	cfg *config.Config,
	harness adapter.AgentHarness,
	planSvc *service.PlanService,
	questionSvc *service.QuestionService,
	agentSessionSvc *service.AgentSessionService,
	workItemSvc *service.SessionService,
	eventBus event.Publisher,
) *Foreman

NewForeman creates a new Foreman instance.

func (*Foreman) Ask

func (f *Foreman) Ask(ctx context.Context, q domain.Question) <-chan string

Ask sends a question to the foreman and returns a channel for the answer.

func (*Foreman) IsRunning

func (f *Foreman) IsRunning() bool

IsRunning reports whether the Foreman has an active session. Safe for concurrent use.

func (*Foreman) LastPlanID

func (f *Foreman) LastPlanID() string

LastPlanID returns the plan ID associated with the most recently stopped foreman session.

func (*Foreman) LastSessionID

func (f *Foreman) LastSessionID() string

LastSessionID returns the session ID of the most recently stopped foreman session. This allows the TUI to display the foreman's session log even after the foreman has been stopped. Returns "" if no session has ever run.

func (*Foreman) RefineAnswer added in v0.2.0

func (f *Foreman) RefineAnswer(ctx context.Context, questionID, text string) (newProposal string, uncertain bool, err error)

RefineAnswer sends human follow-up text to get a revised answer proposal. The escalation remains open; human must still call ResolveEscalated to finalize. This is the ForemanHandler interface implementation; it delegates to SendUserMessage.

func (*Foreman) ResolveEscalated

func (f *Foreman) ResolveEscalated(ctx context.Context, questionID, answer string) error

ResolveEscalated delivers a human-approved answer for a previously escalated question. Called by the TUI after the human iterates with the Foreman and presses [A]pprove. Records the answer in the DB and unblocks the waiting sub-agent.

func (*Foreman) SendUserMessage

func (f *Foreman) SendUserMessage(ctx context.Context, questionID, text string) (newProposal string, uncertain bool, err error)

SendUserMessage sends human follow-up text to the running Foreman session, waits for an updated proposed answer, persists it with UpdateProposal, and returns the new proposal so the TUI can refresh the question UI. The answer channel remains registered — the human must still call ResolveEscalated (or SkipQuestion) to actually unblock the sub-agent.

func (*Foreman) SessionID

func (f *Foreman) SessionID() string

SessionID returns the ID of the currently running foreman session. Returns "" if the Foreman has not been started or has been stopped.

func (*Foreman) Start

func (f *Foreman) Start(ctx context.Context, planID string, followUpContext string) error

Start begins the foreman session for a plan. If followUpContext is non-empty, it is included in the initial user prompt so the foreman is aware of follow-up feedback from the operator.

Start persists an AgentSessionKindForeman row if one does not already exist for this work item. Follow-up and restart reuse the same row so the sidebar always shows a single continuous Foreman entry.

func (*Foreman) Stop

func (f *Foreman) Stop(ctx context.Context) error

Idempotent: safe to call multiple times (e.g. re-implementation cycles where ImplementationCompleteMsg fires StopForemanCmd each time).

type ForemanLifecycle added in v0.2.0

type ForemanLifecycle interface {
	Start(ctx context.Context, planID string, followUpContext string) error
	Stop(ctx context.Context) error
	IsRunning() bool
}

ForemanLifecycle abstracts Foreman for use by orchestrators that need to control its lifecycle. Implemented by *Foreman.

type ImplementResult

type ImplementResult struct {
	PlanID        string
	WorkItemID    string
	State         *ExecutionState
	Sessions      []SessionResult
	Warnings      []ImplementationWarning
	ReviewResults map[string]*SubPlanOutcome // keyed by sub-plan ID
	CompletedAt   time.Time
}

ImplementResult contains the result of implementation execution.

type ImplementationConfig

type ImplementationConfig struct {
	SessionTimeout time.Duration
}

ImplementationConfig contains configuration for the implementation service.

func DefaultImplementationConfig

func DefaultImplementationConfig() *ImplementationConfig

DefaultImplementationConfig returns the default implementation configuration.

type ImplementationService

type ImplementationService struct {
	// contains filtered or unexported fields
}

ImplementationService orchestrates the implementation phase after plan approval. It manages wave-based execution of sub-plans, worktree creation, and agent sessions.

func NewImplementationService

func NewImplementationService(
	cfg *config.Config,
	harness adapter.AgentHarness,
	gitClient *gitwork.Client,
	eventBus event.Publisher,
	planSvc *service.PlanService,
	workItemSvc *service.SessionService,
	sessionSvc *service.AgentSessionService,
	continuationSvc *service.AgentSessionContinuationService,
	workspaceSvc *service.WorkspaceService,
	registry SessionRegistry,
	reviewPipeline *ReviewPipeline,
	foremanHarness adapter.AgentHarness,
	questionSvc *service.QuestionService,
	reviewSvc *service.ReviewService,
	hookRegistry *worktree.HookRegistry,
) *ImplementationService

func (*ImplementationService) BeginForeman added in v0.2.0

func (s *ImplementationService) BeginForeman(ctx context.Context, workItemID, planID string) error

BeginForeman starts a foreman for the work item, tied to the plan. Called when implementation starts (from TUI after plan approval, before Implement()). Creates a fresh *Foreman instance registered in SessionRegistry.

func (*ImplementationService) ContinueImplementationGraph added in v0.2.0

func (s *ImplementationService) ContinueImplementationGraph(ctx context.Context, cc ContinuationContext) error

ContinueImplementationGraph resumes the per-sub-plan pipeline starting from a completed implementation session and records durable continuation state for review, sub-plan, work-item, and finalization work.

func (*ImplementationService) EndForeman added in v0.2.0

func (s *ImplementationService) EndForeman(ctx context.Context, workItemID string) error

EndForeman stops the foreman for the work item. Called when implementation completes or is abandoned.

func (*ImplementationService) FinalizeWorkItem added in v0.0.35

func (s *ImplementationService) FinalizeWorkItem(ctx context.Context, workItemID string) (*ImplementResult, error)

FinalizeWorkItem retries the final commit/push/completion step for a work item whose repo tasks already finished.

func (*ImplementationService) Implement

func (s *ImplementationService) Implement(ctx context.Context, planID string) (result *ImplementResult, err error)

Implement starts the implementation phase for an approved plan. It executes sub-plans in waves, creating worktrees and spawning agent sessions.

func (*ImplementationService) RecoverContinuationsForWorkItem added in v0.2.1

func (s *ImplementationService) RecoverContinuationsForWorkItem(ctx context.Context, workItemID string) (ContinuationRecoveryResult, error)

RecoverContinuationsForWorkItem resumes interrupted implementation continuation work for one work item after an explicit operator action.

func (*ImplementationService) RecoverContinuationsForWorkspace added in v0.2.0

func (s *ImplementationService) RecoverContinuationsForWorkspace(ctx context.Context, workspaceID string) (ContinuationRecoveryResult, error)

RecoverContinuationsForWorkspace resumes interrupted implementation continuation work that was durably left pending or running by a prior process. Failed continuations are returned as skipped so UI/retry surfaces can expose the recorded error instead of silently replaying a known-bad continuation.

func (*ImplementationService) RestartForemanWithPlan added in v0.2.0

func (s *ImplementationService) RestartForemanWithPlan(ctx context.Context, workItemID, planID string) error

RestartForemanWithPlan stops and starts the foreman with the current plan. Called after replanning to update foreman's context with new plan/FAQ.

func (*ImplementationService) ResumeRetryLeavesForWorkItem added in v0.2.0

func (s *ImplementationService) ResumeRetryLeavesForWorkItem(ctx context.Context, workItemID string, mode ResumeRetryMode, instanceID string) (ResumeRetryDispatchResult, error)

ResumeRetryLeavesForWorkItem dispatches graph-managed resume or retry work for current leaves in a work item. Implementation and review leaves use the agent-session graph. Planning leaves are routed to PlanningService when it is wired. Foreman is restarted once for the current plan before implementation or review work so resumed agents have question routing available.

func (*ImplementationService) RetryReviewLeaf added in v0.2.0

RetryReviewLeaf reruns review continuation from a failed or interrupted review graph leaf while preserving the graph edge from that leaf to the replacement review session. The reviewed implementation is discovered by walking ancestors rather than assuming the review's direct parent is the implementation.

func (*ImplementationService) SetPlanningService added in v0.2.0

func (s *ImplementationService) SetPlanningService(planningSvc *PlanningService)

func (*ImplementationService) StartImplementationGraphRun added in v0.2.0

func (s *ImplementationService) StartImplementationGraphRun(ctx context.Context, intent AgentGraphIntent) (AgentGraphRunResult, error)

StartImplementationGraphRun starts an implementation child from a current implementation graph leaf, waits for that child, then runs the graph continuation. It is the graph-aware entry point for implementation resume/retry/follow-up paths; callers that must not block should dispatch it from a background goroutine.

type ImplementationWarning

type ImplementationWarning struct {
	Type      string // "worktree_exists", "session_failed", etc.
	Message   string
	RepoName  string
	SessionID string
}

ImplementationWarning represents a non-fatal issue during implementation.

type ManualSessionService added in v0.1.1

type ManualSessionService struct {
	// contains filtered or unexported fields
}

ManualSessionService orchestrates manual agent sessions within an existing work item. Unlike implementation sessions, manual sessions have no sub-plan context, no automatic commit/push, and no Foreman involvement. Questions are routed to the operator inline.

func NewManualSessionService added in v0.1.1

func NewManualSessionService(
	cfg *config.Config,
	harness adapter.AgentHarness,
	gitClient *gitwork.Client,
	sessionSvc *service.AgentSessionService,
	workItemSvc *service.SessionService,
	workspaceSvc *service.WorkspaceService,
	registry SessionRegistry,
	questionRouter *QuestionRouter,
	eventBus event.Publisher,
) *ManualSessionService

NewManualSessionService creates a new ManualSessionService.

func (*ManualSessionService) Abort added in v0.1.1

func (s *ManualSessionService) Abort(ctx context.Context, sessionID string) error

Abort aborts a running manual session.

func (*ManualSessionService) FollowUpManualSession added in v0.1.1

func (s *ManualSessionService) FollowUpManualSession(ctx context.Context, completed domain.AgentSession, message string) (domain.AgentSession, error)

FollowUpManualSession sends a follow-up message to a completed manual session. It reuses the same session row (completed → running) when native resume is available, otherwise starts a new session and links old→new via EventAgentSessionResumed.

func (*ManualSessionService) ResumeManualSession added in v0.1.1

func (s *ManualSessionService) ResumeManualSession(ctx context.Context, interrupted domain.AgentSession, initialMessage string, ownerInstanceID *string) (domain.AgentSession, error)

ResumeManualSession resumes an interrupted manual session with a new harness instance. It creates a new DB row in pending/running state and links to the interrupted session's resume info for native conversation resumption.

func (*ManualSessionService) SendAnswer added in v0.1.1

func (s *ManualSessionService) SendAnswer(ctx context.Context, sessionID, answer string) error

SendAnswer sends an operator answer to resolve a pending question in a manual session.

func (*ManualSessionService) SendMessage added in v0.1.1

func (s *ManualSessionService) SendMessage(ctx context.Context, sessionID, message string) error

SendMessage sends a follow-up message to a running manual session.

func (*ManualSessionService) StartManualSession added in v0.1.1

StartManualSession starts a new manual agent session in the deterministic worktree for the given work item and repository.

func (*ManualSessionService) Steer added in v0.1.1

func (s *ManualSessionService) Steer(ctx context.Context, sessionID, message string) error

Steer sends a steering prompt to interrupt a running manual session's active streaming turn.

type PlanParser

type PlanParser struct{}

PlanParser parses planning agent output into structured data.

func NewPlanParser

func NewPlanParser() *PlanParser

NewPlanParser creates a new PlanParser.

func (*PlanParser) Parse

func (p *PlanParser) Parse(content string) (domain.RawPlanOutput, domain.ParseErrors)

Parse reads plan content and extracts structured data.

func (*PlanParser) ParseAndValidate

func (p *PlanParser) ParseAndValidate(content string, discoveredRepos []domain.RepoPointer) (domain.RawPlanOutput, domain.ParseErrors)

ParseAndValidate combines parsing and validation.

func (*PlanParser) Validate

func (p *PlanParser) Validate(output domain.RawPlanOutput, discoveredRepos []domain.RepoPointer) domain.ParseErrors

Validate checks that the parsed plan is consistent with discovered repos.

type PlanningConfig

type PlanningConfig struct {
	MaxParseRetries int
}

PlanningConfig contains configuration for the planning pipeline.

func DefaultPlanningConfig

func DefaultPlanningConfig() *PlanningConfig

DefaultPlanningConfig returns the default planning configuration.

func PlanningConfigFromConfig

func PlanningConfigFromConfig(cfg *config.Config) *PlanningConfig

PlanningConfigFromConfig extracts planning config from global config.

type PlanningError

type PlanningError struct {
	Err         error
	ParseErrors *domain.ParseErrors
}

PlanningError represents a planning failure with optional parse errors.

func (*PlanningError) Error

func (e *PlanningError) Error() string

func (*PlanningError) Unwrap

func (e *PlanningError) Unwrap() error

type PlanningService

type PlanningService struct {
	// contains filtered or unexported fields
}

PlanningService orchestrates the planning pipeline.

func NewPlanningService

func NewPlanningService(
	cfg *PlanningConfig,
	discoverer *Discoverer,
	gitClient *gitwork.Client,
	harness adapter.AgentHarness,
	planSvc *service.PlanService,
	workItemSvc *service.SessionService,
	sessionSvc *service.AgentSessionService,
	eventBus event.Publisher,
	workspaceSvc *service.WorkspaceService,
	registry SessionRegistry,
	questionSvc *service.QuestionService,
	globalCfg *config.Config,
) (*PlanningService, error)

func (*PlanningService) FollowUpPlan

func (s *PlanningService) FollowUpPlan(ctx context.Context, workItemID, feedback string) (*domain.PlanningResult, error)

func (*PlanningService) Plan

func (s *PlanningService) Plan(ctx context.Context, workItemID string) (*domain.PlanningResult, error)

Plan executes the planning pipeline for a work item, transitioning it to planning state.

func (*PlanningService) PlanWithFeedback

func (s *PlanningService) PlanWithFeedback(ctx context.Context, workItemID, oldPlanID, feedback string) (*domain.PlanningResult, error)

PlanWithFeedback runs a revision planning session for a work item in plan_review state. It rejects the existing plan and re-plans with the human's feedback. When the prior planning session produced resume data, the session is resumed natively so the model retains full conversation context of what it planned.

func (*PlanningService) ResumeInterruptedPlanning added in v0.2.0

func (s *PlanningService) ResumeInterruptedPlanning(ctx context.Context, interrupted domain.AgentSession, prompt string) (*domain.PlanningResult, error)

ResumeInterruptedPlanning resumes an interrupted planning session with native harness resume data when available. The interrupted session remains as audit history; planRun creates a replacement planning agent session.

func (*PlanningService) UpdateReviewedPlan

func (s *PlanningService) UpdateReviewedPlan(ctx context.Context, planID, rawContent string) (domain.Plan, []domain.TaskPlan, error)

UpdateReviewedPlan validates and persists a full reviewed plan document in place.

type PlanningTemplates

type PlanningTemplates struct {
	// contains filtered or unexported fields
}

PlanningTemplates holds compiled templates.

func NewPlanningTemplates

func NewPlanningTemplates() (*PlanningTemplates, error)

NewPlanningTemplates creates compiled templates.

type QuestionRouter added in v0.0.33

type QuestionRouter struct {
	// contains filtered or unexported fields
}

QuestionRouter is the single stage-aware routing point for normalized agent questions. It looks up the correct foreman dynamically per question using the work item ID.

func NewQuestionRouter added in v0.0.33

func NewQuestionRouter(questionSvc *service.QuestionService, sessionSvc *service.AgentSessionService, registry SessionRegistry, eventBus event.Publisher) *QuestionRouter

func (*QuestionRouter) Route added in v0.0.33

func (r *QuestionRouter) Route(ctx context.Context, kind domain.AgentSessionKind, evt adapter.AgentEvent, sessionID string) error

type RepoFinalizationResult added in v0.1.0

type RepoFinalizationResult struct {
	SubPlanID    string
	Repository   string
	WorktreePath string
	Branch       string
	Review       domain.ReviewRef
	Err          error
}

RepoFinalizationResult contains the result of finalizing a single repo's branch. Used by the orchestrator to emit EventSubPlanPRReady per sub-plan after successful push.

type RepoResultSummary

type RepoResultSummary struct {
	RepoName string
	Status   string
	LogTail  string
}

RepoResultSummary holds the implementation outcome for a single repository.

type RepoUpdateResults

type RepoUpdateResults struct {
	PullFailures []domain.PullFailure
}

RepoUpdateResults holds the outcomes of a combined pull-and-sync pass over all git-work repos. Sync failures are logged internally and not returned; they are maintenance-only and must not surface as planning warnings or toasts.

type ResumeRetryDispatchResult added in v0.2.0

type ResumeRetryDispatchResult struct {
	Accepted int
	Skipped  []ResumeRetrySkippedLeaf
}

type ResumeRetryMode added in v0.2.0

type ResumeRetryMode string
const (
	ResumeRetryModeResumeInterrupted ResumeRetryMode = "resume_interrupted"
	ResumeRetryModeRetryFailed       ResumeRetryMode = "retry_failed"
)

type ResumeRetrySkippedLeaf added in v0.2.0

type ResumeRetrySkippedLeaf struct {
	SessionID string
	Kind      domain.AgentSessionKind
	Status    domain.AgentSessionStatus
	Reason    string
}

type ReviewFollowup added in v0.2.0

type ReviewFollowup struct {
	// contains filtered or unexported fields
}

ReviewFollowup orchestrates a follow-up agent session and the associated Foreman lifecycle. It is the single owner of Foreman Start/Stop for follow-up sessions.

func NewReviewFollowup added in v0.2.0

func NewReviewFollowup(
	cfg *config.Config,
	harness adapter.AgentHarness,
	registry SessionRegistry,
	planSvc *service.PlanService,
	questionSvc *service.QuestionService,
	sessionSvc *service.AgentSessionService,
	workItemSvc *service.SessionService,
	eventBus event.Publisher,
) *ReviewFollowup

NewReviewFollowup creates a new ReviewFollowup instance.

func (*ReviewFollowup) FollowUp added in v0.2.0

func (r *ReviewFollowup) FollowUp(ctx context.Context, workItemID, feedback string) error

FollowUp restarts the foreman with follow-up context. Gets the current foreman, stops it, starts new one with feedback.

func (*ReviewFollowup) FollowUpFailed added in v0.2.0

func (r *ReviewFollowup) FollowUpFailed(ctx context.Context, workItemID, feedback string) error

FollowUpFailed handles the failed follow-up case. Similar to FollowUp but may include different context about what failed.

type ReviewPipeline

type ReviewPipeline struct {
	// contains filtered or unexported fields
}

ReviewPipeline orchestrates the review process for agent sessions.

func NewReviewPipeline

func NewReviewPipeline(
	cfg *config.Config,
	harness adapter.AgentHarness,
	reviewSvc *service.ReviewService,
	sessionSvc *service.AgentSessionService,
	planSvc *service.PlanService,
	workItemSvc *service.SessionService,
	eventBus event.Publisher,
	registry SessionRegistry,
) *ReviewPipeline

NewReviewPipeline creates a new ReviewPipeline instance.

func (*ReviewPipeline) ReviewSession

func (p *ReviewPipeline) ReviewSession(ctx context.Context, agentSession domain.AgentSession) (result *ReviewResult, err error)

ReviewSession reviews an agent session's output. If an error is returned after the new review cycle has been created, the cycle is durably transitioned to `failed` so it does not linger in `reviewing` and mask outstanding critiques on prior cycles for the same impl session.

func (*ReviewPipeline) ReviewSessionWithParent added in v0.2.0

func (p *ReviewPipeline) ReviewSessionWithParent(ctx context.Context, agentSession domain.AgentSession, reviewParentSessionID string) (result *ReviewResult, err error)

ReviewSessionWithParent reviews an implementation session's output while allowing retry/recovery callers to link the new review agent session to the graph leaf it supersedes. The reviewed implementation remains agentSession; reviewParentSessionID controls only the agent-session graph edge.

type ReviewResult

type ReviewResult struct {
	Passed      bool
	Critiques   []domain.Critique
	CycleNumber int
	NeedsReimpl bool
	Escalated   bool
	SessionID   string // review agent session ID — log at config.SessionsDir()/<SessionID>.log
}

ReviewResult contains the result of a review.

type RevisionData

type RevisionData struct {
	Feedback            string
	CurrentPlan         string
	NewSessionDraftPath string
}

RevisionData contains data for the revision template.

type SessionRegistry

type SessionRegistry interface {
	// Session management
	Register(sessionID string, session adapter.AgentSession)
	Deregister(sessionID string)
	SendMessage(ctx context.Context, sessionID string, msg string) error
	Steer(ctx context.Context, sessionID string, msg string) error
	SendAnswer(ctx context.Context, sessionID string, answer string) error
	IsRunning(sessionID string) bool
	Registered(sessionID string) (adapter.AgentSession, bool)
	AbortAndDeregister(ctx context.Context, sessionID string)

	// Foreman management (per work item)
	RegisterForeman(workItemID string, foreman *Foreman)
	GetForeman(workItemID string) *Foreman
	DeregisterForeman(workItemID string)

	// Close shuts down all registered sessions and foremen.
	// Called during application shutdown. Uses context.WithoutCancel to ensure
	// graceful shutdown completes even if the provided context is cancelled.
	Close(ctx context.Context)
}

SessionRegistry abstracts session and foreman registration. The concrete implementation is *sessionRegistry; consumers use this interface.

type SessionResult

type SessionResult struct {
	SessionID    string
	SubPlanID    string
	Repository   string
	WorktreePath string
	Branch       string
	Status       domain.AgentSessionStatus
	StartedAt    time.Time
	CompletedAt  *time.Time
	ExitCode     *int
	Summary      string
	Errors       []string
	Outcome      *SubPlanOutcome // populated after review loop completes
}

SessionResult contains the result of a single agent session.

type StartManualSessionRequest added in v0.1.1

type StartManualSessionRequest struct {
	WorkItemID      string
	WorkspaceID     string
	RepositoryName  string
	InitialMessage  string
	SubPlanID       string // optional context only
	OwnerInstanceID *string
}

StartManualSessionRequest contains the parameters for starting a manual session.

type SubPlanExecution

type SubPlanExecution struct {
	SubPlanID   string
	Order       int
	WaveIndex   int
	Status      domain.TaskPlanStatus
	StartedAt   int64 // Unix nano timestamp
	CompletedAt int64 // Unix nano timestamp
	Error       error
}

SubPlanExecution represents the execution state of a single sub-plan.

type SubPlanOutcome

type SubPlanOutcome struct {
	SubPlanID    string
	Repository   string
	Passed       bool
	Escalated    bool
	Failed       bool
	ReviewResult *ReviewResult // nil when review was skipped (impl failed or no pipeline)
	Cycles       int           // total impl→review cycles executed
}

SubPlanOutcome captures the final state of a sub-plan after the full implement→review→reimpl cycle.

type WaveState

type WaveState struct {
	Index      int
	Status     WaveStatus
	SubPlanIDs []string
	StartedAt  int64 // Unix nano timestamp
	EndedAt    int64 // Unix nano timestamp
}

WaveState tracks the execution state of a single wave.

type WaveStatus

type WaveStatus string

WaveStatus represents the status of a wave during execution.

const (
	WavePending   WaveStatus = "pending"
	WaveRunning   WaveStatus = "running"
	WaveCompleted WaveStatus = "completed"
	WaveFailed    WaveStatus = "failed"
)

type WorktreeCreatedPayload

type WorktreeCreatedPayload struct {
	WorkspaceID   string                    `json:"workspace_id"`
	WorkItemID    string                    `json:"work_item_id"`
	Repository    string                    `json:"repository"`
	Branch        string                    `json:"branch"`
	WorktreePath  string                    `json:"worktree_path"`
	WorkItemTitle string                    `json:"work_item_title"`
	SubPlan       string                    `json:"sub_plan"`
	TrackerRefs   []domain.TrackerReference `json:"tracker_refs"`
	Review        domain.ReviewRef          `json:"review"`
}

type WorktreeCreatingPayload

type WorktreeCreatingPayload struct {
	WorkspaceID   string           `json:"workspace_id"`
	WorkItemID    string           `json:"work_item_id"`
	Repository    string           `json:"repository"`
	Branch        string           `json:"branch"`
	WorkItemTitle string           `json:"work_item_title"`
	SubPlan       string           `json:"sub_plan"`
	Review        domain.ReviewRef `json:"review"`
}

Jump to

Keyboard shortcuts

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