diff --git a/docs/superpowers/plans/2026-05-13-ai-client-style-curation-plan.md b/docs/superpowers/plans/2026-05-13-ai-client-style-curation-plan.md new file mode 100644 index 0000000..1293abb --- /dev/null +++ b/docs/superpowers/plans/2026-05-13-ai-client-style-curation-plan.md @@ -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?** \ No newline at end of file