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.
- mcp_bridge/__init__.py +1 -1
- mcp_bridge/auth/token_refresh.py +130 -0
- mcp_bridge/cli/__init__.py +6 -0
- mcp_bridge/cli/install_hooks.py +1265 -0
- mcp_bridge/cli/session_report.py +585 -0
- mcp_bridge/hooks/HOOKS_SETTINGS.json +175 -0
- mcp_bridge/hooks/README.md +215 -0
- mcp_bridge/hooks/__init__.py +117 -46
- mcp_bridge/hooks/edit_recovery.py +42 -37
- mcp_bridge/hooks/git_noninteractive.py +89 -0
- mcp_bridge/hooks/keyword_detector.py +30 -0
- mcp_bridge/hooks/manager.py +50 -0
- mcp_bridge/hooks/notification_hook.py +103 -0
- mcp_bridge/hooks/parallel_enforcer.py +127 -0
- mcp_bridge/hooks/parallel_execution.py +111 -0
- mcp_bridge/hooks/pre_compact.py +123 -0
- mcp_bridge/hooks/preemptive_compaction.py +81 -7
- mcp_bridge/hooks/rules_injector.py +507 -0
- mcp_bridge/hooks/session_idle.py +116 -0
- mcp_bridge/hooks/session_notifier.py +125 -0
- mcp_bridge/{native_hooks → hooks}/stravinsky_mode.py +51 -16
- mcp_bridge/hooks/subagent_stop.py +98 -0
- mcp_bridge/hooks/task_validator.py +73 -0
- mcp_bridge/hooks/tmux_manager.py +141 -0
- mcp_bridge/hooks/todo_continuation.py +90 -0
- mcp_bridge/hooks/todo_delegation.py +88 -0
- mcp_bridge/hooks/tool_messaging.py +164 -0
- mcp_bridge/hooks/truncator.py +21 -17
- mcp_bridge/prompts/__init__.py +3 -1
- mcp_bridge/prompts/dewey.py +30 -20
- mcp_bridge/prompts/explore.py +46 -8
- mcp_bridge/prompts/multimodal.py +24 -3
- mcp_bridge/prompts/planner.py +222 -0
- mcp_bridge/prompts/stravinsky.py +107 -28
- mcp_bridge/server.py +76 -10
- mcp_bridge/server_tools.py +164 -32
- mcp_bridge/tools/agent_manager.py +203 -96
- mcp_bridge/tools/background_tasks.py +2 -1
- mcp_bridge/tools/code_search.py +81 -9
- mcp_bridge/tools/lsp/tools.py +6 -2
- mcp_bridge/tools/model_invoke.py +270 -47
- mcp_bridge/tools/templates.py +32 -18
- stravinsky-0.2.67.dist-info/METADATA +284 -0
- stravinsky-0.2.67.dist-info/RECORD +76 -0
- stravinsky-0.2.67.dist-info/entry_points.txt +5 -0
- mcp_bridge/native_hooks/edit_recovery.py +0 -46
- mcp_bridge/native_hooks/truncator.py +0 -23
- stravinsky-0.2.40.dist-info/METADATA +0 -204
- stravinsky-0.2.40.dist-info/RECORD +0 -57
- stravinsky-0.2.40.dist-info/entry_points.txt +0 -3
- /mcp_bridge/{native_hooks → hooks}/context.py +0 -0
- {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
|
+
])
|
mcp_bridge/prompts/stravinsky.py
CHANGED
|
@@ -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 = """##
|
|
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.
|
|
166
|
-
2.
|
|
167
|
-
3.
|
|
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
|
|
212
|
+
1. TASK: Atomic, specific goal (one sentence)
|
|
176
213
|
2. EXPECTED OUTCOME: Concrete deliverables with success criteria
|
|
177
|
-
3. REQUIRED
|
|
178
|
-
4.
|
|
179
|
-
5. MUST DO:
|
|
180
|
-
6.
|
|
181
|
-
7.
|
|
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
|
-
|
|
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
|
-
| `
|
|
316
|
-
| `
|
|
317
|
-
| `
|
|
318
|
-
| `
|
|
319
|
-
| `
|
|
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
|
|
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
|
-
|
|
|
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
|
-
|
|
|
390
|
-
|
|
|
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(
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
414
|
-
|
|
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(
|