Skip to content

Commit 6cd19d3

Browse files
nyldnclaude
andcommitted
feat(routing): Add cost-aware auto-routing with complexity estimation
- Add estimate_complexity() for trivial/standard/complex task classification - Add get_tiered_agent() for complexity-based model selection - Route trivial tasks to codex-mini/gemini-fast (cheaper models) - Route complex tasks to codex/gemini-pro (premium models) - Add CLI flags: -Q/--quick, -P/--premium, --tier - Fix Bash 3.2 compatibility (macOS) for lowercase conversion - Update help text with Cost Control section Closes: Cost optimization for simple tasks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent bf765f6 commit 6cd19d3

5 files changed

Lines changed: 184 additions & 15 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"name": "claude-octopus",
1313
"source": "./",
1414
"description": "Multi-tentacled orchestrator using Double Diamond methodology",
15-
"version": "1.0.2",
15+
"version": "1.0.3",
1616
"author": {
1717
"name": "nyldn"
1818
},

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ All notable changes to Claude Octopus will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.3] - 2026-01-15
9+
10+
### Added
11+
- **Cost-Aware Auto-Routing** - Intelligent model tier selection based on task complexity
12+
- Analyzes prompts to estimate complexity (trivial, standard, complex)
13+
- Routes trivial tasks to cheaper models (`codex-mini`, `gemini-fast`)
14+
- Routes complex tasks to premium models (`codex`, `gemini-pro`)
15+
- Prevents expensive models from being wasted on simple tasks
16+
- **Cost Control CLI Flags**
17+
- `-Q, --quick` - Force cheapest model tier
18+
- `-P, --premium` - Force premium model tier
19+
- `--tier LEVEL` - Explicit tier: trivial|standard|premium
20+
- Complexity displayed in task analysis output
21+
22+
### Changed
23+
- `auto_route()` now uses `get_tiered_agent()` for cost-aware model selection
24+
- Help text updated with Cost Control section
25+
26+
---
27+
828
## [1.0.2] - 2026-01-15
929

1030
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<img src="https://img.shields.io/badge/Claude_Code-Plugin-blueviolet" alt="Claude Code Plugin">
77
<img src="https://img.shields.io/badge/Double_Diamond-Design_Thinking-orange" alt="Double Diamond">
88
<img src="https://img.shields.io/badge/License-MIT-green" alt="MIT License">
9-
<img src="https://img.shields.io/badge/Version-1.0.2-blue" alt="Version 1.0.2">
9+
<img src="https://img.shields.io/badge/Version-1.0.3-blue" alt="Version 1.0.3">
1010
</p>
1111

