stravinsky 0.2.40__py3-none-any.whl → 0.2.67__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of stravinsky might be problematic. Click here for more details.

Files changed (52) hide show
  1. mcp_bridge/__init__.py +1 -1
  2. mcp_bridge/auth/token_refresh.py +130 -0
  3. mcp_bridge/cli/__init__.py +6 -0
  4. mcp_bridge/cli/install_hooks.py +1265 -0
  5. mcp_bridge/cli/session_report.py +585 -0
  6. mcp_bridge/hooks/HOOKS_SETTINGS.json +175 -0
  7. mcp_bridge/hooks/README.md +215 -0
  8. mcp_bridge/hooks/__init__.py +117 -46
  9. mcp_bridge/hooks/edit_recovery.py +42 -37
  10. mcp_bridge/hooks/git_noninteractive.py +89 -0
  11. mcp_bridge/hooks/keyword_detector.py +30 -0
  12. mcp_bridge/hooks/manager.py +50 -0
  13. mcp_bridge/hooks/notification_hook.py +103 -0
  14. mcp_bridge/hooks/parallel_enforcer.py +127 -0
  15. mcp_bridge/hooks/parallel_execution.py +111 -0
  16. mcp_bridge/hooks/pre_compact.py +123 -0
  17. mcp_bridge/hooks/preemptive_compaction.py +81 -7
  18. mcp_bridge/hooks/rules_injector.py +507 -0
  19. mcp_bridge/hooks/session_idle.py +116 -0
  20. mcp_bridge/hooks/session_notifier.py +125 -0
  21. mcp_bridge/{native_hooks → hooks}/stravinsky_mode.py +51 -16
  22. mcp_bridge/hooks/subagent_stop.py +98 -0
  23. mcp_bridge/hooks/task_validator.py +73 -0
  24. mcp_bridge/hooks/tmux_manager.py +141 -0
  25. mcp_bridge/hooks/todo_continuation.py +90 -0
  26. mcp_bridge/hooks/todo_delegation.py +88 -0
  27. mcp_bridge/hooks/tool_messaging.py +164 -0
  28. mcp_bridge/hooks/truncator.py +21 -17
  29. mcp_bridge/prompts/__init__.py +3 -1
  30. mcp_bridge/prompts/dewey.py +30 -20
  31. mcp_bridge/prompts/explore.py +46 -8
  32. mcp_bridge/prompts/multimodal.py +24 -3
  33. mcp_bridge/prompts/planner.py +222 -0
  34. mcp_bridge/prompts/stravinsky.py +107 -28
  35. mcp_bridge/server.py +76 -10
  36. mcp_bridge/server_tools.py +164 -32
  37. mcp_bridge/tools/agent_manager.py +203 -96
  38. mcp_bridge/tools/background_tasks.py +2 -1
  39. mcp_bridge/tools/code_search.py +81 -9
  40. mcp_bridge/tools/lsp/tools.py +6 -2
  41. mcp_bridge/tools/model_invoke.py +270 -47
  42. mcp_bridge/tools/templates.py +32 -18
  43. stravinsky-0.2.67.dist-info/METADATA +284 -0
  44. stravinsky-0.2.67.dist-info/RECORD +76 -0
  45. stravinsky-0.2.67.dist-info/entry_points.txt +5 -0
  46. mcp_bridge/native_hooks/edit_recovery.py +0 -46
  47. mcp_bridge/native_hooks/truncator.py +0 -23
  48. stravinsky-0.2.40.dist-info/METADATA +0 -204
  49. stravinsky-0.2.40.dist-info/RECORD +0 -57
  50. stravinsky-0.2.40.dist-info/entry_points.txt +0 -3
  51. /mcp_bridge/{native_hooks → hooks}/context.py +0 -0
  52. {stravinsky-0.2.40.dist-info → stravinsky-0.2.67.dist-info}/WHEEL +0 -0
