Files
poimen-workflows/statemachine/types.go
T
Test 60f9ca2b1d feat(T1.1): implement error recovery, retry policies, and deadletter handling
- Add internal/recovery package with comprehensive error recovery infrastructure
- Implement RetryPolicy with exponential backoff
- Three predefined policies: DefaultRetryPolicy, ActivityRetryPolicy, LLMActivityRetryPolicy
- Integrate with Temporal SDK via ToTemporalRetryPolicy()
- Implement DeadletterQueue for tracking permanently failed activities
- Thread-safe deadletter operations with JSON persistence
- Mark items as recoverable or non-recoverable
- Support batch retrieval of recoverable items
- Implement CheckpointManager for periodic state snapshots
- Track workflow stages and task lifecycle (completed/pending/failed)
- Persist checkpoints to enable recovery after crashes
- Add OrchestratorWorkflowWithRecovery demonstrating recovery patterns
- Structured logging at each workflow step
- Retry policies applied to all activity types
- Extended ActivityTuning with retry configuration fields

Test Coverage:
- 8/8 retry policy tests passing
- 10/10 deadletter queue tests passing
- 10/10 checkpoint manager tests passing
- 40 total recovery tests, all passing
- All existing tests continue to pass

Key Features:
- Exponential backoff prevents thundering herd
- Deadletter audit trail with timestamps
- Checkpoint interval configurable (30s default)
- Thread-safe concurrent access
- No external dependencies added

Closes T1.1
2026-08-23 16:43:30 -07:00

133 lines
4.2 KiB
Go

package statemachine
import "time"
// ModelSpec defines LLM model configuration.
type ModelSpec struct {
ModelID string // e.g. "claude-opus-5", "claude-sonnet-5"
Thinking string // "adaptive" or ""
Effort string // "low", "medium", "high", "xhigh", "max"
}
// PromptSpec defines a prompt template with variables and model.
type PromptSpec struct {
TemplateRef string // e.g. "planner/default.tmpl"
RawTemplate string // overrides TemplateRef if non-empty
Variables map[string]any // template variables
Model ModelSpec // which LLM to use
LessonsRef string // key into lessons store
}
// PiRetryPolicy defines retry and timeout settings for Pi command execution.
type PiRetryPolicy struct {
ScheduleToCloseTimeout time.Duration // default: 5m
InitialInterval time.Duration // default: 2s
MaximumInterval time.Duration // default: 30s
BackoffCoefficient float64 // default: 2.0
StreamTimeout time.Duration // default: 30s
StreamTimeoutMax time.Duration // default: 2m
}
// ActivityTuning defines timeouts and retry counts for activities.
type ActivityTuning struct {
ImplementerBaseTimeout time.Duration // default: 10m
ImplementerMaxRetries int // default: 3
JudgeTimeout time.Duration // default: 5m
PiRetry PiRetryPolicy
// Retry policy settings
InitialRetryInterval time.Duration // default: 2s
MaxRetryInterval time.Duration // default: 5m
RetryBackoffCoefficient float64 // default: 2.0
}
// OrchestratorConfig holds all runtime configuration for the orchestrator.
type OrchestratorConfig struct {
SystemPrompt string // shared prompt prefix
Skills []SkillRef // required skill sources
RolePrompts map[string]PromptSpec // per-role: "planner", "judge", "implementer"
Tuning ActivityTuning
}
// OrchestratorInput is the input to the Orchestrator workflow.
type OrchestratorInput struct {
TargetRepoPath string
RemoteURL string
Milestone string // e.g. "T0"
Config OrchestratorConfig
DryRun bool
CycleCount int
MaxCyclesBeforeCAN int // default: 100
}
// OrchestratorOutput is the output of the Orchestrator workflow.
type OrchestratorOutput struct {
MilestoneComplete bool
Done bool
LastError string
}
// TaskUnitInput is the input to the TaskUnit workflow.
type TaskUnitInput struct {
TaskID string
TargetRepoPath string
JudgeSpec PromptSpec
ImplementerSpec PromptSpec
BaseTimeout time.Duration
MaxJudgeRetries int
}
// TaskUnitOutput is the output of the TaskUnit workflow.
type TaskUnitOutput struct {
TaskID string
Verdict string // "pass" or "fail"
Critique string
Branch string
}
// SkillRef references a skill source.
type SkillRef struct {
Name string // skill identifier
URL string // source to clone
}
// Default values for types.
const (
defaultScheduleToCloseTimeout = 5 * time.Minute
defaultInitialInterval = 2 * time.Second
defaultMaximumInterval = 30 * time.Second
defaultBackoffCoefficient = 2.0
defaultStreamTimeout = 30 * time.Second
defaultStreamTimeoutMax = 2 * time.Minute
defaultImplementerBaseTimeout = 10 * time.Minute
defaultImplementerMaxRetries = 3
defaultJudgeTimeout = 5 * time.Minute
)
// NewPiRetryPolicy returns a PiRetryPolicy with defaults.
func NewPiRetryPolicy() PiRetryPolicy {
return PiRetryPolicy{
ScheduleToCloseTimeout: defaultScheduleToCloseTimeout,
InitialInterval: defaultInitialInterval,
MaximumInterval: defaultMaximumInterval,
BackoffCoefficient: defaultBackoffCoefficient,
StreamTimeout: defaultStreamTimeout,
StreamTimeoutMax: defaultStreamTimeoutMax,
}
}
// NewActivityTuning returns an ActivityTuning with defaults.
func NewActivityTuning() ActivityTuning {
return ActivityTuning{
ImplementerBaseTimeout: defaultImplementerBaseTimeout,
ImplementerMaxRetries: defaultImplementerMaxRetries,
JudgeTimeout: defaultJudgeTimeout,
PiRetry: NewPiRetryPolicy(),
}
}
// PromptUpdate represents an update to a role prompt.
type PromptUpdate struct {
Role string
Spec PromptSpec
}