1212
```

plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "claude-octopus",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "Multi-tentacled orchestrator using Double Diamond methodology",
55
"author": {
66
"name": "nyldn"

scripts/orchestrate.sh

Lines changed: 161 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,115 @@ get_agent_for_task() {
172172
esac
173173
}
174174

175+
# ═══════════════════════════════════════════════════════════════════════════════
176+
# COST-AWARE ROUTING - Complexity estimation and tiered model selection
177+
# Prevents expensive premium models from being used on trivial tasks
178+
# ═══════════════════════════════════════════════════════════════════════════════
179+
180+
# Estimate task complexity: trivial (1), standard (2), complex (3)
181+
# Uses keyword analysis and prompt length to determine appropriate model tier
182+
estimate_complexity() {
183+
local prompt="$1"
184+
local prompt_lower
185+
prompt_lower=$(echo "$prompt" | tr '[:upper:]' '[:lower:]') # Bash 3.2 compatible
186+
local word_count=$(echo "$prompt" | wc -w | tr -d ' ')
187+
local score=2 # Default: standard
188+
189+
# TRIVIAL indicators (reduce score)
190+
# Short, simple operations that don't need premium models
191+
local trivial_patterns="typo|rename|update.?version|bump.?version|change.*to|fix.?typo|formatting|indent|whitespace|simple|quick|small"
192+
local single_file_patterns="in readme|in package|in changelog|in config|\.json|\.md|\.txt|\.yml|\.yaml"
193+
194+
# Check for trivial indicators
195+
if [[ $word_count -lt 12 ]]; then
196+
((score--))
197+
fi
198+
199+
if [[ "$prompt_lower" =~ ($trivial_patterns) ]]; then
200+
((score--))
201+
fi
202+
203+
if [[ "$prompt_lower" =~ ($single_file_patterns) ]]; then
204+
((score--))
205+
fi
206+
207+
# COMPLEX indicators (increase score)
208+
# Multi-step, architectural, or comprehensive tasks need premium models
209+
local complex_patterns="implement|design|architect|build.*feature|create.*system|from.?scratch|comprehensive|full.?system|entire|integrate|authentication|api|database"
210+
local multi_component="and.*and|multiple|across|throughout|all.?files|refactor.*entire|complete"
211+
212+
# Check for complex indicators
213+
if [[ $word_count -gt 40 ]]; then
214+
((score++))
215+
fi
216+
217+
if [[ "$prompt_lower" =~ ($complex_patterns) ]]; then
218+
((score++))
219+
fi
220+
221+
if [[ "$prompt_lower" =~ ($multi_component) ]]; then
222+
((score++))
223+
fi
224+
225+
# Clamp to 1-3 range
226+
[[ $score -lt 1 ]] && score=1
227+
[[ $score -gt 3 ]] && score=3
228+
229+
echo "$score"
230+
}
231+
232+
# Get complexity tier name for display
233+
get_tier_name() {
234+
local complexity="$1"
235+
case "$complexity" in
236+
1) echo "trivial (🐙 quick mode)" ;;
237+
2) echo "standard" ;;
238+
3) echo "complex (premium)" ;;
239+
*) echo "standard" ;;
240+
esac
241+
}
242+
243+
# Get agent based on task type AND complexity tier
244+
# This replaces the simple get_agent_for_task for cost-aware routing
245+
get_tiered_agent() {
246+
local task_type="$1"
247+
local complexity="${2:-2}" # Default: standard
248+
249+
case "$task_type" in
250+
image)
251+
# Image generation always uses gemini-image
252+
echo "gemini-image"
253+
;;
254+
review)
255+
# Reviews use standard tier (already cost-effective)
256+
echo "codex-review"
257+
;;
258+
coding|general)
259+
# Coding tasks: tier based on complexity
260+
case "$complexity" in
261+
1) echo "codex-mini" ;; # Trivial → mini (cheapest)
262+
2) echo "codex-standard" ;; # Standard → standard tier
263+
3) echo "codex" ;; # Complex → premium
264+
esac
265+
;;
266+
design|copywriting|research)
267+
# Gemini tasks: tier based on complexity
268+
case "$complexity" in
269+
1) echo "gemini-fast" ;; # Trivial → flash (cheaper)
270+
*) echo "gemini" ;; # Standard+ → pro
271+
esac
272+
;;
273+
diamond-*)
274+
# Double Diamond workflows always use premium
275+
echo "codex"
276+
;;
277+
*)
278+
# Safe default: standard tier
279+
echo "codex-standard"
280+
;;
281+
esac
282+
}
283+
175284
# Default settings
176285
MAX_PARALLEL=3
177286
TIMEOUT=300
@@ -189,6 +298,10 @@ MAX_QUALITY_RETRIES="${CLAUDE_OCTOPUS_MAX_RETRIES:-3}"
189298
LOOP_UNTIL_APPROVED=false
190299
RESUME_SESSION=false
191300

301+
# v3.1 Feature: Cost-Aware Routing
302+
# Complexity tiers: trivial (1), standard (2), complex/premium (3)
303+
FORCE_TIER="" # "", "trivial", "standard", "premium"
304+
192305
# Session recovery
193306
SESSION_FILE="${WORKSPACE_DIR}/session.json"
194307

@@ -270,6 +383,11 @@ ${YELLOW}Options:${NC}
270383
-l, --loop Enable loop-until-approved for quality gates
271384
-R, --resume Resume last interrupted session
272385
386+
${YELLOW}Cost Control:${NC} (v3.1 - Smart model selection based on task complexity)
387+
-Q, --quick Force trivial tier (cheapest models: codex-mini, gemini-fast)
388+
-P, --premium Force premium tier (most capable: codex-max)
389+
--tier LEVEL Explicit tier: trivial|standard|premium
390+
273391
${YELLOW}Double Diamond Examples:${NC}
274392
# Full workflow - explore, define, develop, deliver
275393
$(basename "$0") embrace "Build a user authentication system"
@@ -828,6 +946,25 @@ auto_route() {
828946
local task_type
829947
task_type=$(classify_task "$prompt")
830948

949+
# ═══════════════════════════════════════════════════════════════════════════
950+
# COST-AWARE COMPLEXITY ESTIMATION
951+
# ═══════════════════════════════════════════════════════════════════════════
952+
local complexity=2
953+
if [[ -n "$FORCE_TIER" ]]; then
954+
# User override via -Q/--quick, -P/--premium, or --tier
955+
case "$FORCE_TIER" in
956+
trivial) complexity=1 ;;
957+
standard) complexity=2 ;;
958+
premium) complexity=3 ;;
959+
esac
960+
log DEBUG "Complexity forced to $complexity via --tier flag"
961+
else
962+
# Auto-detect complexity from prompt
963+
complexity=$(estimate_complexity "$prompt")
964+
fi
965+
local tier_name
966+
tier_name=$(get_tier_name "$complexity")
967+
831968
echo ""
832969
echo -e "${MAGENTA}═══════════════════════════════════════════════════════════${NC}"
833970
echo -e "${MAGENTA} Claude Octopus - Smart Routing${NC}"
@@ -836,6 +973,7 @@ auto_route() {
836973
echo -e "${BLUE}Task Analysis:${NC}"
837974
echo -e " Prompt: ${prompt:0:80}..."
838975
echo -e " Detected Type: ${GREEN}$task_type${NC}"
976+
echo -e " Complexity: ${CYAN}$tier_name${NC}"
839977
echo ""
840978

841979
# ═══════════════════════════════════════════════════════════════════════════
@@ -872,11 +1010,13 @@ auto_route() {
8721010
esac
8731011

8741012
# ═══════════════════════════════════════════════════════════════════════════
875-
# STANDARD SINGLE-AGENT ROUTING
1013+
# STANDARD SINGLE-AGENT ROUTING (with cost-aware tier selection)
8761014
# ═══════════════════════════════════════════════════════════════════════════
8771015
local agent
878-
agent=$(get_agent_for_task "$task_type")
879-
echo -e " Selected Agent: ${GREEN}$agent${NC}"
1016+
agent=$(get_tiered_agent "$task_type" "$complexity")
1017+
local model_name
1018+
model_name=$(get_agent_command "$agent" | awk '{print $NF}')
1019+
echo -e " Selected Agent: ${GREEN}$agent${NC}${CYAN}$model_name${NC}"
8801020
echo ""
8811021

8821022
case "$task_type" in
@@ -907,37 +1047,43 @@ auto_route() {
9071047
;;
9081048
review)
9091049
echo -e "${YELLOW}Code Review Task${NC}"
910-
echo " Using gpt-5.2-codex in review mode for thorough code analysis."
1050+
echo " Using $model_name for thorough code analysis."
9111051
echo " Focus: Security, performance, best practices, bugs"
9121052
;;
9131053
coding)
9141054
echo -e "${YELLOW}Coding/Implementation Task${NC}"
915-
echo " Using gpt-5.1-codex-max (premium) for complex code generation."
916-
echo " State-of-the-art on SWE-Bench Pro benchmarks"
1055+
case "$complexity" in
1056+
1) echo " Using $model_name (mini) for quick fixes and simple tasks." ;;
1057+
2) echo " Using $model_name (standard) for general coding tasks." ;;
1058+
3) echo " Using $model_name (premium) for complex code generation." ;;
1059+
esac
9171060
;;
9181061
design)
9191062
echo -e "${YELLOW}Design/UI/UX Task${NC}"
920-
echo " Using gemini-3-pro-preview for design reasoning and analysis."
1063+
echo " Using $model_name for design reasoning and analysis."
9211064
echo " Strong at: Component patterns, accessibility, design systems"
9221065
;;
9231066
copywriting)
9241067
echo -e "${YELLOW}Copywriting Task${NC}"
925-
echo " Using gemini-3-pro-preview for creative content generation."
1068+
echo " Using $model_name for creative content generation."
9261069
echo " Strong at: Marketing copy, tone adaptation, messaging"
9271070
;;
9281071
research)
9291072
echo -e "${YELLOW}Research/Analysis Task${NC}"
930-
echo " Using gemini-3-pro-preview for deep analysis and synthesis."
931-
echo " 1M token context window for comprehensive analysis"
1073+
echo " Using $model_name for deep analysis and synthesis."
9321074
;;
9331075
*)
9341076
echo -e "${YELLOW}General Task${NC}"
935-
echo " Using codex (premium) as default for general-purpose tasks."
1077+
case "$complexity" in
1078+
1) echo " Using $model_name (mini) - detected as simple task." ;;
1079+
2) echo " Using $model_name (standard) for general tasks." ;;
1080+
3) echo " Using $model_name (premium) - detected as complex task." ;;
1081+
esac
9361082
;;
9371083
esac
9381084
echo ""
9391085

940-
log INFO "Routing to $agent agent (task type: $task_type)"
1086+
log INFO "Routing to $agent agent (task: $task_type, tier: $tier_name)"
9411087

9421088
spawn_agent "$agent" "$prompt"
9431089
}
@@ -2245,6 +2391,9 @@ while [[ $# -gt 0 ]]; do
22452391
-q|--quality) QUALITY_THRESHOLD="$2"; shift 2 ;;
22462392
-l|--loop) LOOP_UNTIL_APPROVED=true; shift ;;
22472393
-R|--resume) RESUME_SESSION=true; shift ;;
2394+
-Q|--quick) FORCE_TIER="trivial"; shift ;;
2395+
-P|--premium) FORCE_TIER="premium"; shift ;;
2396+
--tier) FORCE_TIER="$2"; shift 2 ;;
22482397
-h|--help|help) usage ;;
22492398
*) break ;;
22502399
esac

0 commit comments

Comments
 (0)