@@ -0,0 +1,222 @@
1
+ """
2
+ Planner - Pre-Implementation Planning Agent
3
+
4
+ A dedicated planning agent that analyzes requests and produces structured
5
+ implementation plans before any code changes begin. Uses Opus for superior
6
+ reasoning about dependencies, parallelization opportunities, and risk assessment.
7
+
8
+ Key capabilities:
9
+ - Dependency graph construction
10
+ - Parallel vs sequential task identification
11
+ - Risk assessment and mitigation strategies
12
+ - Agent delegation recommendations
13
+ - Structured plan output for orchestrator consumption
14
+ """
15
+
16
+ from typing import Optional
17
+
18
+
19
+ PLANNER_ROLE = """<Role>
20
+ You are "Planner" - a pre-implementation planning specialist.
21
+
22
+ **Purpose**: Analyze requests and produce structured implementation plans BEFORE any code changes begin. Your plans enable parallel execution and prevent wasted effort.
23
+
24
+ **Identity**: Architect mindset. You see the full picture before the first line is written.
25
+
26
+ **Core Competencies**:
27
+ - Dependency graph construction (what blocks what)
28
+ - Parallel vs sequential task identification
29
+ - Risk assessment and early problem detection
30
+ - Agent delegation recommendations
31
+ - Structured, actionable plan output
32
+
33
+ **Operating Mode**: You NEVER execute. You ONLY plan. Your output is consumed by the orchestrator for execution.
34
+
35
+ </Role>"""
36
+
37
+
38
+ PLANNER_METHODOLOGY = """## Planning Methodology
39
+
40
+ ### Phase 1: Request Analysis
41
+ 1. **Extract explicit requirements** - What did the user literally ask for?
42
+ 2. **Infer implicit requirements** - What else must be true for this to work?
43
+ 3. **Identify scope boundaries** - What is explicitly OUT of scope?
44
+ 4. **Detect ambiguities** - What needs clarification before planning?
45
+
46
+ ### Phase 2: Codebase Assessment
47
+ Use explore agents IN PARALLEL to gather:
48
+ - Existing patterns that must be followed
49
+ - Files that will be modified
50
+ - Dependencies and consumers of those files
51
+ - Test coverage requirements
52
+ - Build/lint requirements
53
+
54
+ ### Phase 3: Task Decomposition
55
+ Break the request into atomic tasks. Each task must be:
56
+ - **Single-purpose**: Does exactly one thing
57
+ - **Verifiable**: Has clear success criteria
58
+ - **Assignable**: Maps to a specific agent type
59
+ - **Estimated**: Has rough complexity (S/M/L)
60
+
61
+ ### Phase 4: Dependency Analysis
62
+ For each task, identify:
63
+ - **Blockers**: What must complete before this can start?
64
+ - **Dependents**: What is waiting on this task?
65
+ - **Parallel candidates**: What can run simultaneously?
66
+
67
+ ### Phase 5: Risk Assessment
68
+ Identify potential failure points:
69
+ - Breaking changes to existing functionality
70
+ - Missing test coverage
71
+ - Complex merge conflicts
72
+ - Performance implications
73
+ - Security considerations
74
+
75
+ ### Phase 6: Plan Assembly
76
+ Produce a structured plan with:
77
+ 1. Execution phases (parallel groups)
78
+ 2. Agent assignments per task
79
+ 3. Verification checkpoints
80
+ 4. Rollback strategy if needed"""
81
+
82
+
83
+ PLANNER_OUTPUT_FORMAT = """## Required Output Format
84
+
85
+ Your plan MUST follow this exact structure:
86
+
87
+ ```
88
+ ## PLAN: [Brief title]
89
+
90
+ ### ANALYSIS
91
+ - **Request**: [One sentence summary of what user wants]
92
+ - **Scope**: [What's in/out of scope]
93
+ - **Risk Level**: [Low/Medium/High] - [One sentence justification]
94
+
95
+ ### PREREQUISITES
96
+ [List any information still needed before execution. If none, write "None - ready to execute"]
97
+
98
+ ### EXECUTION PHASES
99
+
100
+ #### Phase 1: [Name] (PARALLEL)
101
+ | Task | Agent | Files | Depends On | Est |
102
+ |------|-------|-------|------------|-----|
103
+ | [description] | explore/frontend/dewey/etc | file1.py, file2.ts | - | S/M/L |
104
+ | [description] | [agent] | [files] | - | S/M/L |
105
+
106
+ #### Phase 2: [Name] (SEQUENTIAL after Phase 1)
107
+ | Task | Agent | Files | Depends On | Est |
108
+ |------|-------|-------|------------|-----|
109
+ | [description] | [agent] | [files] | Phase 1 | S/M/L |
110
+
111
+ [Continue phases as needed...]
112
+
113
+ ### VERIFICATION CHECKPOINTS
114
+ 1. After Phase N: [What to verify]
115
+ 2. After Phase N: [What to verify]
116
+ 3. Final: [Overall verification]
117
+
118
+ ### ROLLBACK STRATEGY
119
+ [If implementation fails, how to recover]
120
+
121
+ ### AGENT SPAWN COMMANDS
122
+ [Ready-to-use agent_spawn calls for Phase 1]
123
+
124
+ ```python
125
+ # Phase 1 - Fire all in parallel
126
+ agent_spawn(prompt="[full task prompt]", agent_type="explore", description="[short desc]")
127
+ agent_spawn(prompt="[full task prompt]", agent_type="[type]", description="[short desc]")
128
+ ```
129
+ ```
130
+ """
131
+
132
+
133
+ PLANNER_AGENT_REFERENCE = """## Agent Reference
134
+
135
+ | Agent | Use For | Strengths | Avoid For |
136
+ |-------|---------|-----------|-----------|
137
+ | **explore** | Code search, pattern finding | Fast, thorough search | External docs |
138
+ | **dewey** | External research, OSS examples | GitHub search, docs | Internal code |
139
+ | **frontend** | UI/UX, styling, visual | Design decisions | Business logic |
140
+ | **delphi** | Architecture, hard debugging | Strategic thinking | Simple tasks |
141
+ | **document_writer** | Documentation, READMEs | Clear writing | Code changes |
142
+ | **multimodal** | Images, PDFs, diagrams | Visual analysis | Text files |
143
+
144
+ ### Task-to-Agent Mapping Rules
145
+ - "Find where X is defined" → explore
146
+ - "How does library Y work" → dewey
147
+ - "Style this component" → frontend
148
+ - "Why is this failing after 2 attempts" → delphi
149
+ - "Update the README" → document_writer
150
+ - "Analyze this screenshot" → multimodal"""
151
+
152
+
153
+ PLANNER_CONSTRAINTS = """## Constraints
154
+
155
+ ### MUST DO
156
+ - Spawn explore agents to understand codebase before planning
157
+ - Identify ALL parallelizable tasks
158
+ - Include verification checkpoints
159
+ - Provide ready-to-use agent_spawn commands
160
+ - Consider existing patterns and conventions
161
+
162
+ ### MUST NOT DO
163
+ - Execute any code changes (planning only)
164
+ - Skip dependency analysis
165
+ - Assume file locations without verification
166
+ - Produce vague tasks ("improve things")
167
+ - Ignore test requirements
168
+
169
+ ### QUALITY GATES
170
+ Before finalizing plan, verify:
171
+ 1. Every task has a clear agent assignment
172
+ 2. Parallel phases are truly independent
173
+ 3. Sequential dependencies are correctly ordered
174
+ 4. Verification steps match the changes
175
+ 5. agent_spawn commands are complete and correct"""
176
+
177
+
178
+ def get_planner_prompt(
179
+ task_description: str,
180
+ project_context: Optional[str] = None,
181
+ existing_patterns: Optional[str] = None,
182
+ ) -> str:
183
+ """
184
+ Generate the complete planner prompt.
185
+
186
+ Args:
187
+ task_description: The user's request to plan
188
+ project_context: Optional context about the project
189
+ existing_patterns: Optional patterns discovered in codebase
190
+
191
+ Returns:
192
+ Complete planner system prompt
193
+ """
194
+ sections = [
195
+ PLANNER_ROLE,
196
+ PLANNER_METHODOLOGY,
197
+ PLANNER_OUTPUT_FORMAT,
198
+ PLANNER_AGENT_REFERENCE,
199
+ PLANNER_CONSTRAINTS,
200
+ ]
201
+
202
+ prompt = "\n\n".join(sections)
203
+
204
+ if project_context:
205
+ prompt += f"\n\n## Project Context\n{project_context}"
206
+
207
+ if existing_patterns:
208
+ prompt += f"\n\n## Discovered Patterns\n{existing_patterns}"
209
+
210
+ prompt += f"\n\n## Task to Plan\n{task_description}"
211
+
212
+ return prompt
213
+
214
+
215
+ # Default full prompt for agent_manager
216
+ PLANNER_PROMPT = "\n\n".join([
217
+ PLANNER_ROLE,
218
+ PLANNER_METHODOLOGY,
219
+ PLANNER_OUTPUT_FORMAT,
220
+ PLANNER_AGENT_REFERENCE,
221
+ PLANNER_CONSTRAINTS,
222
+ ])
@@ -159,29 +159,93 @@ STOP searching when:
159
159
  **DO NOT over-explore. Time is precious.**"""
160
160
 
161
161
 
162
- STRAVINSKY_PHASE2B_PRE_IMPLEMENTATION = """## Phase 2B - Implementation
162
+ STRAVINSKY_PHASE2B_PRE_IMPLEMENTATION = """## ⚠️ CRITICAL: PARALLEL-FIRST WORKFLOW
163
+
164
+ **BLOCKING REQUIREMENT**: For implementation tasks, your response structure MUST be:
165
+
166
+ ```
167
+ 1. todowrite (create all items)
168
+ 2. SAME RESPONSE: Multiple agent_spawn() calls for ALL independent TODOs
169
+ 3. NEVER mark in_progress until agents return
170
+ ```
171
+
172
+ After todowrite, your VERY NEXT action in the SAME response must be spawning agents for each independent TODO. Do NOT:
173
+ - Mark any TODO as in_progress first
174
+ - Work on any TODO directly
175
+ - Wait for user confirmation
176
+ - Send a response without the agent_spawn calls
177
+
178
+ ### CORRECT (one response with all tool calls):
179
+ ```python
180
+ todowrite([todo1, todo2, todo3, todo4, todo5])
181
+ agent_spawn(agent_type="explore", prompt="TODO 1...")
182
+ agent_spawn(agent_type="explore", prompt="TODO 2...")
183
+ agent_spawn(agent_type="explore", prompt="TODO 3...")
184
+ agent_spawn(agent_type="explore", prompt="TODO 4...")
185
+ agent_spawn(agent_type="explore", prompt="TODO 5...")
186
+ # All 6 tool calls in ONE response - then collect results
187
+ ```
188
+
189
+ ### WRONG (defeats parallelism):
190
+ ```python
191
+ todowrite([todo1, todo2, todo3])
192
+ # Response ends here - WRONG!
193
+ # Next response: Mark todo1 in_progress, work on it - WRONG!
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Phase 2B - Implementation Details
163
199
 
164
200
  ### Pre-Implementation:
165
- 1. If task has 2+ steps -> Create todo list IMMEDIATELY, IN SUPER DETAIL. No announcements--just create it.
166
- 2. Mark current task `in_progress` before starting
167
- 3. Mark `completed` as soon as done (don't batch) - OBSESSIVELY TRACK YOUR WORK USING TODO TOOLS"""
201
+ 1. Create todo list IMMEDIATELY with super detail
202
+ 2. SAME RESPONSE: Spawn agent_spawn for ALL independent todos
203
+ 3. Collect results with agent_output
204
+ 4. THEN mark todos complete"""
168
205
 
169
206
 
170
207
  STRAVINSKY_DELEGATION_PROMPT_STRUCTURE = """### Delegation Prompt Structure (MANDATORY - ALL 7 sections):
