Documentation
¶
Overview ¶
Package ralph provides autonomous loop execution for Claude Code agents.
Index ¶
- Constants
- func CountCompletionIndicators(output string) int
- func DetectRateLimitError(output string) bool
- func ExtractErrorSignature(output string) string
- type AnalysisResult
- type CircuitBreaker
- func (cb *CircuitBreaker) Check() bool
- func (cb *CircuitBreaker) ConsecutiveTestLoops() int
- func (cb *CircuitBreaker) IsTripped() bool
- func (cb *CircuitBreaker) NoProgressCount() int
- func (cb *CircuitBreaker) Reset()
- func (cb *CircuitBreaker) RestoreState(state CircuitBreakerState)
- func (cb *CircuitBreaker) SameErrorCount() int
- func (cb *CircuitBreaker) State() CircuitBreakerState
- func (cb *CircuitBreaker) Threshold() int
- func (cb *CircuitBreaker) TripReason() string
- func (cb *CircuitBreaker) Update(status *Status) (tripped bool, reason string)
- func (cb *CircuitBreaker) UpdateWithAnalysis(status *Status, analysis *AnalysisResult) UpdateResult
- type CircuitBreakerConfig
- type CircuitBreakerState
- type CircuitHistory
- type CircuitHistoryEntry
- type CircuitState
- type Config
- func (c Config) GetCallsPerHour() int
- func (c Config) GetCompletionThreshold() int
- func (c Config) GetLoopDelaySeconds() int
- func (c Config) GetMaxConsecutiveTestLoops() int
- func (c Config) GetMaxLoops() int
- func (c Config) GetOutputDeclineThreshold() int
- func (c Config) GetSafetyCompletionThreshold() int
- func (c Config) GetSameErrorThreshold() int
- func (c Config) GetSessionExpirationHours() int
- func (c Config) GetStagnationThreshold() int
- func (c Config) Timeout() time.Duration
- type HistoryStore
- func (h *HistoryStore) AddCircuitEntry(project, agent, fromState, toState, reason string, ...) error
- func (h *HistoryStore) AddSessionEntry(project, agent, event, status, errorMsg string, loopCount int) error
- func (h *HistoryStore) DeleteCircuitHistory(project, agent string) error
- func (h *HistoryStore) DeleteSessionHistory(project, agent string) error
- func (h *HistoryStore) LoadCircuitHistory(project, agent string) (*CircuitHistory, error)
- func (h *HistoryStore) LoadSessionHistory(project, agent string) (*SessionHistory, error)
- func (h *HistoryStore) SaveCircuitHistory(history *CircuitHistory) error
- func (h *HistoryStore) SaveSessionHistory(history *SessionHistory) error
- type LoopOptions
- type LoopResult
- type Monitor
- func (m *Monitor) FormatAPILimitError(isInteractive bool) string
- func (m *Monitor) FormatLoopEnd(loopNum int, status *Status, err error, outputSize int, elapsed time.Duration) string
- func (m *Monitor) FormatLoopProgress(loopNum int, status *Status, circuit *CircuitBreaker) string
- func (m *Monitor) FormatLoopStart(loopNum int) string
- func (m *Monitor) FormatRateLimitWait(resetTime time.Time) string
- func (m *Monitor) FormatResult(result *LoopResult) string
- func (m *Monitor) PrintLoopEnd(loopNum int, status *Status, err error, outputSize int, elapsed time.Duration)
- func (m *Monitor) PrintLoopProgress(loopNum int, status *Status, circuit *CircuitBreaker)
- func (m *Monitor) PrintLoopStart(loopNum int)
- func (m *Monitor) PrintResult(result *LoopResult)
- type MonitorOptions
- type RateLimitState
- type RateLimiter
- func (r *RateLimiter) Allow() bool
- func (r *RateLimiter) CallCount() int
- func (r *RateLimiter) IsEnabled() bool
- func (r *RateLimiter) Limit() int
- func (r *RateLimiter) Record()
- func (r *RateLimiter) Remaining() int
- func (r *RateLimiter) ResetTime() time.Time
- func (r *RateLimiter) RestoreState(state RateLimitState) bool
- func (r *RateLimiter) State() RateLimitState
- type Runner
- func (r *Runner) ExecCapture(ctx context.Context, containerName string, cmd []string, onOutput func([]byte)) (string, int, error)
- func (r *Runner) GetCircuitState(project, agent string) (*CircuitState, error)
- func (r *Runner) GetSession(project, agent string) (*Session, error)
- func (r *Runner) ResetCircuit(project, agent string) error
- func (r *Runner) ResetSession(project, agent string) error
- func (r *Runner) Run(ctx context.Context, opts LoopOptions) (*LoopResult, error)
- type Session
- type SessionHistory
- type SessionHistoryEntry
- type SessionStore
- func (s *SessionStore) DeleteCircuitState(project, agent string) error
- func (s *SessionStore) DeleteSession(project, agent string) error
- func (s *SessionStore) LoadCircuitState(project, agent string) (*CircuitState, error)
- func (s *SessionStore) LoadSession(project, agent string) (*Session, error)
- func (s *SessionStore) LoadSessionWithExpiration(project, agent string, expirationHours int) (*Session, bool, error)
- func (s *SessionStore) SaveCircuitState(state *CircuitState) error
- func (s *SessionStore) SaveSession(session *Session) error
- type Status
- type UpdateResult
Constants ¶
const ( WorkTypeImplementation = "IMPLEMENTATION" WorkTypeTesting = "TESTING" WorkTypeDocumentation = "DOCUMENTATION" WorkTypeRefactoring = "REFACTORING" )
Work type constants.
const ( DefaultMaxLoops = 50 DefaultStagnationThreshold = 3 DefaultTimeoutMinutes = 15 DefaultCallsPerHour = 100 DefaultCompletionThreshold = 2 DefaultSessionExpirationHours = 24 DefaultSameErrorThreshold = 5 DefaultOutputDeclineThreshold = 70 DefaultMaxConsecutiveTestLoops = 3 DefaultSafetyCompletionThreshold = 5 // Force exit after N consecutive loops with completion indicators DefaultLoopDelaySeconds = 3 // Seconds to wait between loop iterations )
Default configuration values.
const (
// MaxHistoryEntries is the maximum number of history entries to keep.
MaxHistoryEntries = 50
)
const StatusBlocked = "BLOCKED"
StatusBlocked indicates the agent is blocked.
const StatusComplete = "COMPLETE"
StatusComplete indicates the task is complete.
const StatusPending = "IN_PROGRESS"
StatusPending indicates work is still in progress.
const TestsFailing = "FAILING"
TestsFailing indicates tests are failing.
const TestsNotRun = "NOT_RUN"
TestsNotRun indicates tests were not run.
const TestsPassing = "PASSING"
TestsPassing indicates tests are passing.
Variables ¶
This section is empty.
Functions ¶
func CountCompletionIndicators ¶
CountCompletionIndicators counts how many completion phrases appear in the output.
func DetectRateLimitError ¶
DetectRateLimitError checks if the output contains Claude's rate limit error. Returns true if a rate limit error is detected.
func ExtractErrorSignature ¶
ExtractErrorSignature extracts a normalized error signature from output. The signature can be used to detect repeated identical errors. Returns empty string if no error pattern is found.
Types ¶
type AnalysisResult ¶
type AnalysisResult struct {
Status *Status
RateLimitHit bool
ErrorSignature string
OutputSize int
CompletionCount int
}
AnalysisResult contains the full analysis of a loop's output.
func AnalyzeOutput ¶
func AnalyzeOutput(output string) *AnalysisResult
AnalyzeOutput performs full analysis of a loop's output.
type CircuitBreaker ¶
type CircuitBreaker struct {
// contains filtered or unexported fields
}
CircuitBreaker detects stagnation in Ralph loops. It tracks consecutive loops without progress and trips when the threshold is exceeded. It also tracks same-error sequences, output decline, and consecutive test-only loops.
func NewCircuitBreaker ¶
func NewCircuitBreaker(threshold int) *CircuitBreaker
NewCircuitBreaker creates a new circuit breaker with the given threshold.
func NewCircuitBreakerWithConfig ¶
func NewCircuitBreakerWithConfig(cfg CircuitBreakerConfig) *CircuitBreaker
NewCircuitBreakerWithConfig creates a circuit breaker with full configuration.
func (*CircuitBreaker) Check ¶
func (cb *CircuitBreaker) Check() bool
Check returns true if the circuit is still open (not tripped).
func (*CircuitBreaker) ConsecutiveTestLoops ¶
func (cb *CircuitBreaker) ConsecutiveTestLoops() int
ConsecutiveTestLoops returns the count of consecutive test-only loops.
func (*CircuitBreaker) IsTripped ¶
func (cb *CircuitBreaker) IsTripped() bool
IsTripped returns true if the circuit has tripped.
func (*CircuitBreaker) NoProgressCount ¶
func (cb *CircuitBreaker) NoProgressCount() int
NoProgressCount returns the current count of loops without progress.
func (*CircuitBreaker) Reset ¶
func (cb *CircuitBreaker) Reset()
Reset clears the circuit breaker state.
func (*CircuitBreaker) RestoreState ¶
func (cb *CircuitBreaker) RestoreState(state CircuitBreakerState)
RestoreState restores circuit breaker state from persistence.
func (*CircuitBreaker) SameErrorCount ¶
func (cb *CircuitBreaker) SameErrorCount() int
SameErrorCount returns the current count of same-error loops.
func (*CircuitBreaker) State ¶
func (cb *CircuitBreaker) State() CircuitBreakerState
State returns the current circuit breaker state for persistence.
func (*CircuitBreaker) Threshold ¶
func (cb *CircuitBreaker) Threshold() int
Threshold returns the configured stagnation threshold.
func (*CircuitBreaker) TripReason ¶
func (cb *CircuitBreaker) TripReason() string
TripReason returns the reason the circuit tripped, or empty if not tripped.
func (*CircuitBreaker) Update ¶
func (cb *CircuitBreaker) Update(status *Status) (tripped bool, reason string)
Update evaluates the status and updates the circuit breaker state. Returns true and a reason if the circuit has tripped.
func (*CircuitBreaker) UpdateWithAnalysis ¶
func (cb *CircuitBreaker) UpdateWithAnalysis(status *Status, analysis *AnalysisResult) UpdateResult
UpdateWithAnalysis evaluates the full analysis and updates circuit state. Provides more detailed results including completion detection.
type CircuitBreakerConfig ¶
type CircuitBreakerConfig struct {
StagnationThreshold int
SameErrorThreshold int
OutputDeclineThreshold int
MaxConsecutiveTestLoops int
CompletionThreshold int
SafetyCompletionThreshold int
}
CircuitBreakerConfig holds configuration for the circuit breaker.
func DefaultCircuitBreakerConfig ¶
func DefaultCircuitBreakerConfig() CircuitBreakerConfig
DefaultCircuitBreakerConfig returns default configuration.
type CircuitBreakerState ¶
type CircuitBreakerState struct {
NoProgressCount int `json:"no_progress_count"`
Tripped bool `json:"tripped"`
TripReason string `json:"trip_reason,omitempty"`
SameErrorCount int `json:"same_error_count"`
LastErrorSignature string `json:"last_error_signature,omitempty"`
DeclineCount int `json:"decline_count"`
LastOutputSize int `json:"last_output_size"`
ConsecutiveTestLoops int `json:"consecutive_test_loops"`
ConsecutiveCompletionCount int `json:"consecutive_completion_count"`
}
CircuitBreakerState holds the state for persistence.
type CircuitHistory ¶
type CircuitHistory struct {
Project string `json:"project"`
Agent string `json:"agent"`
Entries []CircuitHistoryEntry `json:"entries"`
}
CircuitHistory tracks circuit breaker state changes.
type CircuitHistoryEntry ¶
type CircuitHistoryEntry struct {
Timestamp time.Time `json:"timestamp"`
FromState string `json:"from_state"` // closed, tripped
ToState string `json:"to_state"`
Reason string `json:"reason,omitempty"`
NoProgressCount int `json:"no_progress_count"`
SameErrorCount int `json:"same_error_count,omitempty"`
TestLoopCount int `json:"test_loop_count,omitempty"`
CompletionCount int `json:"completion_count,omitempty"`
}
CircuitHistoryEntry represents a circuit breaker state change.
type CircuitState ¶
type CircuitState struct {
Project string `json:"project"`
Agent string `json:"agent"`
NoProgressCount int `json:"no_progress_count"`
Tripped bool `json:"tripped"`
TripReason string `json:"trip_reason,omitempty"`
TrippedAt *time.Time `json:"tripped_at,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
CircuitState represents the persistent state of the circuit breaker.
type Config ¶
type Config struct {
MaxLoops int `yaml:"max_loops" mapstructure:"max_loops"`
StagnationThreshold int `yaml:"stagnation_threshold" mapstructure:"stagnation_threshold"`
TimeoutMinutes int `yaml:"timeout_minutes" mapstructure:"timeout_minutes"`
AutoConfirm bool `yaml:"auto_confirm" mapstructure:"auto_confirm"`
CallsPerHour int `yaml:"calls_per_hour" mapstructure:"calls_per_hour"`
CompletionThreshold int `yaml:"completion_threshold" mapstructure:"completion_threshold"`
SessionExpirationHours int `yaml:"session_expiration_hours" mapstructure:"session_expiration_hours"`
SameErrorThreshold int `yaml:"same_error_threshold" mapstructure:"same_error_threshold"`
OutputDeclineThreshold int `yaml:"output_decline_threshold" mapstructure:"output_decline_threshold"`
MaxConsecutiveTestLoops int `yaml:"max_consecutive_test_loops" mapstructure:"max_consecutive_test_loops"`
LoopDelaySeconds int `yaml:"loop_delay_seconds" mapstructure:"loop_delay_seconds"`
SafetyCompletionThreshold int `yaml:"safety_completion_threshold" mapstructure:"safety_completion_threshold"`
}
Config holds Ralph-specific configuration.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the default Ralph configuration.
func (Config) GetCallsPerHour ¶
GetCallsPerHour returns the calls per hour limit with default fallback. Returns 0 to disable rate limiting.
func (Config) GetCompletionThreshold ¶
GetCompletionThreshold returns the completion indicator threshold with default fallback.
func (Config) GetLoopDelaySeconds ¶
GetLoopDelaySeconds returns the loop delay in seconds with default fallback.
func (Config) GetMaxConsecutiveTestLoops ¶
GetMaxConsecutiveTestLoops returns the max consecutive test loops with default fallback.
func (Config) GetMaxLoops ¶
GetMaxLoops returns the max loops with default fallback.
func (Config) GetOutputDeclineThreshold ¶
GetOutputDeclineThreshold returns the output decline threshold percentage with default fallback.
func (Config) GetSafetyCompletionThreshold ¶
GetSafetyCompletionThreshold returns the safety completion threshold with default fallback.
func (Config) GetSameErrorThreshold ¶
GetSameErrorThreshold returns the same error threshold with default fallback.
func (Config) GetSessionExpirationHours ¶
GetSessionExpirationHours returns the session expiration hours with default fallback.
func (Config) GetStagnationThreshold ¶
GetStagnationThreshold returns the stagnation threshold with default fallback.
type HistoryStore ¶
type HistoryStore struct {
// contains filtered or unexported fields
}
HistoryStore manages history persistence.
func DefaultHistoryStore ¶
func DefaultHistoryStore() (*HistoryStore, error)
DefaultHistoryStore returns a history store using the default clawker directory.
func NewHistoryStore ¶
func NewHistoryStore(baseDir string) *HistoryStore
NewHistoryStore creates a new history store at the given base directory.
func (*HistoryStore) AddCircuitEntry ¶
func (h *HistoryStore) AddCircuitEntry(project, agent, fromState, toState, reason string, noProgressCount, sameErrorCount, testLoopCount, completionCount int) error
AddCircuitEntry adds an entry to circuit history, trimming to MaxHistoryEntries.
func (*HistoryStore) AddSessionEntry ¶
func (h *HistoryStore) AddSessionEntry(project, agent, event, status, errorMsg string, loopCount int) error
AddSessionEntry adds an entry to session history, trimming to MaxHistoryEntries.
func (*HistoryStore) DeleteCircuitHistory ¶
func (h *HistoryStore) DeleteCircuitHistory(project, agent string) error
DeleteCircuitHistory removes circuit history from disk.
func (*HistoryStore) DeleteSessionHistory ¶
func (h *HistoryStore) DeleteSessionHistory(project, agent string) error
DeleteSessionHistory removes session history from disk.
func (*HistoryStore) LoadCircuitHistory ¶
func (h *HistoryStore) LoadCircuitHistory(project, agent string) (*CircuitHistory, error)
LoadCircuitHistory loads circuit history from disk. Returns an empty history if no file exists.
func (*HistoryStore) LoadSessionHistory ¶
func (h *HistoryStore) LoadSessionHistory(project, agent string) (*SessionHistory, error)
LoadSessionHistory loads session history from disk. Returns an empty history if no file exists.
func (*HistoryStore) SaveCircuitHistory ¶
func (h *HistoryStore) SaveCircuitHistory(history *CircuitHistory) error
SaveCircuitHistory saves circuit history to disk.
func (*HistoryStore) SaveSessionHistory ¶
func (h *HistoryStore) SaveSessionHistory(history *SessionHistory) error
SaveSessionHistory saves session history to disk.
type LoopOptions ¶
type LoopOptions struct {
// ContainerName is the full container name (clawker.project.agent).
ContainerName string
// Project is the project name.
Project string
// Agent is the agent name.
Agent string
// Prompt is the initial prompt (used only on first loop if provided).
Prompt string
// MaxLoops is the maximum number of loops to run.
MaxLoops int
// StagnationThreshold is how many loops without progress before tripping.
StagnationThreshold int
// Timeout is the per-loop timeout.
Timeout time.Duration
// ResetCircuit resets the circuit breaker before starting.
ResetCircuit bool
// CallsPerHour is the rate limit (0 to disable).
CallsPerHour int
// CompletionThreshold is the number of completion indicators required.
CompletionThreshold int
// SessionExpirationHours is the session TTL (0 for default).
SessionExpirationHours int
// SameErrorThreshold is how many same-error loops before tripping.
SameErrorThreshold int
// OutputDeclineThreshold is the percentage decline that triggers trip.
OutputDeclineThreshold int
// MaxConsecutiveTestLoops is how many test-only loops before tripping.
MaxConsecutiveTestLoops int
// LoopDelaySeconds is the delay between loop iterations.
LoopDelaySeconds int
// UseStrictCompletion requires both EXIT_SIGNAL and completion indicators.
UseStrictCompletion bool
// SkipPermissions passes --dangerously-skip-permissions to claude.
SkipPermissions bool
// Monitor is the optional monitor for live output.
Monitor *Monitor
// Verbose enables verbose logging.
Verbose bool
// OnLoopStart is called before each loop iteration.
OnLoopStart func(loopNum int)
// OnLoopEnd is called after each loop iteration.
OnLoopEnd func(loopNum int, status *Status, err error)
// OnOutput is called with output chunks during execution.
OnOutput func(chunk []byte)
// OnRateLimitHit is called when Claude's API limit is detected.
// Return true to wait and retry, false to exit.
OnRateLimitHit func() bool
}
LoopOptions configures the Ralph loop execution.
type LoopResult ¶
type LoopResult struct {
// LoopsCompleted is the number of loops that ran.
LoopsCompleted int
// FinalStatus is the last parsed status.
FinalStatus *Status
// ExitReason describes why the loop exited.
ExitReason string
// Session is the final session state.
Session *Session
// Error is set if the loop exited due to an error.
Error error
// RateLimitHit is true if the loop hit Claude's API rate limit.
RateLimitHit bool
}
LoopResult represents the outcome of running the Ralph loop.
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor provides real-time progress output for Ralph loops.
func NewMonitor ¶
func NewMonitor(opts MonitorOptions) *Monitor
NewMonitor creates a new monitor with the given options.
func (*Monitor) FormatAPILimitError ¶
FormatAPILimitError returns the API limit error message.
func (*Monitor) FormatLoopEnd ¶
func (m *Monitor) FormatLoopEnd(loopNum int, status *Status, err error, outputSize int, elapsed time.Duration) string
FormatLoopEnd returns the loop end message.
func (*Monitor) FormatLoopProgress ¶
func (m *Monitor) FormatLoopProgress(loopNum int, status *Status, circuit *CircuitBreaker) string
FormatLoopProgress returns the progress line for monitor mode. Format: [Loop 3/50] IN_PROGRESS | Tasks: 2 | Files: 5 | Rate: 97/100 | Circuit: CLOSED
func (*Monitor) FormatLoopStart ¶
FormatLoopStart returns the loop start message.
func (*Monitor) FormatRateLimitWait ¶
FormatRateLimitWait returns the rate limit wait message.
func (*Monitor) FormatResult ¶
func (m *Monitor) FormatResult(result *LoopResult) string
FormatResult returns the final result summary.
func (*Monitor) PrintLoopEnd ¶
func (m *Monitor) PrintLoopEnd(loopNum int, status *Status, err error, outputSize int, elapsed time.Duration)
PrintLoopEnd writes the loop end message.
func (*Monitor) PrintLoopProgress ¶
func (m *Monitor) PrintLoopProgress(loopNum int, status *Status, circuit *CircuitBreaker)
PrintLoopProgress writes the progress line.
func (*Monitor) PrintLoopStart ¶
PrintLoopStart writes the loop start message.
func (*Monitor) PrintResult ¶
func (m *Monitor) PrintResult(result *LoopResult)
PrintResult writes the final result summary.
type MonitorOptions ¶
type MonitorOptions struct {
// Writer is where monitor output goes (typically os.Stderr).
Writer io.Writer
// MaxLoops is the total max loops for progress calculation.
MaxLoops int
// ShowRateLimit shows rate limiter status if enabled.
ShowRateLimit bool
// RateLimiter to query for status.
RateLimiter *RateLimiter
// Verbose enables detailed output.
Verbose bool
}
MonitorOptions configures the monitor output.
type RateLimitState ¶
RateLimitState represents the persistent state of the rate limiter.
type RateLimiter ¶
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter tracks API calls per hour and enforces a configurable limit.
func NewRateLimiter ¶
func NewRateLimiter(limit int) *RateLimiter
NewRateLimiter creates a new rate limiter with the given limit per hour. A limit of 0 or less disables rate limiting.
func (*RateLimiter) Allow ¶
func (r *RateLimiter) Allow() bool
Allow checks if a call is allowed and records it if so. Returns true if the call is allowed, false if rate limited.
func (*RateLimiter) CallCount ¶
func (r *RateLimiter) CallCount() int
CallCount returns the current number of calls in this window.
func (*RateLimiter) IsEnabled ¶
func (r *RateLimiter) IsEnabled() bool
IsEnabled returns true if rate limiting is enabled.
func (*RateLimiter) Record ¶
func (r *RateLimiter) Record()
Record manually records a call without checking the limit. Useful when a call has already been made.
func (*RateLimiter) Remaining ¶
func (r *RateLimiter) Remaining() int
Remaining returns the number of calls remaining in the current window.
func (*RateLimiter) ResetTime ¶
func (r *RateLimiter) ResetTime() time.Time
ResetTime returns when the current rate limit window will reset.
func (*RateLimiter) RestoreState ¶
func (r *RateLimiter) RestoreState(state RateLimitState) bool
RestoreState restores the rate limiter from a persisted state. Returns true if the state was actually restored, false if it was discarded due to expiration or invalid values.
func (*RateLimiter) State ¶
func (r *RateLimiter) State() RateLimitState
State returns the current state for persistence.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner executes Ralph loops.
func NewRunnerWith ¶
func NewRunnerWith(client *docker.Client, store *SessionStore, history *HistoryStore) *Runner
NewRunnerWith creates a Runner with explicit store and history dependencies. This is useful for testing with custom storage directories.
func (*Runner) ExecCapture ¶
func (r *Runner) ExecCapture(ctx context.Context, containerName string, cmd []string, onOutput func([]byte)) (string, int, error)
ExecCapture executes a command in the container and captures output.
func (*Runner) GetCircuitState ¶
func (r *Runner) GetCircuitState(project, agent string) (*CircuitState, error)
GetCircuitState returns the circuit breaker state for a project/agent.
func (*Runner) GetSession ¶
GetSession returns the current session for a project/agent.
func (*Runner) ResetCircuit ¶
ResetCircuit resets the circuit breaker for a project/agent.
func (*Runner) ResetSession ¶
ResetSession resets both session and circuit for a project/agent.
func (*Runner) Run ¶
func (r *Runner) Run(ctx context.Context, opts LoopOptions) (*LoopResult, error)
Run executes the Ralph loop until completion, error, or max loops.
type Session ¶
type Session struct {
// Project is the clawker project name.
Project string `json:"project"`
// Agent is the agent name.
Agent string `json:"agent"`
// StartedAt is when the session started.
StartedAt time.Time `json:"started_at"`
// UpdatedAt is when the session was last updated.
UpdatedAt time.Time `json:"updated_at"`
// LoopsCompleted is the number of loops completed.
LoopsCompleted int `json:"loops_completed"`
// Status is the last known status.
Status string `json:"status"`
// NoProgressCount is the current count without progress.
NoProgressCount int `json:"no_progress_count"`
// TotalTasksCompleted is the cumulative tasks completed.
TotalTasksCompleted int `json:"total_tasks_completed"`
// TotalFilesModified is the cumulative files modified.
TotalFilesModified int `json:"total_files_modified"`
// LastError is the last error message, if any.
LastError string `json:"last_error,omitempty"`
// InitialPrompt is the prompt that started the session.
InitialPrompt string `json:"initial_prompt,omitempty"`
// RateLimitState tracks the rate limiter state for persistence.
RateLimitState *RateLimitState `json:"rate_limit_state,omitempty"`
}
Session represents the persistent state of a Ralph loop session.
func NewSession ¶
NewSession creates a new session.
type SessionHistory ¶
type SessionHistory struct {
Project string `json:"project"`
Agent string `json:"agent"`
Entries []SessionHistoryEntry `json:"entries"`
}
SessionHistory tracks session lifecycle events.
type SessionHistoryEntry ¶
type SessionHistoryEntry struct {
Timestamp time.Time `json:"timestamp"`
Event string `json:"event"` // created, updated, expired, deleted
LoopCount int `json:"loop_count"`
Status string `json:"status,omitempty"`
Error string `json:"error,omitempty"`
}
SessionHistoryEntry represents a session state transition.
type SessionStore ¶
type SessionStore struct {
// contains filtered or unexported fields
}
SessionStore manages session and circuit breaker persistence.
func DefaultSessionStore ¶
func DefaultSessionStore() (*SessionStore, error)
DefaultSessionStore returns a session store using the default clawker directory.
func NewSessionStore ¶
func NewSessionStore(baseDir string) *SessionStore
NewSessionStore creates a new session store at the given base directory.
func (*SessionStore) DeleteCircuitState ¶
func (s *SessionStore) DeleteCircuitState(project, agent string) error
DeleteCircuitState removes circuit breaker state from disk.
func (*SessionStore) DeleteSession ¶
func (s *SessionStore) DeleteSession(project, agent string) error
DeleteSession removes a session from disk.
func (*SessionStore) LoadCircuitState ¶
func (s *SessionStore) LoadCircuitState(project, agent string) (*CircuitState, error)
LoadCircuitState loads circuit breaker state from disk. Returns nil if no state exists.
func (*SessionStore) LoadSession ¶
func (s *SessionStore) LoadSession(project, agent string) (*Session, error)
LoadSession loads a session from disk. Returns nil if no session exists.
func (*SessionStore) LoadSessionWithExpiration ¶
func (s *SessionStore) LoadSessionWithExpiration(project, agent string, expirationHours int) (*Session, bool, error)
LoadSessionWithExpiration loads a session and auto-resets if expired. Returns nil (and deletes the old session) if the session is expired.
func (*SessionStore) SaveCircuitState ¶
func (s *SessionStore) SaveCircuitState(state *CircuitState) error
SaveCircuitState saves circuit breaker state to disk.
func (*SessionStore) SaveSession ¶
func (s *SessionStore) SaveSession(session *Session) error
SaveSession saves a session to disk.
type Status ¶
type Status struct {
// Status is one of: IN_PROGRESS, COMPLETE, BLOCKED
Status string
// TasksCompleted is the number of tasks completed in this loop.
TasksCompleted int
// FilesModified is the number of files modified in this loop.
FilesModified int
// TestsStatus is one of: PASSING, FAILING, NOT_RUN
TestsStatus string
// WorkType describes the type of work done (IMPLEMENTATION, TESTING, etc.)
WorkType string
// ExitSignal indicates whether Claude requested to exit the loop.
ExitSignal bool
// Recommendation is a one-line recommendation for next steps.
Recommendation string
// CompletionIndicators is the count of completion phrases found in output.
CompletionIndicators int
}
Status represents the parsed RALPH_STATUS block from Claude's output.
func ParseStatus ¶
ParseStatus extracts the RALPH_STATUS block from output and parses it. Returns nil if no valid status block is found.
func (*Status) HasProgress ¶
HasProgress returns true if the status indicates meaningful progress.
func (*Status) IsComplete ¶
IsComplete returns true if the status indicates completion. This is the basic check: STATUS: COMPLETE or EXIT_SIGNAL: true
func (*Status) IsCompleteStrict ¶
IsCompleteStrict returns true only if BOTH conditions are met: - EXIT_SIGNAL is true - CompletionIndicators >= threshold This prevents premature exit due to false positives.
func (*Status) IsTestOnly ¶
IsTestOnly returns true if this loop was test-only work.