|
| 1 | +# API & Interface Design: Model Selection by Role |
| 2 | + |
| 3 | +## Command-Line Interface |
| 4 | + |
| 5 | +### Option A: Using Existing RoleAgents (Recommended) |
| 6 | + |
| 7 | +No new CLI flags needed. Users define agent presets with models baked in: |
| 8 | + |
| 9 | +```bash |
| 10 | +# Town-level config: ~/gt/settings/agents.json |
| 11 | +{ |
| 12 | + "version": 1, |
| 13 | + "agents": { |
| 14 | + "claude-opus": { |
| 15 | + "command": "claude", |
| 16 | + "args": ["--dangerously-skip-permissions", "--model", "opus-4.5"] |
| 17 | + }, |
| 18 | + "claude-sonnet": { |
| 19 | + "command": "claude", |
| 20 | + "args": ["--dangerously-skip-permissions", "--model", "sonnet-4"] |
| 21 | + }, |
| 22 | + "claude-haiku": { |
| 23 | + "command": "claude", |
| 24 | + "args": ["--dangerously-skip-permissions", "--model", "haiku-3.5"] |
| 25 | + } |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +# Town-level settings: ~/gt/settings/config.json |
| 30 | +{ |
| 31 | + "type": "town-settings", |
| 32 | + "version": 1, |
| 33 | + "default_agent": "claude-opus", |
| 34 | + "role_agents": { |
| 35 | + "polecat": "claude-opus", |
| 36 | + "witness": "claude-sonnet", |
| 37 | + "refinery": "claude-haiku", |
| 38 | + "mayor": "claude-sonnet", |
| 39 | + "deacon": "claude-sonnet", |
| 40 | + "crew": "claude-sonnet" |
| 41 | + } |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +### Option B: New --model Flag (Alternative) |
| 46 | + |
| 47 | +Add explicit model flag to spawn commands: |
| 48 | + |
| 49 | +```bash |
| 50 | +# Override at spawn time |
| 51 | +gt sling <bead> <rig> --model sonnet |
| 52 | + |
| 53 | +# Show current model config |
| 54 | +gt config models |
| 55 | + |
| 56 | +# Set role model |
| 57 | +gt config set role-model polecat opus |
| 58 | +gt config set role-model witness sonnet |
| 59 | +``` |
| 60 | + |
| 61 | +### Subcommand Ergonomics |
| 62 | + |
| 63 | +If implementing Option B, new commands would be: |
| 64 | + |
| 65 | +```bash |
| 66 | +# View all model assignments |
| 67 | +gt config models |
| 68 | +# Output: |
| 69 | +# Role Model Source |
| 70 | +# ---- ----- ------ |
| 71 | +# polecat opus-4.5 rig (gastown) |
| 72 | +# witness sonnet-4 town |
| 73 | +# refinery haiku-3.5 default |
| 74 | +# crew sonnet-4 town |
| 75 | + |
| 76 | +# Set model for a role |
| 77 | +gt config set-model <role> <model> |
| 78 | + |
| 79 | +# List available models |
| 80 | +gt config list-models |
| 81 | +# Output: opus-4.5, sonnet-4, haiku-3.5 |
| 82 | +``` |
| 83 | + |
| 84 | +## Programmatic API |
| 85 | + |
| 86 | +### Configuration Interface (Go) |
| 87 | + |
| 88 | +For Option A (agent presets with models): |
| 89 | +```go |
| 90 | +// No API changes needed - use existing RoleAgents |
| 91 | + |
| 92 | +// Get agent for role (existing function) |
| 93 | +func ResolveRoleAgentConfig(role string, rigSettings *RigSettings, townSettings *TownSettings) (*AgentPresetInfo, error) |
| 94 | +``` |
| 95 | + |
| 96 | +For Option B (explicit model field): |
| 97 | +```go |
| 98 | +// New function to resolve model |
| 99 | +func ResolveRoleModel(role string, rigSettings *RigSettings, townSettings *TownSettings) string |
| 100 | + |
| 101 | +// Extended TownSettings |
| 102 | +type TownSettings struct { |
| 103 | + // ...existing fields... |
| 104 | + RoleModels map[string]string `json:"role_models,omitempty"` |
| 105 | +} |
| 106 | + |
| 107 | +// Extended RigSettings |
| 108 | +type RigSettings struct { |
| 109 | + // ...existing fields... |
| 110 | + RoleModels map[string]string `json:"role_models,omitempty"` |
| 111 | +} |
| 112 | +``` |
| 113 | + |
| 114 | +### Return Types |
| 115 | + |
| 116 | +Model resolution returns a simple string: |
| 117 | +- `"opus-4.5"` | `"sonnet-4"` | `"haiku-3.5"` | `""` |
| 118 | + |
| 119 | +Empty string means "use Claude's default" (currently Opus 4.5). |
| 120 | + |
| 121 | +## Configuration Interface |
| 122 | + |
| 123 | +### File Locations |
| 124 | + |
| 125 | +| Level | File | Purpose | |
| 126 | +|-------|------|---------| |
| 127 | +| Town | `~/gt/settings/agents.json` | Custom agent definitions with model args | |
| 128 | +| Town | `~/gt/settings/config.json` | Default agent and role_agents mapping | |
| 129 | +| Rig | `<rig>/settings/agents.json` | Rig-specific agent definitions | |
| 130 | +| Rig | `<rig>/settings/config.json` | Rig-specific overrides | |
| 131 | + |
| 132 | +### Environment Variables |
| 133 | + |
| 134 | +For runtime override (useful for debugging/testing): |
| 135 | +```bash |
| 136 | +GT_MODEL_OVERRIDE=haiku # Forces all roles to use haiku |
| 137 | +``` |
| 138 | + |
| 139 | +Not recommended for production use - config files are better for persistence. |
| 140 | + |
| 141 | +## Error Messages |
| 142 | + |
| 143 | +### Invalid Model Name |
| 144 | +``` |
| 145 | +Error: unknown model "gpt4" |
| 146 | +Available models: opus-4.5, sonnet-4, haiku-3.5 |
| 147 | +``` |
| 148 | + |
| 149 | +### Invalid Role Name |
| 150 | +``` |
| 151 | +Error: unknown role "worker" |
| 152 | +Valid roles: polecat, witness, refinery, mayor, deacon, crew |
| 153 | +``` |
| 154 | + |
| 155 | +### Config Validation |
| 156 | +``` |
| 157 | +Warning: role_agents references undefined agent "claude-fast" |
| 158 | +Available agents: claude, claude-opus, claude-sonnet, claude-haiku, gemini, codex |
| 159 | +``` |
| 160 | + |
| 161 | +## Help Text |
| 162 | + |
| 163 | +``` |
| 164 | +MODEL SELECTION |
| 165 | +
|
| 166 | +Gas Town supports per-role model selection for cost optimization. |
| 167 | +
|
| 168 | +Configuration: |
| 169 | + Define agent presets with model args in ~/gt/settings/agents.json: |
| 170 | +
|
| 171 | + { |
| 172 | + "agents": { |
| 173 | + "claude-opus": {"command": "claude", "args": ["--model", "opus-4.5"]}, |
| 174 | + "claude-sonnet": {"command": "claude", "args": ["--model", "sonnet-4"]} |
| 175 | + } |
| 176 | + } |
| 177 | +
|
| 178 | + Then assign to roles in ~/gt/settings/config.json: |
| 179 | +
|
| 180 | + { |
| 181 | + "role_agents": { |
| 182 | + "polecat": "claude-opus", |
| 183 | + "witness": "claude-sonnet" |
| 184 | + } |
| 185 | + } |
| 186 | +
|
| 187 | +Resolution order: |
| 188 | + 1. Rig role_agents (if set) |
| 189 | + 2. Town role_agents (if set) |
| 190 | + 3. Rig default_agent (if set) |
| 191 | + 4. Town default_agent (if set) |
| 192 | + 5. Built-in default: "claude" |
| 193 | +``` |
| 194 | + |
| 195 | +## Naming Conventions |
| 196 | + |
| 197 | +### Model Names |
| 198 | +Use Claude Code's short names for ergonomics: |
| 199 | +- `opus` → `opus-4.5` (aliases work) |
| 200 | +- `sonnet` → `sonnet-4` |
| 201 | +- `haiku` → `haiku-3.5` |
| 202 | + |
| 203 | +### Agent Preset Names |
| 204 | +Convention: `<cli>-<model>` for model variants: |
| 205 | +- `claude-opus` (Claude with Opus) |
| 206 | +- `claude-sonnet` (Claude with Sonnet) |
| 207 | +- `claude-haiku` (Claude with Haiku) |
| 208 | + |
| 209 | +## Discoverability |
| 210 | + |
| 211 | +### How Users Learn This Feature |
| 212 | + |
| 213 | +1. **Documentation**: Add section to Gas Town README and `gt help config` |
| 214 | +2. **Example configs**: Ship example `agents.json` with model presets |
| 215 | +3. **Status command**: `gt status` shows current model for each active agent |
| 216 | +4. **Cost reporting**: `gt costs` shows model breakdown (existing feature) |
| 217 | + |
| 218 | +### Happy Path |
| 219 | + |
| 220 | +1. User wants to reduce costs |
| 221 | +2. Runs `gt help config` or reads docs |
| 222 | +3. Copies example agent definitions to settings |
| 223 | +4. Maps roles to agents via `role_agents` |
| 224 | +5. Starts Gas Town - polecats run on Opus, others on Sonnet/Haiku |
| 225 | + |
| 226 | +### Edge Cases |
| 227 | + |
| 228 | +1. **Undefined agent**: Config references agent not in registry → warning, fall back to default |
| 229 | +2. **Invalid model**: Claude rejects model name → agent fails to start, error in logs |
| 230 | +3. **Mixed models in rig**: Different polecats in same rig can't use different models (by design) |
| 231 | + |
| 232 | +## Consistency with Existing Interfaces |
| 233 | + |
| 234 | +### Follows Existing Patterns |
| 235 | + |
| 236 | +- Uses same config file locations (`settings/config.json`, `settings/agents.json`) |
| 237 | +- Uses same resolution hierarchy (rig → town → default) |
| 238 | +- Uses same JSON schema patterns (`map[string]string` for mappings) |
| 239 | +- Uses existing `RoleAgents` field (Option A) |
| 240 | + |
| 241 | +### Changes from Existing Patterns |
| 242 | + |
| 243 | +- Option B would add a new `RoleModels` field (parallel to `RoleAgents`) |
| 244 | +- New CLI flags if implementing `gt config set-model` |
0 commit comments