claude-profile: bump opus to 4.8, add fable driver

- driver_model_id(): opus -> claude-opus-4-8, opus-1m -> claude-opus-4-8[1m]
- driver_model_id(): add fable -> claude-fable-5
- error message updated: Valid: haiku sonnet opus opus-1m fable
- spec: driver->model table updated (opus 4.8, fable added); frontmatter
  driver enum includes fable; note that opus-1m retained for [1m] convention
- tests: add Test 13 (deep-fable dryrun asserting claude-fable-5);
  add Test 14 (unknown driver exits 1) — 47 assertions total
  Note: deep-fable mode file lands in the next commit
This commit is contained in:
Paul O'Reilly
2026-06-12 21:33:58 +12:00
parent 9e13b7f096
commit 16586541ea
3 changed files with 66 additions and 7 deletions

View File

@@ -36,9 +36,10 @@ driver_model_id() {
case "$1" in case "$1" in
haiku) echo "claude-haiku-4-5-20251001" ;; haiku) echo "claude-haiku-4-5-20251001" ;;
sonnet) echo "claude-sonnet-4-6" ;; sonnet) echo "claude-sonnet-4-6" ;;
opus) echo "claude-opus-4-6" ;; opus) echo "claude-opus-4-8" ;;
opus-1m) echo "claude-opus-4-6[1m]" ;; opus-1m) echo "claude-opus-4-8[1m]" ;;
*) err "Unknown driver '$1'. Valid: haiku sonnet opus opus-1m" ;; fable) echo "claude-fable-5" ;;
*) err "Unknown driver '$1'. Valid: haiku sonnet opus opus-1m fable" ;;
esac esac
} }

View File

@@ -21,7 +21,7 @@ claude-profile [OPTIONS] [PROFILE] [-- CLAUDE_ARGS...]
| Flag | Description | | Flag | Description |
|------|-------------| |------|-------------|
| `--mode <NAME>` | Skip the mode picker and use the named mode (`chat`, `quick`, `deep`, `hybrid`, `orch`). | | `--mode <NAME>` | Skip the mode picker and use the named mode (`chat`, `quick`, `deep`, `deep-fable`, `hybrid`, `orch`). |
| `--preset <NAME>` | Use a named preset from the active profile's `presets.yaml`. Sets profile, mode, and any preset-defined defaults in one shot. | | `--preset <NAME>` | Use a named preset from the active profile's `presets.yaml`. Sets profile, mode, and any preset-defined defaults in one shot. |
| `--project <NAME>` | Pre-select a project (skips the project question for modes that ask it). | | `--project <NAME>` | Pre-select a project (skips the project question for modes that ask it). |
| `--dryrun`, `-n` | Print all resolved values and the command that would be executed; do not launch `claude`, do not write `active-mode.env` or `last-mode`. | | `--dryrun`, `-n` | Print all resolved values and the command that would be executed; do not launch `claude`, do not write `active-mode.env` or `last-mode`. |
@@ -64,8 +64,9 @@ The model ID is determined by combining the mode's `driver` field with the profi
|---|---| |---|---|
| `haiku` | `claude-haiku-4-5-20251001` | | `haiku` | `claude-haiku-4-5-20251001` |
| `sonnet` | `claude-sonnet-4-6` | | `sonnet` | `claude-sonnet-4-6` |
| `opus` | `claude-opus-4-6` | | `opus` | `claude-opus-4-8` |
| `opus-1m` | `claude-opus-4-6[1m]` | | `opus-1m` | `claude-opus-4-8[1m]` (Opus 4.8 has 1M context natively; `opus-1m` is retained for the `[1m]` launch convention) |
| `fable` | `claude-fable-5` |
2. If `$CLAUDE_CONFIG_DIR/provider.env` exists, parse it. If it contains a `MODEL_ID` entry, use that instead of the hardcoded default. 2. If `$CLAUDE_CONFIG_DIR/provider.env` exists, parse it. If it contains a `MODEL_ID` entry, use that instead of the hardcoded default.
@@ -95,7 +96,7 @@ YAML frontmatter (machine-readable) + markdown body (read by the driver model).
```yaml ```yaml
name: <short name, matches filename> name: <short name, matches filename>
tag: <status-line tag, ≤8 chars> tag: <status-line tag, ≤8 chars>
driver: <haiku|sonnet|opus|opus-1m> driver: <haiku|sonnet|opus|opus-1m|fable>
async_ok: <yes|no> async_ok: <yes|no>
autoloop: <none|"/loop 2m /orchestrate"|other slash command> autoloop: <none|"/loop 2m /orchestrate"|other slash command>
plan_mode_auto: <yes|no> plan_mode_auto: <yes|no>

View File

@@ -177,6 +177,63 @@ rc=$?
assert_exit_code "unknown flag exits 1" 1 "$rc" assert_exit_code "unknown flag exits 1" 1 "$rc"
assert_contains "unknown flag error message" "Unknown flag" "$out" assert_contains "unknown flag error message" "Unknown flag" "$out"
# === Test 13: deep-fable dryrun (deep-fable mode file lands in the next commit) ===
echo
echo "Test 13: deep-fable mode dryrun"
out=$(run --dryrun oreillyit-anthropic --mode deep-fable)
rc=$?
assert_exit_code "deep-fable dryrun exits 0" 0 "$rc"
assert_contains "deep-fable uses fable driver" "Driver: fable" "$out"
assert_contains "deep-fable shows fable model ID" "Model ID: claude-fable-5" "$out"
assert_contains "deep-fable shows model in exec command" "claude --model claude-fable-5" "$out"
# === Test 14: error — unknown driver produces exit 1 ===
echo
echo "Test 14: error path — unknown driver"
# Create a temporary mode file with an unknown driver in the actual modes dir,
# run the test, then remove it immediately.
baddriver_file="$REPO_ROOT/data/claude-profile/modes/_test-baddriver.md"
cat > "$baddriver_file" <<'MEOF'
---
name: _test-baddriver
tag: bad
driver: notadriver
async_ok: no
autoloop: none
plan_mode_auto: no
spec_driven: no
escalates_to: none
---
# Mode: Bad Driver Test
## Purpose
Temporary test fixture — do not use.
## Driver constraint
Unused.
## Subagent policy
Unused.
## Reasoning posture
Unused.
## Async policy
Unused.
## Workflow stance
Unused.
## Auto-fire at session start
none
## Status line format
none
## Escalation triggers
none
## Out of scope
none
## On context wipe (/clear)
none
MEOF
out=$(run --dryrun oreillyit-anthropic --mode _test-baddriver 2>&1); rc=$?
rm -f "$baddriver_file"
assert_exit_code "unknown driver exits 1" 1 "$rc"
assert_contains "unknown driver error message" "Unknown driver" "$out"
# === Summary === # === Summary ===
echo echo
echo "================================" echo "================================"