Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ type MonitorConfig struct {
PollIntervalMs int `yaml:"poll_interval_ms"`
StuckThresholdS int `yaml:"stuck_threshold_s"`
ContextFreshnessTokens int `yaml:"context_freshness_tokens"`
// PipelineTimeoutS bounds the whole post-execution pipeline (review + QA +
// merge/conflict-resolution) per story. Slow local LLM calls plus rebase-
// conflict resolution under concurrent builds can exceed a tight limit and
// trip "context deadline exceeded". Default 900s.
PipelineTimeoutS int `yaml:"pipeline_timeout_s"`
}

// ControllerConfig configures the periodic active controller.
Expand Down
1 change: 1 addition & 0 deletions internal/config/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func DefaultConfig() Config {
PollIntervalMs: 10000,
StuckThresholdS: 120,
ContextFreshnessTokens: 150000,
PipelineTimeoutS: 900, // 15 min — room for slow local LLM calls + conflict resolution
},
Cleanup: CleanupConfig{
WorktreePrune: "immediate",
Expand Down
11 changes: 8 additions & 3 deletions internal/engine/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,14 @@ func (m *Monitor) postExecutionPipeline(ctx context.Context, ag ActiveAgent, rep
// would mark the story DB as devdb.OutcomeFailed and pollute metrics.
parentCtx := ctx

// Wrap context with a 5-minute timeout to prevent pipeline LLM calls
// (review, QA, conflict resolution) from blocking indefinitely.
pipelineCtx, pipelineCancel := context.WithTimeout(ctx, 5*time.Minute)
// Bound the post-execution pipeline (review, QA, conflict resolution).
// Configurable because slow local LLM calls + conflict resolution under
// concurrent builds can exceed a tight limit. Falls back to 15m when unset.
pipelineTimeout := time.Duration(m.config.Monitor.PipelineTimeoutS) * time.Second
if pipelineTimeout <= 0 {
pipelineTimeout = 15 * time.Minute
}
pipelineCtx, pipelineCancel := context.WithTimeout(ctx, pipelineTimeout)
defer pipelineCancel()
ctx = pipelineCtx

Expand Down
1 change: 1 addition & 0 deletions nxd.config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ monitor:
poll_interval_ms: 10000
stuck_threshold_s: 120
context_freshness_tokens: 150000
pipeline_timeout_s: 900
cleanup:
worktree_prune: immediate
branch_retention_days: 7
Expand Down
Loading