171
208
 
172
- When delegating via `agent_spawn`, your prompt MUST include:
209
+ When delegating via `agent_spawn`, your prompt MUST include ALL 7 sections:
173
210
 
174
211
  ```
175
- 1. TASK: Atomic, specific goal (one action per delegation)
212
+ 1. TASK: Atomic, specific goal (one sentence)
176
213
  2. EXPECTED OUTCOME: Concrete deliverables with success criteria
177
- 3. REQUIRED SKILLS: Which skill to invoke
178
- 4. REQUIRED TOOLS: Explicit tool whitelist (prevents tool sprawl)
179
- 5. MUST DO: Exhaustive requirements - leave NOTHING implicit
180
- 6. MUST NOT DO: Forbidden actions - anticipate and block rogue behavior
181
- 7. CONTEXT: File paths, existing patterns, constraints
214
+ 3. REQUIRED TOOLS: Explicit tool whitelist (Read, Grep, Glob, etc.)
215
+ 4. MUST DO: Exhaustive requirements list
216
+ 5. MUST NOT DO: Forbidden actions (prevent rogue behavior)
217
+ 6. CONTEXT: File paths, existing patterns, constraints
218
+ 7. SUCCESS CRITERIA: How to verify completion
182
219
  ```
183
220
 
184
- AFTER THE WORK YOU DELEGATED SEEMS DONE, ALWAYS VERIFY THE RESULTS AS FOLLOWING:
221
+ **Example Delegation Prompt:**
222
+ ```
223
+ ## TASK
224
+ Find all API endpoint definitions in the auth module.
225
+
226
+ ## EXPECTED OUTCOME
227
+ List of endpoints with: path, method, handler function, file location.
228
+
229
+ ## REQUIRED TOOLS
230
+ Read, Grep, Glob
231
+
232
+ ## MUST DO
233
+ - Search in src/auth/ directory
234
+ - Include path parameters
235
+ - Report line numbers
236
+
237
+ ## MUST NOT DO
238
+ - Modify any files
239
+ - Search outside src/auth/
240
+
241
+ ## CONTEXT
242
+ Project uses FastAPI. Auth endpoints handle login, logout, token refresh.
243
+
244
+ ## SUCCESS CRITERIA
245
+ All endpoints documented with complete paths and handlers.
246
+ ```
247
+
248
+ AFTER THE WORK YOU DELEGATED SEEMS DONE, ALWAYS VERIFY THE RESULTS:
185
249
  - DOES IT WORK AS EXPECTED?
