docs: Add ai_client.py style curation implementation plan
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# ai_client.py Style Convention Curation Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Refactor `src/ai_client.py` to follow `conductor/code_styleguides/python.md` conventions (region blocks, module-level `ProviderError`, vertical compaction)
|
||||
|
||||
**Architecture:** Organizational refactor only — no logic changes. Move `ProviderError` class to module level, add `#region` sections, apply vertical alignment to dense conditionals.
|
||||
|
||||
**Tech Stack:** Python 3.11+, same codebase
|
||||
|
||||
---
|
||||
|
||||
## Pre-Work: Audit Current State
|
||||
|
||||
Before modifying, verify current line ranges and confirm exact locations for edits.
|
||||
|
||||
- [ ] **Step 1: Verify `ProviderError` location**
|
||||
|
||||
Run: `python -c "import src.ai_client; print(src.ai_client.ProviderError.__module__)"`
|
||||
Expected: `src.ai_client` (currently nested but accessible)
|
||||
|
||||
- [ ] **Step 2: Get exact line range of ai_client.py**
|
||||
|
||||
Run: `Get-Content src/ai_client.py | Measure-Object -Line`
|
||||
Expected: ~2522 lines
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Move `ProviderError` to Module Level
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ai_client.py:301-324`
|
||||
|
||||
- [ ] **Step 1: Read current `ProviderError` definition**
|
||||
|
||||
```python
|
||||
# Lines 301-324
|
||||
class ProviderError(Exception):
|
||||
def __init__(self, provider: str, message: str, code: str | None = None):
|
||||
self.provider = provider
|
||||
self.message = message
|
||||
self.code = code
|
||||
|
||||
def ui_message(self) -> str:
|
||||
lines = self.message.split("\n")
|
||||
first = lines[0]
|
||||
prefix = f"[{self.provider.upper()}] "
|
||||
if first.startswith(prefix):
|
||||
return first
|
||||
return f"{prefix}{first}"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Find insertion point (after imports, before first function)**
|
||||
|
||||
Read `src/ai_client.py:1-60` to find where imports end and first function begins (~line 54).
|
||||
|
||||
- [ ] **Step 3: Insert `ProviderError` at module level** (before line 54)
|
||||
|
||||
- [ ] **Step 4: Remove original `ProviderError` class definition** (lines 301-324)
|
||||
|
||||
- [ ] **Step 5: Verify no import changes needed** — class moved within same module
|
||||
|
||||
- [ ] **Step 6: Run syntax check**
|
||||
|
||||
Run: `uv run python -m py_compile src/ai_client.py`
|
||||
Expected: No errors
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ai_client.py
|
||||
git commit -m "refactor(ai_client): Move ProviderError to module level"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Add Region Blocks
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ai_client.py:54-2522` (throughout)
|
||||
|
||||
Insert `#region: Name` before first function of each section, `#endregion: Name` after last function.
|
||||
|
||||
Region order (follows logical flow from setup to public API):
|
||||
|
||||
| Order | Region Name | Start Line | End Line |
|
||||
|-------|-------------|------------|----------|
|
||||
| 1 | `#region: Provider Configuration` | after `ProviderError` | before `_get_proxy` |
|
||||
| 2 | `#region: Credentials & Setup` | `_get_proxy` | before `set_model_params` |
|
||||
| 3 | `#region: System Prompt Management` | `set_model_params` | before `get_current_tier` |
|
||||
| 4 | `#region: Thread Context` | `get_current_tier` | before `set_custom_system_prompt` |
|
||||
| 5 | `#region: Comms Log` | `set_custom_system_prompt` section | before `_classify_anthropic_error` |
|
||||
| 6 | `#region: Error Classification` | `_classify_anthropic_error` | before `set_provider` |
|
||||
| 7 | `#region: Provider Lifecycle` | `set_provider` | before `set_agent_tools` |
|
||||
| 8 | `#region: Tool Configuration` | `set_agent_tools` | before `_execute_tool_calls_concurrently` |
|
||||
| 9 | `#region: Tool Execution` | `_execute_tool_calls_concurrently` | before `_reread_file_items` |
|
||||
| 10 | `#region: File Context Building` | `_reread_file_items` | before `_estimate_message_tokens` |
|
||||
| 11 | `#region: Token Estimation` | `_estimate_message_tokens` | before `_send_gemini` |
|
||||
| 12 | `#region: Gemini Provider` | `_send_gemini` | before `_send_anthropic` |
|
||||
| 13 | `#region: Anthropic Provider` | `_send_anthropic` | before `_send_deepseek` |
|
||||
| 14 | `#region: DeepSeek Provider` | `_send_deepseek` | before `_send_minimax` |
|
||||
| 15 | `#region: MiniMax Provider` | `_send_minimax` | before `run_tier4_analysis` |
|
||||
| 16 | `#region: Tier 4 Analysis` | `run_tier4_analysis` | before `get_token_stats` |
|
||||
| 17 | `#region: Session & Public API` | `get_token_stats` | end of file |
|
||||
|
||||
- [ ] **Step 1: For each region, insert opening `#region: Name` on its own line before the first function in that group**
|
||||
|
||||
- [ ] **Step 2: For each region, insert closing `#endregion: Name` on its own line after the last function in that group**
|
||||
|
||||
- [ ] **Step 3: Run syntax check after all insertions**
|
||||
|
||||
Run: `uv run python -m py_compile src/ai_client.py`
|
||||
Expected: No errors
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ai_client.py
|
||||
git commit -m "refactor(ai_client): Add region blocks for organization"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Vertical Compaction Pass
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ai_client.py` (targeted sections)
|
||||
|
||||
- [ ] **Step 1: Identify dense conditionals for alignment**
|
||||
|
||||
Read `_classify_anthropic_error` (lines 326-351), `_classify_gemini_error` (353-377), `_classify_deepseek_error` (379-410), `_classify_minimax_error` (412-441).
|
||||
|
||||
- [ ] **Step 2: Apply vertical alignment to status/color mappings if present**
|
||||
|
||||
Look for patterns like:
|
||||
```python
|
||||
if status == 'running': col = (0.0, 1.0, 0.0, 1.0)
|
||||
elif status == 'starting': col = (1.0, 1.0, 0.0, 1.0)
|
||||
elif status == 'error': col = (1.0, 0.0, 0.0, 1.0)
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Run syntax check**
|
||||
|
||||
Run: `uv run python -m py_compile src/ai_client.py`
|
||||
Expected: No errors
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ai_client.py
|
||||
git commit -m "refactor(ai_client): Apply vertical compaction alignment"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Verify No Call Sites Broken
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/test_ai_client_concurrency.py`, `tests/test_bias_efficacy.py`, others
|
||||
|
||||
- [ ] **Step 1: Run ai_client-related tests**
|
||||
|
||||
Run: `uv run pytest tests/test_ai_client_concurrency.py tests/test_bias_efficacy.py tests/test_agent_capabilities_list_models.py -v --timeout=60`
|
||||
Expected: All pass
|
||||
|
||||
- [ ] **Step 2: If failures, diagnose and fix inline**
|
||||
|
||||
Do not skip — fix the issue or escalate.
|
||||
|
||||
- [ ] **Step 3: Commit final verification**
|
||||
|
||||
```bash
|
||||
git add src/ai_client.py
|
||||
git commit -m "test(ai_client): Verify no call sites broken after style refactor"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
- [ ] **Step 1: Run full ai_client test suite**
|
||||
|
||||
Run: `uv run pytest tests/test_ai_client*.py -v --timeout=120` (batch if many files)
|
||||
Expected: All pass
|
||||
|
||||
- [ ] **Step 2: Run lint check**
|
||||
|
||||
Run: `uv run ruff check src/ai_client.py`
|
||||
Expected: No errors (or only pre-existing warnings)
|
||||
|
||||
- [ ] **Step 3: Final commit**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "conductor(checkpoint): ai_client.py style curation complete"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Plan complete and saved to `docs/superpowers/plans/2026-05-13-ai-client-style-curation-plan.md`.**
|
||||
|
||||
**Two execution options:**
|
||||
|
||||
**1. Subagent-Driven (recommended)** - Dispatch a fresh subagent per task, review between tasks, fast iteration
|
||||
|
||||
**2. Inline Execution** - Execute tasks in this session using executing-plans, batch execution with checkpoints
|
||||
|
||||
**Which approach?**
|
||||
Reference in New Issue
Block a user