stravinsky 0.4.18__py3-none-any.whl → 0.4.66__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 (184) hide show
  1. mcp_bridge/__init__.py +1 -1
  2. mcp_bridge/auth/__init__.py +16 -6
  3. mcp_bridge/auth/cli.py +202 -11
  4. mcp_bridge/auth/oauth.py +1 -2
  5. mcp_bridge/auth/openai_oauth.py +4 -7
  6. mcp_bridge/auth/token_store.py +0 -1
  7. mcp_bridge/cli/__init__.py +1 -1
  8. mcp_bridge/cli/install_hooks.py +503 -107
  9. mcp_bridge/cli/session_report.py +0 -3
  10. mcp_bridge/config/__init__.py +2 -2
  11. mcp_bridge/config/hook_config.py +3 -5
  12. mcp_bridge/config/rate_limits.py +108 -13
  13. mcp_bridge/hooks/HOOKS_SETTINGS.json +17 -4
  14. mcp_bridge/hooks/__init__.py +14 -4
  15. mcp_bridge/hooks/agent_reminder.py +4 -4
  16. mcp_bridge/hooks/auto_slash_command.py +5 -5
  17. mcp_bridge/hooks/budget_optimizer.py +2 -2
  18. mcp_bridge/hooks/claude_limits_hook.py +114 -0
  19. mcp_bridge/hooks/comment_checker.py +3 -4
  20. mcp_bridge/hooks/compaction.py +2 -2
  21. mcp_bridge/hooks/context.py +2 -1
  22. mcp_bridge/hooks/context_monitor.py +2 -2
  23. mcp_bridge/hooks/delegation_policy.py +85 -0
  24. mcp_bridge/hooks/directory_context.py +3 -3
  25. mcp_bridge/hooks/edit_recovery.py +3 -2
  26. mcp_bridge/hooks/edit_recovery_policy.py +49 -0
  27. mcp_bridge/hooks/empty_message_sanitizer.py +2 -2
  28. mcp_bridge/hooks/events.py +160 -0
  29. mcp_bridge/hooks/git_noninteractive.py +4 -4
  30. mcp_bridge/hooks/keyword_detector.py +8 -10
  31. mcp_bridge/hooks/manager.py +35 -22
  32. mcp_bridge/hooks/notification_hook.py +13 -6
  33. mcp_bridge/hooks/parallel_enforcement_policy.py +67 -0
  34. mcp_bridge/hooks/parallel_enforcer.py +5 -5
  35. mcp_bridge/hooks/parallel_execution.py +22 -10
  36. mcp_bridge/hooks/post_tool/parallel_validation.py +103 -0
  37. mcp_bridge/hooks/pre_compact.py +8 -9
  38. mcp_bridge/hooks/pre_tool/agent_spawn_validator.py +115 -0
  39. mcp_bridge/hooks/preemptive_compaction.py +2 -3
  40. mcp_bridge/hooks/routing_notifications.py +80 -0
  41. mcp_bridge/hooks/rules_injector.py +11 -19
  42. mcp_bridge/hooks/session_idle.py +4 -4
  43. mcp_bridge/hooks/session_notifier.py +4 -4
  44. mcp_bridge/hooks/session_recovery.py +4 -5
  45. mcp_bridge/hooks/stravinsky_mode.py +1 -1
  46. mcp_bridge/hooks/subagent_stop.py +1 -3
  47. mcp_bridge/hooks/task_validator.py +2 -2
  48. mcp_bridge/hooks/tmux_manager.py +7 -8
  49. mcp_bridge/hooks/todo_delegation.py +4 -1
  50. mcp_bridge/hooks/todo_enforcer.py +180 -10
  51. mcp_bridge/hooks/truncation_policy.py +37 -0
  52. mcp_bridge/hooks/truncator.py +1 -2
  53. mcp_bridge/metrics/cost_tracker.py +115 -0
  54. mcp_bridge/native_search.py +93 -0
  55. mcp_bridge/native_watcher.py +118 -0
  56. mcp_bridge/notifications.py +3 -4
  57. mcp_bridge/orchestrator/enums.py +11 -0
  58. mcp_bridge/orchestrator/router.py +165 -0
  59. mcp_bridge/orchestrator/state.py +32 -0
  60. mcp_bridge/orchestrator/visualization.py +14 -0
  61. mcp_bridge/orchestrator/wisdom.py +34 -0
  62. mcp_bridge/prompts/__init__.py +1 -8
  63. mcp_bridge/prompts/dewey.py +1 -1
  64. mcp_bridge/prompts/planner.py +2 -4
  65. mcp_bridge/prompts/stravinsky.py +53 -31
  66. mcp_bridge/proxy/__init__.py +0 -0
  67. mcp_bridge/proxy/client.py +70 -0
  68. mcp_bridge/proxy/model_server.py +157 -0
  69. mcp_bridge/routing/__init__.py +43 -0
  70. mcp_bridge/routing/config.py +250 -0
  71. mcp_bridge/routing/model_tiers.py +135 -0
  72. mcp_bridge/routing/provider_state.py +261 -0
  73. mcp_bridge/routing/task_classifier.py +190 -0
  74. mcp_bridge/server.py +363 -34
  75. mcp_bridge/server_tools.py +298 -6
  76. mcp_bridge/tools/__init__.py +19 -8
  77. mcp_bridge/tools/agent_manager.py +549 -799
  78. mcp_bridge/tools/background_tasks.py +13 -17
  79. mcp_bridge/tools/code_search.py +54 -51
  80. mcp_bridge/tools/continuous_loop.py +0 -1
  81. mcp_bridge/tools/dashboard.py +19 -0
  82. mcp_bridge/tools/find_code.py +296 -0
  83. mcp_bridge/tools/init.py +1 -0
  84. mcp_bridge/tools/list_directory.py +42 -0
  85. mcp_bridge/tools/lsp/__init__.py +8 -8
  86. mcp_bridge/tools/lsp/manager.py +51 -28
  87. mcp_bridge/tools/lsp/tools.py +98 -65
  88. mcp_bridge/tools/model_invoke.py +1047 -152
  89. mcp_bridge/tools/mux_client.py +75 -0
  90. mcp_bridge/tools/project_context.py +1 -2
  91. mcp_bridge/tools/query_classifier.py +132 -49
  92. mcp_bridge/tools/read_file.py +84 -0
  93. mcp_bridge/tools/replace.py +45 -0
  94. mcp_bridge/tools/run_shell_command.py +38 -0
  95. mcp_bridge/tools/search_enhancements.py +347 -0
  96. mcp_bridge/tools/semantic_search.py +677 -92
  97. mcp_bridge/tools/session_manager.py +0 -2
  98. mcp_bridge/tools/skill_loader.py +0 -1
  99. mcp_bridge/tools/task_runner.py +5 -7
  100. mcp_bridge/tools/templates.py +3 -3
  101. mcp_bridge/tools/tool_search.py +331 -0
  102. mcp_bridge/tools/write_file.py +29 -0
  103. mcp_bridge/update_manager.py +33 -37
  104. mcp_bridge/update_manager_pypi.py +6 -8
  105. mcp_bridge/utils/cache.py +82 -0
  106. mcp_bridge/utils/process.py +71 -0
  107. mcp_bridge/utils/session_state.py +51 -0
  108. mcp_bridge/utils/truncation.py +76 -0
  109. {stravinsky-0.4.18.dist-info → stravinsky-0.4.66.dist-info}/METADATA +84 -35
  110. stravinsky-0.4.66.dist-info/RECORD +198 -0
  111. {stravinsky-0.4.18.dist-info → stravinsky-0.4.66.dist-info}/entry_points.txt +1 -0
  112. stravinsky_claude_assets/HOOKS_INTEGRATION.md +316 -0
  113. stravinsky_claude_assets/agents/HOOKS.md +437 -0
  114. stravinsky_claude_assets/agents/code-reviewer.md +210 -0
  115. stravinsky_claude_assets/agents/comment_checker.md +580 -0
  116. stravinsky_claude_assets/agents/debugger.md +254 -0
  117. stravinsky_claude_assets/agents/delphi.md +495 -0
  118. stravinsky_claude_assets/agents/dewey.md +248 -0
  119. stravinsky_claude_assets/agents/explore.md +1198 -0
  120. stravinsky_claude_assets/agents/frontend.md +472 -0
  121. stravinsky_claude_assets/agents/implementation-lead.md +164 -0
  122. stravinsky_claude_assets/agents/momus.md +464 -0
  123. stravinsky_claude_assets/agents/research-lead.md +141 -0
  124. stravinsky_claude_assets/agents/stravinsky.md +730 -0
  125. stravinsky_claude_assets/commands/delphi.md +9 -0
  126. stravinsky_claude_assets/commands/dewey.md +54 -0
  127. stravinsky_claude_assets/commands/git-master.md +112 -0
  128. stravinsky_claude_assets/commands/index.md +49 -0
  129. stravinsky_claude_assets/commands/publish.md +86 -0
  130. stravinsky_claude_assets/commands/review.md +73 -0
  131. stravinsky_claude_assets/commands/str/agent_cancel.md +70 -0
  132. stravinsky_claude_assets/commands/str/agent_list.md +56 -0
  133. stravinsky_claude_assets/commands/str/agent_output.md +92 -0
  134. stravinsky_claude_assets/commands/str/agent_progress.md +74 -0
  135. stravinsky_claude_assets/commands/str/agent_retry.md +94 -0
  136. stravinsky_claude_assets/commands/str/cancel.md +51 -0
  137. stravinsky_claude_assets/commands/str/clean.md +97 -0
  138. stravinsky_claude_assets/commands/str/continue.md +38 -0
  139. stravinsky_claude_assets/commands/str/index.md +199 -0
  140. stravinsky_claude_assets/commands/str/list_watchers.md +96 -0
  141. stravinsky_claude_assets/commands/str/search.md +205 -0
  142. stravinsky_claude_assets/commands/str/start_filewatch.md +136 -0
  143. stravinsky_claude_assets/commands/str/stats.md +71 -0
  144. stravinsky_claude_assets/commands/str/stop_filewatch.md +89 -0
  145. stravinsky_claude_assets/commands/str/unwatch.md +42 -0
  146. stravinsky_claude_assets/commands/str/watch.md +45 -0
  147. stravinsky_claude_assets/commands/strav.md +53 -0
  148. stravinsky_claude_assets/commands/stravinsky.md +292 -0
  149. stravinsky_claude_assets/commands/verify.md +60 -0
  150. stravinsky_claude_assets/commands/version.md +5 -0
  151. stravinsky_claude_assets/hooks/README.md +248 -0
  152. stravinsky_claude_assets/hooks/comment_checker.py +193 -0
  153. stravinsky_claude_assets/hooks/context.py +38 -0
  154. stravinsky_claude_assets/hooks/context_monitor.py +153 -0
  155. stravinsky_claude_assets/hooks/dependency_tracker.py +73 -0
  156. stravinsky_claude_assets/hooks/edit_recovery.py +46 -0
  157. stravinsky_claude_assets/hooks/execution_state_tracker.py +68 -0
  158. stravinsky_claude_assets/hooks/notification_hook.py +103 -0
  159. stravinsky_claude_assets/hooks/notification_hook_v2.py +96 -0
  160. stravinsky_claude_assets/hooks/parallel_execution.py +241 -0
  161. stravinsky_claude_assets/hooks/parallel_reinforcement.py +106 -0
  162. stravinsky_claude_assets/hooks/parallel_reinforcement_v2.py +112 -0
  163. stravinsky_claude_assets/hooks/pre_compact.py +123 -0
  164. stravinsky_claude_assets/hooks/ralph_loop.py +173 -0
  165. stravinsky_claude_assets/hooks/session_recovery.py +263 -0
  166. stravinsky_claude_assets/hooks/stop_hook.py +89 -0
  167. stravinsky_claude_assets/hooks/stravinsky_metrics.py +164 -0
  168. stravinsky_claude_assets/hooks/stravinsky_mode.py +146 -0
  169. stravinsky_claude_assets/hooks/subagent_stop.py +98 -0
  170. stravinsky_claude_assets/hooks/todo_continuation.py +111 -0
  171. stravinsky_claude_assets/hooks/todo_delegation.py +96 -0
  172. stravinsky_claude_assets/hooks/tool_messaging.py +281 -0
  173. stravinsky_claude_assets/hooks/truncator.py +23 -0
  174. stravinsky_claude_assets/rules/deployment_safety.md +51 -0
  175. stravinsky_claude_assets/rules/integration_wiring.md +89 -0
  176. stravinsky_claude_assets/rules/pypi_deployment.md +220 -0
  177. stravinsky_claude_assets/rules/stravinsky_orchestrator.md +32 -0
  178. stravinsky_claude_assets/settings.json +152 -0
  179. stravinsky_claude_assets/skills/chrome-devtools/SKILL.md +81 -0
  180. stravinsky_claude_assets/skills/sqlite/SKILL.md +77 -0
  181. stravinsky_claude_assets/skills/supabase/SKILL.md +74 -0
  182. stravinsky_claude_assets/task_dependencies.json +34 -0
  183. stravinsky-0.4.18.dist-info/RECORD +0 -88
  184. {stravinsky-0.4.18.dist-info → stravinsky-0.4.66.dist-info}/WHEEL +0 -0
