diff --git a/.archon/workflows/defaults/archon-adversarial-dev.yaml b/.archon/workflows/defaults/archon-adversarial-dev.yaml index eecf4b72..2ab207dc 100644 --- a/.archon/workflows/defaults/archon-adversarial-dev.yaml +++ b/.archon/workflows/defaults/archon-adversarial-dev.yaml @@ -115,6 +115,7 @@ nodes: - id: adversarial-sprint depends_on: [init-workspace] idle_timeout: 600000 + model: claude-opus-4-6[1m] loop: prompt: | # Adversarial Development — Sprint Loop diff --git a/.archon/workflows/defaults/archon-feature-development.yaml b/.archon/workflows/defaults/archon-feature-development.yaml index f63d9b1a..6d074770 100644 --- a/.archon/workflows/defaults/archon-feature-development.yaml +++ b/.archon/workflows/defaults/archon-feature-development.yaml @@ -8,6 +8,7 @@ description: | nodes: - id: implement command: archon-implement + model: claude-opus-4-6[1m] - id: create-pr command: archon-create-pr diff --git a/.archon/workflows/defaults/archon-fix-github-issue.yaml b/.archon/workflows/defaults/archon-fix-github-issue.yaml index 72713178..12ad675d 100644 --- a/.archon/workflows/defaults/archon-fix-github-issue.yaml +++ b/.archon/workflows/defaults/archon-fix-github-issue.yaml @@ -133,7 +133,7 @@ nodes: command: archon-fix-issue depends_on: [bridge-artifacts] context: fresh - model: opus + model: claude-opus-4-6[1m] # ═══════════════════════════════════════════════════════════════ # PHASE 5: VALIDATE diff --git a/.archon/workflows/defaults/archon-idea-to-pr.yaml b/.archon/workflows/defaults/archon-idea-to-pr.yaml index 519429be..9329c550 100644 --- a/.archon/workflows/defaults/archon-idea-to-pr.yaml +++ b/.archon/workflows/defaults/archon-idea-to-pr.yaml @@ -52,6 +52,7 @@ nodes: command: archon-implement-tasks depends_on: [confirm-plan] context: fresh + model: claude-opus-4-6[1m] # ═══════════════════════════════════════════════════════════════════ # PHASE 4: VALIDATE diff --git a/.archon/workflows/defaults/archon-piv-loop.yaml b/.archon/workflows/defaults/archon-piv-loop.yaml index b9b652e6..7227900c 100644 --- a/.archon/workflows/defaults/archon-piv-loop.yaml +++ b/.archon/workflows/defaults/archon-piv-loop.yaml @@ -415,6 +415,7 @@ nodes: - id: implement depends_on: [implement-setup] idle_timeout: 600000 + model: claude-opus-4-6[1m] loop: prompt: | # PIV Loop — Implementation Agent diff --git a/.archon/workflows/defaults/archon-plan-to-pr.yaml b/.archon/workflows/defaults/archon-plan-to-pr.yaml index ef40e329..067c1a81 100644 --- a/.archon/workflows/defaults/archon-plan-to-pr.yaml +++ b/.archon/workflows/defaults/archon-plan-to-pr.yaml @@ -42,6 +42,7 @@ nodes: command: archon-implement-tasks depends_on: [confirm-plan] context: fresh + model: claude-opus-4-6[1m] # ═══════════════════════════════════════════════════════════════════ # PHASE 4: VALIDATE diff --git a/.archon/workflows/defaults/archon-ralph-dag.yaml b/.archon/workflows/defaults/archon-ralph-dag.yaml index d258b2bb..5c0d7c90 100644 --- a/.archon/workflows/defaults/archon-ralph-dag.yaml +++ b/.archon/workflows/defaults/archon-ralph-dag.yaml @@ -189,6 +189,7 @@ nodes: - id: implement depends_on: [validate-prd] idle_timeout: 600000 + model: claude-opus-4-6[1m] loop: prompt: | # Ralph Agent — Autonomous Story Implementation diff --git a/.archon/workflows/defaults/archon-refactor-safely.yaml b/.archon/workflows/defaults/archon-refactor-safely.yaml index 6ba72de7..56bc96ac 100644 --- a/.archon/workflows/defaults/archon-refactor-safely.yaml +++ b/.archon/workflows/defaults/archon-refactor-safely.yaml @@ -207,6 +207,7 @@ nodes: # ═══════════════════════════════════════════════════════════════ - id: execute-refactor + model: claude-opus-4-6[1m] prompt: | You are executing a refactoring plan with strict safety guardrails. diff --git a/packages/workflows/src/dag-executor.ts b/packages/workflows/src/dag-executor.ts index 4660e612..f52ea5fe 100644 --- a/packages/workflows/src/dag-executor.ts +++ b/packages/workflows/src/dag-executor.ts @@ -1438,8 +1438,8 @@ async function executeBashNode( } /** - * Build WorkflowAssistantOptions from workflow-level config. - * Loop nodes use workflow-level provider/model only; per-node overrides are not supported. + * Build WorkflowAssistantOptions from resolved provider, model, and config. + * Caller is responsible for resolving per-node overrides before passing model. */ function buildLoopNodeOptions( provider: 'claude' | 'codex', @@ -2373,6 +2373,34 @@ export async function executeDagWorkflow( // 3b. Loop node dispatch — manages its own AI sessions and iteration if (isLoopNode(node)) { + // Resolve per-node provider/model overrides (same logic as other node types) + let loopProvider: 'claude' | 'codex'; + if (node.provider) { + loopProvider = node.provider; + } else if (node.model && isClaudeModel(node.model)) { + loopProvider = 'claude'; + } else if (node.model) { + loopProvider = 'codex'; + } else { + loopProvider = workflowProvider; + } + const loopModel = + node.model ?? + (loopProvider === workflowProvider + ? workflowModel + : config.assistants[loopProvider]?.model); + + if (!isModelCompatible(loopProvider, loopModel)) { + return { + nodeId: node.id, + output: { + state: 'failed' as const, + output: '', + error: `Node '${node.id}': model "${loopModel ?? 'default'}" is not compatible with provider "${loopProvider}"`, + }, + }; + } + const output = await executeLoopNode( deps, platform, @@ -2380,8 +2408,8 @@ export async function executeDagWorkflow( cwd, workflowRun, node, - workflowProvider, - workflowModel, + loopProvider, + loopModel, artifactsDir, logDir, baseBranch,