Skip to content

Commit 20c90b4

Browse files
committed
(feat): add classify-complexity composite action
1 parent d765945 commit 20c90b4

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Classify task complexity with Haiku
2+
description: >
3+
Ask Claude Haiku to classify a task as 'simple' or 'complex' and pick a model
4+
pair (primary + fallback). Favours opus — sonnet is only chosen when Haiku
5+
explicitly says 'simple'; any other output routes to opus.
6+
7+
inputs:
8+
oauth-token:
9+
description: Claude Code OAuth token.
10+
required: true
11+
prompt:
12+
description: >
13+
Full classification prompt. Must instruct Haiku to reply with EXACTLY
14+
one lowercase word — 'simple' or 'complex' — and nothing else.
15+
required: true
16+
17+
outputs:
18+
model:
19+
description: Selected primary model.
20+
value: ${{ steps.classify.outputs.model }}
21+
fallback:
22+
description: Fallback model.
23+
value: ${{ steps.classify.outputs.fallback }}
24+
classification:
25+
description: Raw classification string ('simple', 'complex', or fallback on empty/garbage).
26+
value: ${{ steps.classify.outputs.classification }}
27+
28+
runs:
29+
using: composite
30+
steps:
31+
- name: Install Claude CLI
32+
shell: bash
33+
run: |
34+
if ! command -v claude >/dev/null 2>&1; then
35+
curl -fsSL https://claude.ai/install.sh | bash
36+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
37+
fi
38+
39+
- name: Run Haiku classification
40+
id: classify
41+
shell: bash
42+
env:
43+
CLAUDE_CODE_OAUTH_TOKEN: ${{ inputs.oauth-token }}
44+
CLASSIFY_PROMPT: ${{ inputs.prompt }}
45+
run: |
46+
set +e
47+
48+
# Force the model to emit a JSON object matching this schema — removes
49+
# any chance of leading/trailing prose, punctuation, or casing drift.
50+
SCHEMA='{
51+
"type": "object",
52+
"properties": {
53+
"classification": {
54+
"type": "string",
55+
"enum": ["simple", "complex"]
56+
}
57+
},
58+
"required": ["classification"],
59+
"additionalProperties": false
60+
}'
61+
62+
RAW=$(claude -p \
63+
--model claude-haiku-4-5 \
64+
--bare \
65+
--max-turns 1 \
66+
--tools "" \
67+
--dangerously-skip-permissions \
68+
--output-format json \
69+
--json-schema "$SCHEMA" \
70+
"$CLASSIFY_PROMPT" 2>/dev/null)
71+
72+
CLASSIFICATION=$(printf '%s' "$RAW" | jq -r '.result | fromjson? | .classification // empty' 2>/dev/null)
73+
74+
echo "Haiku classification: '$CLASSIFICATION'"
75+
76+
# Favour opus, sonnet only when haiku explicitly says simple.
77+
if [[ "$CLASSIFICATION" == "simple" ]]; then
78+
MODEL="claude-sonnet-4-6"
79+
FALLBACK="claude-opus-4-7"
80+
else
81+
MODEL="claude-opus-4-7"
82+
FALLBACK="claude-sonnet-4-6"
83+
fi
84+
85+
echo "classification=$CLASSIFICATION" >> "$GITHUB_OUTPUT"
86+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
87+
echo "fallback=$FALLBACK" >> "$GITHUB_OUTPUT"
88+
echo "Selected primary=$MODEL, fallback=$FALLBACK"

0 commit comments

Comments
 (0)