ok
This commit is contained in:
@@ -1,37 +1,113 @@
|
||||
# Track Specification: Per-Ticket Model Override (per_ticket_model_20260306)
|
||||
|
||||
## Overview
|
||||
Allow user to manually select which model to use for a specific ticket, overriding the default tier model.
|
||||
Allow user to manually select which model to use for a specific ticket, overriding the default tier model. Useful for forcing smarter model on hard tickets.
|
||||
|
||||
## Current State Audit
|
||||
|
||||
### Already Implemented
|
||||
- **`models.Ticket`**: Has no model_override field
|
||||
- **`multi_agent_conductor.py`**: Uses fixed model per tier
|
||||
- **`ai_client.py`**: `set_provider()`, `set_model()` functions
|
||||
### Already Implemented (DO NOT re-implement)
|
||||
|
||||
### Gaps to Fill
|
||||
- No model_override field on Ticket
|
||||
#### Ticket Model (src/models.py)
|
||||
- **`Ticket` dataclass**: Has `assigned_to` but no `model_override`
|
||||
- **`status` field**: "todo" | "in_progress" | "completed" | "blocked"
|
||||
- **No model selection per ticket**
|
||||
|
||||
#### Tier Usage (src/multi_agent_conductor.py)
|
||||
- **`ConductorEngine.tier_usage`**: Has per-tier model assignment
|
||||
```python
|
||||
self.tier_usage = {
|
||||
"Tier 1": {"input": 0, "output": 0, "model": "gemini-3.1-pro-preview"},
|
||||
"Tier 2": {"input": 0, "output": 0, "model": "gemini-3-flash-preview"},
|
||||
"Tier 3": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite"},
|
||||
"Tier 4": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite"},
|
||||
}
|
||||
```
|
||||
|
||||
#### Model Escalation (src/multi_agent_conductor.py)
|
||||
- **Already implemented in `run()`**: Escalation based on `retry_count`
|
||||
```python
|
||||
models = ["gemini-2.5-flash-lite", "gemini-2.5-flash", "gemini-3.1-pro-preview"]
|
||||
model_idx = min(ticket.retry_count, len(models) - 1)
|
||||
model_name = models[model_idx]
|
||||
```
|
||||
|
||||
### Gaps to Fill (This Track's Scope)
|
||||
- No `model_override` field on Ticket
|
||||
- No UI for model selection per ticket
|
||||
- No override indicator in GUI
|
||||
|
||||
## Functional Requirements
|
||||
- Add `model_override: Optional[str]` to Ticket dataclass
|
||||
- Model dropdown in ticket UI
|
||||
- Visual indicator when override active
|
||||
- Reset button to clear override
|
||||
## Architectural Constraints
|
||||
|
||||
## Key Integration Points
|
||||
| File | Purpose |
|
||||
|-----|---------|
|
||||
| `src/models.py` | Add model_override field |
|
||||
| `src/gui_2.py` | Model dropdown UI |
|
||||
| `src/multi_agent_conductor.py` | Use override at execution |
|
||||
### Validation
|
||||
- Selected model MUST be valid and available
|
||||
- Model list from `cost_tracker.MODEL_PRICING` or config
|
||||
|
||||
### Clear Override
|
||||
- Override MUST be visually distinct from default
|
||||
- Reset option MUST return to tier default
|
||||
|
||||
## Architecture Reference
|
||||
|
||||
### Key Integration Points
|
||||
|
||||
| File | Lines | Purpose |
|
||||
|------|-------|---------|
|
||||
| `src/models.py` | 30-50 | `Ticket` dataclass - add field |
|
||||
| `src/multi_agent_conductor.py` | 100-130 | Model selection logic |
|
||||
| `src/gui_2.py` | 2650-2750 | Ticket UI - add dropdown |
|
||||
|
||||
### Proposed Ticket Enhancement
|
||||
```python
|
||||
@dataclass
|
||||
class Ticket:
|
||||
# ... existing fields ...
|
||||
model_override: Optional[str] = None # None = use tier default
|
||||
```
|
||||
|
||||
## Functional Requirements
|
||||
|
||||
### FR1: Model Override Field
|
||||
- Add `model_override: Optional[str] = None` to Ticket dataclass
|
||||
- Persist in track state
|
||||
|
||||
### FR2: Model Dropdown UI
|
||||
- Dropdown in ticket node showing available models
|
||||
- Options: None (default), gemini-2.5-flash-lite, gemini-2.5-flash, gemini-3.1-pro-preview, etc.
|
||||
- Only show when ticket is "todo" status
|
||||
|
||||
### FR3: Override Indicator
|
||||
- Visual indicator when override is set (different color or icon)
|
||||
- Show "Using: {model_name}" in ticket display
|
||||
|
||||
### FR4: Execution Integration
|
||||
- In `ConductorEngine.run()`, check `ticket.model_override` first
|
||||
- If set, use override; otherwise use tier default
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
| Requirement | Constraint |
|
||||
|-------------|------------|
|
||||
| UI Response | Dropdown updates immediately |
|
||||
| Persistence | Override saved to state.toml |
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Unit Tests
|
||||
- Test model_override field serialization
|
||||
- Test override takes precedence at execution
|
||||
|
||||
### Integration Tests
|
||||
- Set override, run ticket, verify correct model used
|
||||
|
||||
## Out of Scope
|
||||
- Dynamic model list from API
|
||||
- Cost estimation preview before execution
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Model dropdown works
|
||||
- [ ] Override saves correctly
|
||||
- [ ] Visual indicator shows override
|
||||
- [ ] Reset returns to default
|
||||
- [ ] `model_override` field added to Ticket
|
||||
- [ ] Model dropdown works in UI
|
||||
- [ ] Override saves to track state
|
||||
- [ ] Visual indicator shows override active
|
||||
- [ ] Reset option clears override
|
||||
- [ ] Override used during execution
|
||||
- [ ] 1-space indentation
|
||||
- [ ] 1-space indentation maintained
|
||||
|
||||
Reference in New Issue
Block a user