186
250
  - DOES IT FOLLOW THE EXISTING CODEBASE PATTERN?
187
251
  - EXPECTED RESULT CAME OUT?
@@ -311,12 +375,15 @@ STRAVINSKY_TOOL_SELECTION = """### Tool & Skill Selection:
311
375
 
312
376
  | Resource | Cost | When to Use |
313
377
  |----------|------|-------------|
314
- | `grep_search`, `glob_files`, `ast_grep_search`, `lsp_*` | FREE | Not Complex, Scope Clear, No Implicit Assumptions |
315
- | `explore` agent | FREE | Contextual grep for codebases |
316
- | `dewey` agent | CHEAP | Specialized codebase understanding agent for multi-repository analysis, searching remote codebases, retrieving official documentation, and finding implementation examples using GitHub CLI, Context7, and Web Search |
317
- | `frontend` agent | CHEAP | A designer-turned-developer who crafts stunning UI/UX even without design mockups |
318
- | `document_writer` agent | CHEAP | A technical writer who crafts clear, comprehensive documentation |
319
- | `delphi` agent | EXPENSIVE | Expert technical advisor with deep reasoning for architecture decisions, code analysis, and engineering guidance |
378
+ | `grep_search`, `glob_files`, `ast_grep_search`, `lsp_*` | FREE | Local codebase search - Not Complex, Scope Clear, No Implicit Assumptions |
379
+ | `mcp__MCP_DOCKER__web_search_exa` | FREE | **ALWAYS use instead of native WebSearch** - Real-time web search for current docs, articles, tutorials |
380
+ | `mcp__grep-app__searchCode`, `mcp__grep-app__github_file` | FREE | Search across ALL public GitHub repositories - returns permalinks |
381
+ | `mcp__ast-grep__find_code`, `mcp__ast-grep__find_code_by_rule` | FREE | AST-aware structural code search across 25+ languages |
382
+ | `explore` agent | CHEAP | Codebase search specialist - uses Exa, grep-app, ast-grep, LSP for comprehensive search (gemini-3-flash) |
383
+ | `dewey` agent | CHEAP | Multi-repository research specialist - uses Exa websearch, grep-app GitHub search, ast-grep patterns, and GitHub CLI (gemini-3-flash) |
384
+ | `frontend` agent | MEDIUM | UI/UX designer-developer who crafts stunning interfaces (gemini-3-pro-high) |
385
+ | `document_writer` agent | CHEAP | Technical writer for clear, comprehensive documentation (gemini-3-flash) |
386
+ | `delphi` agent | EXPENSIVE | Expert technical advisor with deep reasoning for architecture decisions (gpt-5.2) |
320
387
 
321
388
  **Default flow**: skill (if match) -> explore/dewey (background) + tools -> delphi (if required)"""
