164 lines
4.1 KiB
Plaintext
164 lines
4.1 KiB
Plaintext
@startuml ai-provider-fallback
|
|
!theme plain
|
|
title AI Provider Fallback Chain with Model Hints
|
|
|
|
start
|
|
|
|
:Automation needs AI generation\n(from patcher.py or runner.py);
|
|
|
|
:Read config/ai.yml;
|
|
|
|
if (Rule has model_hint?) then (yes)
|
|
if (model_hint == "fast"?) then (yes)
|
|
:Use **command_chain_fast**:
|
|
- claude -p (→ Haiku subagent)
|
|
- codex --model gpt-5-mini
|
|
- gemini --model gemini-2.5-flash;
|
|
else if (model_hint == "quality"?) then (yes)
|
|
:Use **command_chain_quality**:
|
|
- claude -p (→ Sonnet subagent)
|
|
- codex --model o3
|
|
- gemini --model gemini-2.5-pro;
|
|
else (unknown hint)
|
|
:Fall back to default chain;
|
|
endif
|
|
else (no hint)
|
|
:Use **command_chain** (default):
|
|
- claude -p (→ auto-select subagent)
|
|
- codex --model gpt-5
|
|
- gemini --model gemini-2.5-flash;
|
|
endif
|
|
|
|
partition "Provider Loop" {
|
|
:Get next provider from chain;
|
|
|
|
if (Provider == "claude"?) then (yes)
|
|
:Execute: **claude -p**;
|
|
note right
|
|
Claude CLI uses TASK COMPLEXITY hint
|
|
from prompt to select subagent:
|
|
- FAST → cdev-patch (Haiku)
|
|
- QUALITY → cdev-patch-quality (Sonnet)
|
|
- Default → auto-select
|
|
end note
|
|
|
|
if (Returned output?) then (yes)
|
|
if (Contains diff markers?) then (yes)
|
|
:✓ Success! Extract diff;
|
|
stop
|
|
else (no - non-diff response)
|
|
:Log: "Claude non-diff output";
|
|
:Try next provider;
|
|
endif
|
|
else (command failed)
|
|
:Log: "Claude command failed";
|
|
:Try next provider;
|
|
endif
|
|
|
|
else if (Provider == "codex"?) then (yes)
|
|
:Execute: **codex exec --model X --json -**;
|
|
note right
|
|
Codex requires special handling:
|
|
- Add "exec" subcommand
|
|
- Add "--json" flag
|
|
- Add "--color=never"
|
|
- Add "-" to read from stdin
|
|
- Parse JSON output for agent_message
|
|
end note
|
|
|
|
if (Exit code == 0?) then (yes)
|
|
:Parse JSON lines;
|
|
:Extract agent_message text;
|
|
|
|
if (Contains diff?) then (yes)
|
|
:✓ Success! Extract diff;
|
|
stop
|
|
else (no diff)
|
|
:Log: "Codex no diff output";
|
|
:Try next provider;
|
|
endif
|
|
else (exit code 1)
|
|
:Log: "Codex exited with 1";
|
|
:Try next provider;
|
|
endif
|
|
|
|
else if (Provider == "gemini"?) then (yes)
|
|
:Execute: **gemini --model X**;
|
|
note right
|
|
Gemini is the most reliable fallback:
|
|
- Accepts plain text input
|
|
- Returns consistent output
|
|
- Supports sentinel token
|
|
end note
|
|
|
|
if (Returned output?) then (yes)
|
|
if (Output == sentinel token?) then (yes)
|
|
:Log: "No changes needed";
|
|
:Return empty (intentional);
|
|
stop
|
|
else if (Contains diff?) then (yes)
|
|
:✓ Success! Extract diff;
|
|
stop
|
|
else (no diff)
|
|
:Log: "Gemini no diff output";
|
|
:Try next provider;
|
|
endif
|
|
else (command failed)
|
|
:Log: "Gemini command failed";
|
|
:Try next provider;
|
|
endif
|
|
endif
|
|
|
|
if (More providers in chain?) then (yes)
|
|
:Continue loop;
|
|
else (no)
|
|
:✗ All providers failed;
|
|
:Raise PatchGenerationError;
|
|
stop
|
|
endif
|
|
}
|
|
|
|
stop
|
|
|
|
legend bottom
|
|
**Configuration Example (config/ai.yml):**
|
|
|
|
runner:
|
|
command_chain:
|
|
- "claude -p"
|
|
- "codex --model gpt-5"
|
|
- "gemini --model gemini-2.5-flash"
|
|
|
|
command_chain_fast:
|
|
- "claude -p"
|
|
- "codex --model gpt-5-mini"
|
|
- "gemini --model gemini-2.5-flash"
|
|
|
|
command_chain_quality:
|
|
- "claude -p"
|
|
- "codex --model o3"
|
|
- "gemini --model gemini-2.5-pro"
|
|
|
|
sentinel: "CASCADINGDEV_NO_CHANGES"
|
|
|
|
**Environment Override:**
|
|
export CDEV_AI_COMMAND="claude -p || gemini --model gemini-2.5-pro"
|
|
(Overrides config.yml for this commit only)
|
|
endlegend
|
|
|
|
note right
|
|
**Why Fallback Chain?**
|
|
|
|
1. **Redundancy**: Rate limits, API outages
|
|
2. **Model specialization**: Different models excel at different tasks
|
|
3. **Cost optimization**: Try cheaper models first
|
|
4. **Quality assurance**: Fast models for simple tasks, quality for complex
|
|
|
|
**Observed Behavior:**
|
|
- Claude occasionally returns non-diff output
|
|
- Codex consistently exits with code 1 (auth issues?)
|
|
- Gemini is the most reliable fallback
|
|
end note
|
|
|
|
@enduml
|