@@ -14,7 +14,6 @@ import logging
14
14
  import platform
15
15
  import subprocess
16
16
  from pathlib import Path
17
- from typing import Dict, Optional
18
17
 
19
18
  logger = logging.getLogger(__name__)
20
19
 
@@ -35,7 +34,7 @@ class NotificationManager:
35
34
  title: str,
36
35
  message: str,
37
36
  sound: bool = True
38
- ) -> Optional[list]:
37
+ ) -> list | None:
39
38
  """Get platform-specific notification command."""
40
39
  if self.system == "Darwin": # macOS
41
40
  script = f'display notification "{message}" with title "{title}"'
@@ -113,7 +112,7 @@ $toast = New-Object Windows.UI.Notifications.ToastNotification $xml
113
112
  message = f"Indexing {path}..."
114
113
  return self._send_notification_sync(title, message, sound=True)
115
114
 
116
- async def notify_reindex_complete(self, stats: Dict) -> bool:
115
+ async def notify_reindex_complete(self, stats: dict) -> bool:
117
116
  """Notify that codebase reindexing is complete."""
118
117
  indexed = stats.get("indexed", 0)
119
118
  pruned = stats.get("pruned", 0)
@@ -134,7 +133,7 @@ $toast = New-Object Windows.UI.Notifications.ToastNotification $xml
134
133
 