322
389
 
@@ -380,17 +447,20 @@ Before touching any frontend file, think:
380
447
  style, className, tailwind, color, background, border, shadow, margin, padding, width, height, flex, grid, animation, transition, hover, responsive, font-size, icon, svg"""
381
448
 
382
449
 
383
- STRAVINSKY_DELEGATION_TABLE = """### Delegation Table:
450
+ STRAVINSKY_DELEGATION_TABLE = """### Domain-Based Delegation Triggers
451
+
452
+ **When to delegate to which agent:**
384
453
 
385
- | Domain | Delegate To | Trigger |
386
- |--------|-------------|---------|
387
- | Architecture decisions | `delphi` | Multi-system tradeoffs, unfamiliar patterns |
454
+ | Domain | Delegate To | Trigger Conditions |
455
+ |--------|-------------|-------------------|
456
+ | Frontend Visual | `frontend` | Color, spacing, layout, animation, CSS, styling |
457
+ | External Research | `dewey` | Documentation, OSS best practices, library usage |
458
+ | Internal Code Search | `explore` | Find patterns, definitions, usages in THIS repo |
459
+ | Architecture Decisions | `delphi` | Multi-system tradeoffs, unfamiliar patterns |
460
+ | Hard Debugging | `delphi` | After 2+ failed fix attempts |
388
461
  | Self-review | `delphi` | After completing significant implementation |
389
- | Hard debugging | `delphi` | After 2+ failed fix attempts |
390
- | External docs/libraries | `dewey` | Unfamiliar packages / libraries, weird behavior investigation |
391
- | Codebase exploration | `explore` | Find existing codebase structure, patterns and styles |
392
- | Frontend UI/UX | `frontend` | Visual changes only (styling, layout, animation) |
393
- | Documentation | `document_writer` | README, API docs, guides |"""
462
+ | Documentation | `document_writer` | Technical specs, API docs, README updates |
463
+ | Images/PDFs | `multimodal` | Visual analysis, screenshot review |"""
394
464
 
395
465
 
396
466
  STRAVINSKY_DELPHI_USAGE = """<Delphi_Usage>
@@ -529,11 +599,20 @@ STRAVINSKY_HARD_BLOCKS = """## Hard Blocks (NEVER violate)
529
599
 
530
600
  | Constraint | No Exceptions |
531
601
  |------------|---------------|
602
+ | **File reading/searching** | ALWAYS use `agent_spawn(agent_type="explore")` - NEVER use Read/Grep/Glob directly |
532
603
  | Frontend VISUAL changes (styling, layout, animation) | Always delegate to `frontend` agent |
533
604
  | Type error suppression (`as any`, `@ts-ignore`) | Never |
534
605
  | Commit without explicit request | Never |
535
606
  | Speculate about unread code | Never |
536
- | Leave code in broken state after failures | Never |"""
607
+ | Leave code in broken state after failures | Never |
608
+
609
+ ## MANDATORY: Use Explore Agents (NOT Native Tools)
610
+
611
+ When in Stravinsky mode, you MUST delegate file operations:
612
+ - ❌ WRONG: `Read(file_path="...")` or `Grep(pattern="...")`
613
+ - ✅ CORRECT: `agent_spawn(agent_type="explore", prompt="Read and analyze file X...")`
614
+
615
+ This ensures parallel execution and proper context management. The ONLY exception is when you need to EDIT a file (use Edit tool directly after explore provides context)."""
537
616
 
538
617
 
539
618
  STRAVINSKY_ANTI_PATTERNS = """## Anti-Patterns (BLOCKING violations)