135
134
 
136
135
  # Global singleton instance
137
- _notification_manager: Optional[NotificationManager] = None
136
+ _notification_manager: NotificationManager | None = None
138
137
 
139
138
 
140
139
  def get_notification_manager() -> NotificationManager:
@@ -0,0 +1,11 @@
1
+ from enum import Enum
2
+
3
+ class OrchestrationPhase(Enum):
4
+ CLASSIFY = "classify"
5
+ CONTEXT = "context"
6
+ WISDOM = "wisdom"
7
+ PLAN = "plan"
8
+ VALIDATE = "validate"
9
+ DELEGATE = "delegate"
10
+ EXECUTE = "execute"
11
+ VERIFY = "verify"
@@ -0,0 +1,165 @@
1
+ from dataclasses import dataclass
2
+
3
+ from ..routing.config import load_routing_config
4
+ from ..routing.provider_state import get_provider_tracker
5
+ from ..routing.task_classifier import TaskType, classify_and_route
6
+ from ..routing.model_tiers import get_oauth_fallback_chain
7
+ from .enums import OrchestrationPhase
8
+
9
+
10
+ @dataclass
11
+ class ModelConfig:
12
+ planning_model: str = "gemini-3-pro" # Default smart
13
+ execution_model: str = "gemini-3-flash" # Default fast
14
+
15
+
16
+ class Router:
17
+ """
18
+ Intelligent model router with multi-provider fallback and task-based routing.
19
+
20
+ Features:
21
+ - Automatic fallback when providers hit rate limits
22
+ - Task-based routing to optimal models (code gen → OpenAI, docs → Gemini)
23
+ - Provider state tracking with cooldown management
24
+ - Project-local configuration support
25
+ """
26
+
27
+ def __init__(self, config: ModelConfig | None = None, project_path: str = "."):
28
+ self.config = config or ModelConfig()
29
+ self.project_path = project_path
30
+
31
+ # Load routing configuration
32
+ self.routing_config = load_routing_config(project_path)
33
+
34
+ # Get provider state tracker singleton
35
+ self.provider_tracker = get_provider_tracker()
36
+
37
+ def select_model(
38
+ self,
39
+ phase: OrchestrationPhase,
40
+ task_type: TaskType | None = None,
41
+ prompt: str | None = None,
42
+ ) -> str:
43
+ """
44
+ Selects the best model for the given phase and task type.
45
+
46
+ Args:
47
+ phase: Orchestration phase (PLAN, EXECUTE, etc.)
48
+ task_type: Optional task type override (CODE_GENERATION, DEBUGGING, etc.)
49
+ prompt: Optional prompt text for automatic task classification
50
+
51
+ Returns:
52
+ Model identifier string (e.g., "gemini-3-flash", "gpt-5.2-codex")
53
+ """
54
+ # If task_type is provided or can be inferred, use task-based routing
55
+ if task_type or prompt:
56
+ # classify_and_route returns (TaskType, provider, model) tuple
57
+ # Extract just the TaskType
58
+ if task_type:
59
+ inferred_type = task_type
60
+ else:
61
+ # classify_and_route returns tuple: (TaskType, provider, model)
62
+ classification_result = classify_and_route(prompt or "")
63
+ inferred_type = classification_result[0] # Extract TaskType from tuple
64
+
65
+ model = self._select_by_task_type(inferred_type)
66
+
67
+ # Check provider availability and fallback if needed
68
+ return self._check_availability_and_fallback(model, inferred_type)
69
+
70
+ # Fallback to phase-based routing (legacy behavior)
71
+ if phase in [
72
+ OrchestrationPhase.PLAN,
73
+ OrchestrationPhase.VALIDATE,
74
+ OrchestrationPhase.WISDOM,
75
+ OrchestrationPhase.VERIFY,
76
+ ]:
77
+ model = self.config.planning_model
78
+ else:
79
+ model = self.config.execution_model
80
+
81
+ return self._check_availability_and_fallback(model, None)
82
+
83
+ def _select_by_task_type(self, task_type: TaskType) -> str:
84
+ """
85
+ Select model based on task type using routing config.
86
+
87
+ Args:
88
+ task_type: Classified task type
89
+
90
+ Returns:
91
+ Primary model for this task type
92
+ """
93
+ # Look up task routing rule in config (it's a dict[str, TaskRoutingRule])
94
+ task_name = task_type.name.lower()
95
+ if task_name in self.routing_config.task_routing:
96
+ rule = self.routing_config.task_routing[task_name]
97
+ if rule.model:
98
+ return rule.model
99
+
100
+ # Fallback to default execution model if no rule matches
101
+ return self.config.execution_model
102
+
103
+ def _check_availability_and_fallback(self, model: str, task_type: TaskType | None) -> str:
104
+ """
105
+ Check provider availability and apply fallback if rate-limited.
106
+
107
+ Args:
108
+ model: Desired model
109
+ task_type: Task type (for finding appropriate fallback)
110
+
111
+ Returns:
112
+ Available model (original or fallback)
113
+ """
114
+ # Determine provider from model name
115
+ provider = self._get_provider_from_model(model)
116
+
117
+ # Check provider availability using is_available() method
118
+ if self.provider_tracker.is_available(provider):
119
+ return model
120
+
121
+ # Prefer tier-aware OAuth fallback chain when possible.
122
+ # Note: use_oauth=False candidates represent non-OAuth access
123
+ # (currently meaningful for Gemini API key fallback).
124
+ try:
125
+ oauth_chain = get_oauth_fallback_chain(provider, model)
126
+ except ValueError:
127
+ oauth_chain = []
128
+
129
+ for candidate_provider, candidate_model, use_oauth in oauth_chain:
130
+ if not use_oauth and candidate_provider == "gemini":
131
+ return candidate_model
132
+ if self.provider_tracker.is_available(candidate_provider):
133
+ return candidate_model
134
+
135
+ # Provider unavailable - use global fallback chain (legacy)
136
+ # NOTE: Task-specific fallbacks from routing config are not currently
137
+ # implemented (TaskRoutingRule doesn't have fallback_models field)
138
+ for fallback_provider in self.routing_config.fallback.chain:
139
+ if self.provider_tracker.is_available(fallback_provider):
140
+ # Map provider to default model
141
+ return self._get_default_model_for_provider(fallback_provider)
142
+
143
+ # All providers unavailable - return original model and let caller handle error
144
+ return model
145
+
146
+ def _get_provider_from_model(self, model: str) -> str:
147
+ """Extract provider name from model identifier."""
148
+ if "gemini" in model.lower():
149
+ return "gemini"
150
+ elif "gpt" in model.lower() or "openai" in model.lower():
151
+ return "openai"
152
+ elif "claude" in model.lower():
153
+ return "claude"
154
+ else:
155
+ # Default to gemini for unknown models
156
+ return "gemini"
157
+
158
+ def _get_default_model_for_provider(self, provider: str) -> str:
159
+ """Get default model for a provider."""
160
+ defaults = {
161
+ "gemini": "gemini-3-flash",
162
+ "openai": "gpt-5.2-codex",
163
+ "claude": "claude-sonnet-4.5",
164
+ }
165
+ return defaults.get(provider, "gemini-3-flash")
@@ -0,0 +1,32 @@
1
+ from typing import List, Dict, Optional, Callable
2
+ from .enums import OrchestrationPhase
3
+
4
+ class OrchestratorState:
5
+ def __init__(self, enable_phase_gates: bool = False, approver: Optional[Callable[[], bool]] = None):
6
+ self.current_phase = OrchestrationPhase.CLASSIFY
7
+ self.history: List[OrchestrationPhase] = []
8
+ self.artifacts: Dict[str, str] = {}
9
+ self.enable_phase_gates = enable_phase_gates
10
+ self.approver = approver
11
+
12
+ def transition_to(self, next_phase: OrchestrationPhase):
13
+ """Transitions to the next phase if requirements are met."""
14
+ self._validate_transition(next_phase)
15
+
16
+ # Phase Gates
17
+ if self.enable_phase_gates and self.approver:
18
+ if not self.approver():
19
+ raise PermissionError(f"Transition to {next_phase} denied by user.")
20
+
21
+ self.history.append(self.current_phase)
22
+ self.current_phase = next_phase
23
+
24
+ def register_artifact(self, name: str, content: str):
25
+ self.artifacts[name] = content
26
+
27
+ def _validate_transition(self, next_phase: OrchestrationPhase):
28
+ """Enforce strict phase requirements."""
29
+ # Example: Must have plan before validation
30
+ if next_phase == OrchestrationPhase.VALIDATE:
31
+ if "plan.md" not in self.artifacts and self.current_phase == OrchestrationPhase.PLAN:
32
+ raise ValueError("Missing artifact: plan.md is required to enter Validation phase")
@@ -0,0 +1,14 @@
1
+ from .enums import OrchestrationPhase
2
+
3
+ def format_phase_progress(current_phase: OrchestrationPhase) -> str:
4
+ """Formats the current phase as a progress string."""
5
+ phases = list(OrchestrationPhase)
6
+ total = len(phases)
7
+
8
+ # Find index (1-based)
9
+ try:
10
+ index = phases.index(current_phase) + 1
11
+ except ValueError:
12
+ index = 0
13
+
14
+ return f"[Phase {index}/{total}: {current_phase.name}]"
@@ -0,0 +1,34 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ class WisdomLoader:
5
+ def __init__(self, wisdom_path: str = ".stravinsky/wisdom.md"):
6
+ self.wisdom_path = wisdom_path
7
+
8
+ def load_wisdom(self) -> str:
9
+ """Loads project wisdom/learnings."""
10
+ if os.path.exists(self.wisdom_path):
11
+ try:
12
+ with open(self.wisdom_path, "r") as f:
13
+ return f.read()
14
+ except Exception:
15
+ return ""
16
+ return ""
17
+
18
+ class CritiqueGenerator:
19
+ def generate_critique_prompt(self, plan_content: str) -> str:
20
+ """Generates a prompt for self-critique."""
21
+ return f"""
22
+ You are currently in the CRITIQUE phase.
23
+ Review the following plan and identify potential weaknesses.
24
+
25
+ PLAN:
26
+ {plan_content}
27
+
28
+ INSTRUCTIONS:
29
+ 1. List 3 ways this plan could fail (edge cases, race conditions, missing context).
30
+ 2. Check if it violates any items in the 'Wisdom' file (if provided).
31
+ 3. Propose specific improvements.
32
+
33
+ Respond with your critique.
34
+ """
@@ -1,12 +1,5 @@
1
1
  # Agent prompts module