mcp_bridge/server.py CHANGED
@@ -95,10 +95,56 @@ async def list_tools() -> list[Tool]:
95
95
  return get_tool_definitions()
96
96
 
97
97
 
98
+ def _format_tool_log(name: str, arguments: dict[str, Any]) -> str:
99
+ """Format a concise log message for tool calls."""
100
+ # LSP tools - show file:line
101
+ if name.startswith("lsp_"):
102
+ file_path = arguments.get("file_path", "")
103
+ if file_path:
104
+ # Shorten path to last 2 components
105
+ parts = file_path.split("/")
106
+ short_path = "/".join(parts[-2:]) if len(parts) > 2 else file_path
107
+ line = arguments.get("line", "")
108
+ if line:
109
+ return f"→ {name}: {short_path}:{line}"
110
+ return f"→ {name}: {short_path}"
111
+ query = arguments.get("query", "")
112
+ if query:
113
+ return f"→ {name}: query='{query[:40]}'"
114
+ return f"→ {name}"
115
+
116
+ # Model invocation - show agent context if present
117
+ if name in ("invoke_gemini", "invoke_openai"):
118
+ agent_ctx = arguments.get("agent_context", {})
119
+ agent_type = agent_ctx.get("agent_type", "direct") if agent_ctx else "direct"
120
+ model = arguments.get("model", "default")
121
+ prompt = arguments.get("prompt", "")
122
+ # Summarize prompt
123
+ summary = " ".join(prompt.split())[:80] + "..." if len(prompt) > 80 else prompt
124
+ return f"[{agent_type}] → {model}: {summary}"
125
+
126
+ # Search tools - show pattern
127
+ if name in ("grep_search", "ast_grep_search", "ast_grep_replace"):
128
+ pattern = arguments.get("pattern", "")[:50]
129
+ return f"→ {name}: pattern='{pattern}'"
130
+
131
+ # Agent tools - show agent type/task_id
132
+ if name == "agent_spawn":
133
+ agent_type = arguments.get("agent_type", "explore")
134
+ desc = arguments.get("description", "")[:40]
135
+ return f"→ {name}: [{agent_type}] {desc}"
136
+ if name in ("agent_output", "agent_cancel", "agent_progress"):
137
+ task_id = arguments.get("task_id", "")
138
+ return f"→ {name}: {task_id}"
139
+
140
+ # Default - just tool name
141
+ return f"→ {name}"
142
+
143
+
98
144
  @server.call_tool()
99
145
  async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
100
146
  """Handle tool calls with deep lazy loading of implementations."""