2
- from . import stravinsky
3
- from . import delphi
4
- from . import dewey
5
- from . import explore
6
- from . import frontend
7
- from . import document_writer
8
- from . import multimodal
9
- from . import planner
2
+ from . import delphi, dewey, document_writer, explore, frontend, multimodal, planner, stravinsky
10
3
 
11
4
  __all__ = [
12
5
  "stravinsky",
@@ -44,7 +44,7 @@ Your job: Answer questions about open-source libraries by finding **EVIDENCE** w
44
44
 
45
45
  ---
46
46
 
47
- ## PHASE 0: REQUEST CLASSIFICATION (MANDATORY FIRST STEP)
47
+ ## PHASE 0: REQUEST CLASSIFICATION (MANDATORY FUWT STEP)
48
48
 
49
49
  Classify EVERY request into one of these categories before taking action:
50
50
 
@@ -13,8 +13,6 @@ Key capabilities:
13
13
  - Structured plan output for orchestrator consumption
14
14
  """
15
15
 
16
- from typing import Optional
17
-
18
16
 
19
17
  PLANNER_ROLE = """<Role>
20
18
  You are "Planner" - a pre-implementation planning specialist.
@@ -177,8 +175,8 @@ Before finalizing plan, verify:
177
175
 
178
176
  def get_planner_prompt(
179
177
  task_description: str,
180
- project_context: Optional[str] = None,
181
- existing_patterns: Optional[str] = None,
178
+ project_context: str | None = None,
179
+ existing_patterns: str | None = None,
182
180
  ) -> str:
183
181
  """
184
182
  Generate the complete planner prompt.
@@ -12,8 +12,6 @@ Key naming conventions (Stravinsky equivalents):
12
12
  - agent_spawn (not call-omo-agent) - spawn background agents
13
13
  """
14
14
 
15
- from typing import Optional
16
-
17
15
  # Core role definition
18
16
  STRAVINSKY_ROLE_SECTION = """<Role>
19
17
  You are "Stravinsky" - Powerful AI Agent with orchestration capabilities from Stravinsky MCP.
@@ -36,7 +34,7 @@ Named after the composer known for revolutionary orchestration.
36
34
  </Role>"""
37
35
 
38
36
 
39
- STRAVINSKY_PHASE0_STEP1_3 = """### Step 0: Check Skills FIRST (BLOCKING)
37
+ STRAVINSKY_PHASE0_STEP1_3 = """### Step 0: Check Skills FUWT (BLOCKING)
40
38
 
41
39
  **Before ANY classification or action, scan for matching skills.**
42
40
 
@@ -54,7 +52,7 @@ Skills are specialized workflows. When relevant, they handle the task better tha
54
52
 
55
53
  | Type | Signal | Action |
56
54
  |------|--------|--------|
57
- | **Skill Match** | Matches skill trigger phrase | **INVOKE skill FIRST** via `skill_get` tool |
55
+ | **Skill Match** | Matches skill trigger phrase | **INVOKE skill FUWT** via `skill_get` tool |
58
56
  | **Trivial** | Single file, known location, direct answer | Direct tools only (UNLESS Key Trigger applies) |
59
57
  | **Explicit** | Specific file/line, clear command | Execute directly |
60
58
  | **Exploratory** | "How does X work?", "Find Y" | Fire explore (1-3) + tools in parallel |
@@ -159,7 +157,7 @@ STOP searching when:
159
157
  **DO NOT over-explore. Time is precious.**"""
160
158
 
161
159
 
162
- STRAVINSKY_PHASE2B_PRE_IMPLEMENTATION = """## ⚠️ CRITICAL: PARALLEL-FIRST WORKFLOW
160
+ STRAVINSKY_PHASE2B_PRE_IMPLEMENTATION = """## ⚠️ CRITICAL: PARALLEL-FUWT WORKFLOW
163
161
 
164
162
  **BLOCKING REQUIREMENT**: For implementation tasks, your response structure MUST be:
165
163
 
@@ -204,54 +202,78 @@ todowrite([todo1, todo2, todo3])
204
202
  4. THEN mark todos complete"""
205
203
 
206
204
 
207
- STRAVINSKY_DELEGATION_PROMPT_STRUCTURE = """### Delegation Prompt Structure (MANDATORY - ALL 7 sections):
205
+ STRAVINSKY_DELEGATION_PROMPT_STRUCTURE = """### Delegation Prompt Structure (RECOMMENDED - 5 KEY SECTIONS):
208
206
 
209
- When delegating via `agent_spawn`, your prompt MUST include ALL 7 sections:
207
+ When delegating via `agent_spawn`, your prompt SHOULD include these sections:
210
208
 
211
209
  ```
212
- 1. TASK: Atomic, specific goal (one sentence)
210
+ 1. TASK: Clear, natural language description of what needs to be found/analyzed
213
211
  2. EXPECTED OUTCOME: Concrete deliverables with success criteria
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
212
+ 3. MUST DO: Exhaustive requirements list
213
+ 4. MUST NOT DO: Forbidden actions (prevent rogue behavior)
214
+ 5. CONTEXT: File paths, existing patterns, constraints (if known)
219
215
  ```
220
216
 
221
- **Example Delegation Prompt:**
217
+ **❌ WRONG - Over-Prescribing Tools:**
222
218
  ```
223
219
  ## TASK
224
220
  Find all API endpoint definitions in the auth module.
225
221
 
226
- ## EXPECTED OUTCOME
227
- List of endpoints with: path, method, handler function, file location.
228
-
229
222
  ## REQUIRED TOOLS
230
- Read, Grep, Glob
223
+ Read, Grep, Glob # ❌ DON'T PRESCRIBE TOOLS - agents choose optimal approach
224
+
225
+ ## MUST DO
226
+ - Use grep_search to find "def" patterns # ❌ TOO SPECIFIC
227
+ ```
228
+
229
+ **✅ CORRECT - Natural Language + Trust Agent Intelligence:**
230
+ ```
231
+ ## TASK
232
+ Find and explain all API endpoint definitions in the auth module, including their request/response patterns and how they connect to each other.
233
+
234
+ ## EXPECTED OUTCOME
235
+ Complete list of endpoints with: path, method, handler function, file location, and architectural notes on how they integrate.
231
236
 
232
237
  ## MUST DO
233
- - Search in src/auth/ directory
234
- - Include path parameters
235
- - Report line numbers
238
+ - Search in src/auth/ directory and related integration points
239
+ - Include path parameters and query string handling
240
+ - Report exact line numbers for each endpoint
241
+ - Explain the authentication flow across endpoints
236
242
 
237
243
  ## MUST NOT DO
238
244
  - Modify any files
239
- - Search outside src/auth/
245
+ - Skip integration patterns (how endpoints call each other)
240
246
 
241
247
  ## CONTEXT
242
248
  Project uses FastAPI. Auth endpoints handle login, logout, token refresh.
249
+ This is a CONCEPTUAL/ARCHITECTURAL query - the agent should use semantic_search + grep for comprehensive coverage.
243
250
 
244
251
  ## SUCCESS CRITERIA
245
- All endpoints documented with complete paths and handlers.
252
+ All endpoints documented with complete paths, handlers, AND architectural understanding of how they work together.
246
253
  ```
247
254
 
255
+ **WHY THIS WORKS BETTER:**
256
+ - ✅ Explore agent has `semantic_search` in its toolset and knows when to use it
257
+ - ✅ Natural language tasks → agent classifies as SEMANTIC → uses semantic_search
258
+ - ✅ Agent combines semantic_search (concepts) + grep_search (exact matches) automatically
259
+ - ❌ "REQUIRED TOOLS: grep_search" → blocks semantic_search even for conceptual queries
260
+
261
+ **TRUST THE AGENTS:**
262
+ The explore agent already has comprehensive tool selection logic:
263
+ - Semantic queries → semantic_search (primary)
264
+ - Exact syntax → grep_search
265
+ - Code structure → ast_grep_search
266
+ - Symbol navigation → LSP tools
267
+
268
+ Let them choose the optimal search strategy based on your TASK description, not prescriptive tool lists.
269
+
248
270
  AFTER THE WORK YOU DELEGATED SEEMS DONE, ALWAYS VERIFY THE RESULTS:
249
271
  - DOES IT WORK AS EXPECTED?
250
272
  - DOES IT FOLLOW THE EXISTING CODEBASE PATTERN?
251
273
  - EXPECTED RESULT CAME OUT?
252
274
  - DID THE AGENT FOLLOW "MUST DO" AND "MUST NOT DO" REQUIREMENTS?
253
275
 
254
- **Vague prompts = rejected. Be exhaustive.**"""
276
+ **Natural language task descriptions = agent intelligence. Tool prescriptions = micromanagement.**"""
255
277
 
256
278
 
257
279
  STRAVINSKY_GITHUB_WORKFLOW = """### GitHub Workflow (CRITICAL - When mentioned in issues/PRs):
@@ -358,7 +380,7 @@ If verification fails:
358
380
 
359
381
  STRAVINSKY_KEY_TRIGGERS = """### Key Triggers (check BEFORE classification):
360
382
 
361
- **BLOCKING: Check skills FIRST before any action.**
383
+ **BLOCKING: Check skills FUWT before any action.**
362
384
  If a skill matches, invoke it IMMEDIATELY via `skill_get` tool.
363
385
 
364
386
  - External library/source mentioned -> fire `dewey` background via `agent_spawn`
@@ -472,12 +494,12 @@ Delphi is an expensive, high-quality reasoning model. Use it wisely via `agent_s
472
494
 
473
495
  | Trigger | Action |
474
496
  |---------|--------|
475
- | Complex architecture design | Delphi FIRST, then implement |
476
- | After completing significant work | Delphi FIRST, then implement |
477
- | 2+ failed fix attempts | Delphi FIRST, then implement |
478
- | Unfamiliar code patterns | Delphi FIRST, then implement |
479
- | Security/performance concerns | Delphi FIRST, then implement |
480
- | Multi-system tradeoffs | Delphi FIRST, then implement |
497
+ | Complex architecture design | Delphi FUWT, then implement |
498
+ | After completing significant work | Delphi FUWT, then implement |
499
+ | 2+ failed fix attempts | Delphi FUWT, then implement |
500
+ | Unfamiliar code patterns | Delphi FUWT, then implement |
501
+ | Security/performance concerns | Delphi FUWT, then implement |
502
+ | Multi-system tradeoffs | Delphi FUWT, then implement |
481
503
 
482
504
  ### WHEN NOT to Consult:
483
505
 
File without changes
@@ -0,0 +1,70 @@
1
+ import os
2
+ import httpx
3
+ import logging
4
+ from typing import Any, Optional
5
+
6
+ logger = logging.getLogger("stravinsky.proxy_client")
7
+
8
+ PROXY_URL = os.getenv("STRAVINSKY_PROXY_URL", "http://127.0.0.1:8765")
9
+
10
+ async def proxy_invoke_gemini(
11
+ prompt: str,
12
+ model: str = "gemini-3-flash",
13
+ temperature: float = 0.7,
14
+ max_tokens: int = 8192,
15
+ thinking_budget: int = 0,
16
+ image_path: Optional[str] = None,
17
+ agent_context: Optional[dict[str, Any]] = None
18
+ ) -> str:
19
+ """Routes Gemini invocation to the proxy server."""
20
+ payload = {
21
+ "prompt": prompt,
22
+ "model": model,
23
+ "temperature": temperature,
24
+ "max_tokens": max_tokens,
25
+ "thinking_budget": thinking_budget,
26
+ "image_path": image_path,
27
+ "agent_context": agent_context
28
+ }
29
+
30
+ async with httpx.AsyncClient(timeout=130.0) as client:
31
+ try:
32
+ response = await client.post(f"{PROXY_URL}/v1/gemini/generate", json=payload)
33
+ response.raise_for_status()
34
+ return response.json()["response"]
35
+ except Exception as e:
36
+ logger.error(f"Proxy request failed: {e}")
37
+ raise
38
+
39
+ async def proxy_invoke_openai(
40
+ prompt: str,
41
+ model: str = "gpt-5.2-codex",
42
+ temperature: float = 0.7,
43
+ max_tokens: int = 4096,
44
+ thinking_budget: int = 0,
45
+ reasoning_effort: str = "medium",
46
+ agent_context: Optional[dict[str, Any]] = None
47
+ ) -> str:
48
+ """Routes OpenAI invocation to the proxy server."""
49
+ payload = {
50
+ "prompt": prompt,
51
+ "model": model,
52
+ "temperature": temperature,
53
+ "max_tokens": max_tokens,
54
+ "thinking_budget": thinking_budget,
55
+ "reasoning_effort": reasoning_effort,
56
+ "agent_context": agent_context
57
+ }
58
+
59
+ async with httpx.AsyncClient(timeout=130.0) as client:
60
+ try:
61
+ response = await client.post(f"{PROXY_URL}/v1/openai/chat", json=payload)
62
+ response.raise_for_status()
63
+ return response.json()["response"]
64
+ except Exception as e:
65
+ logger.error(f"Proxy request failed: {e}")
66
+ raise
67
+
68
+ def is_proxy_enabled() -> bool:
69
+ """Checks if proxy usage is enabled via environment variable."""
70
+ return os.getenv("STRAVINSKY_USE_PROXY", "false").lower() == "true"