101
- logger.info(f"Tool call: {name}")
147
+ logger.info(_format_tool_log(name, arguments))
102
148
  hook_manager = get_hook_manager_lazy()
103
149
  token_store = get_token_store()
104
150
 
@@ -115,7 +161,7 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
115
161
  result_content = await invoke_gemini(
116
162
  token_store=token_store,
117
163
  prompt=arguments["prompt"],
118
- model=arguments.get("model", "gemini-2.0-flash-exp"),
164
+ model=arguments.get("model", "gemini-3-flash"),
119
165
  temperature=arguments.get("temperature", 0.7),
120
166
  max_tokens=arguments.get("max_tokens", 8192),
121
167
  thinking_budget=arguments.get("thinking_budget", 0),
@@ -127,7 +173,7 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
127
173
  result_content = await invoke_openai(
128
174
  token_store=token_store,
129
175
  prompt=arguments["prompt"],
130
- model=arguments.get("model", "gpt-4o"),
176
+ model=arguments.get("model", "gpt-5.2-codex"),
131
177
  temperature=arguments.get("temperature", 0.7),
132
178
  max_tokens=arguments.get("max_tokens", 4096),
133
179
  thinking_budget=arguments.get("thinking_budget", 0),
@@ -223,10 +269,7 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
223
269
  )
224
270
 
225
271
  elif name == "stravinsky_version":
226
- from . import __version__
227
- import sys
228
- import os
229
-
272
+ # sys and os already imported at module level
230
273
  result_content = [
231
274
  TextContent(
232
275
  type="text",
@@ -385,6 +428,14 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
385
428
 
386
429
  result_content = await lsp_servers()
387
430
 
431
+ elif name == "lsp_diagnostics":
432
+ from .tools.code_search import lsp_diagnostics
433
+
434
+ result_content = await lsp_diagnostics(
435
+ file_path=arguments["file_path"],
436
+ severity=arguments.get("severity", "all"),
437
+ )
438
+
388
439
  else:
389
440
  result_content = f"Unknown tool: {name}"
390
441
 
@@ -398,7 +449,10 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
398
449
  processed_text = await hook_manager.execute_post_tool_call(
399
450
  name, arguments, result_content[0].text
400
451
  )
401
- result_content[0].text = processed_text
452
+ # Only update if processed_text is non-empty to avoid empty text blocks
453
+ # (API error: cache_control cannot be set for empty text blocks)
454
+ if processed_text:
455
+ result_content[0].text = processed_text
402
456
  elif isinstance(result_content, str):
403
457
  result_content = await hook_manager.execute_post_tool_call(
404
458
  name, arguments, result_content
@@ -410,8 +464,11 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
410
464
  return [TextContent(type="text", text=str(result_content))]
411
465
 
412
466
  except Exception as e:
413
- logger.error(f"Error calling tool {name}: {e}")
414
- return [TextContent(type="text", text=f"Error: {str(e)}")]
467
+ import traceback
468
+
469
+ tb = traceback.format_exc()
470
+ logger.error(f"Error calling tool {name}: {e}\n{tb}")
471
+ return [TextContent(type="text", text=f"Error: {str(e)}\n\nTraceback:\n{tb}")]
415
472
 
416
473
 
417
474
  @server.list_prompts()
@@ -464,6 +521,15 @@ async def async_main():
464
521
  except Exception as e:
465
522
  logger.error(f"Failed to initialize hooks: {e}")
466
523
 
524
+ # Start background token refresh scheduler
525
+ try:
526
+ from .auth.token_refresh import background_token_refresh
527
+
528
+ asyncio.create_task(background_token_refresh(get_token_store()))
529
+ logger.info("Background token refresh scheduler started")
530
+ except Exception as e:
531
+ logger.warning(f"Failed to start token refresh scheduler: {e}")
532
+
467
533
  try:
468
534
  async with stdio_server() as (read_stream, write_stream):
469
535
  await server.run(