emdash-core 0.1.7__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.
Files changed (187) hide show
  1. emdash_core/__init__.py +3 -0
  2. emdash_core/agent/__init__.py +37 -0
  3. emdash_core/agent/agents.py +225 -0
  4. emdash_core/agent/code_reviewer.py +476 -0
  5. emdash_core/agent/compaction.py +143 -0
  6. emdash_core/agent/context_manager.py +140 -0
  7. emdash_core/agent/events.py +338 -0
  8. emdash_core/agent/handlers.py +224 -0
  9. emdash_core/agent/inprocess_subagent.py +377 -0
  10. emdash_core/agent/mcp/__init__.py +50 -0
  11. emdash_core/agent/mcp/client.py +346 -0
  12. emdash_core/agent/mcp/config.py +302 -0
  13. emdash_core/agent/mcp/manager.py +496 -0
  14. emdash_core/agent/mcp/tool_factory.py +213 -0
  15. emdash_core/agent/prompts/__init__.py +38 -0
  16. emdash_core/agent/prompts/main_agent.py +104 -0
  17. emdash_core/agent/prompts/subagents.py +131 -0
  18. emdash_core/agent/prompts/workflow.py +136 -0
  19. emdash_core/agent/providers/__init__.py +34 -0
  20. emdash_core/agent/providers/base.py +143 -0
  21. emdash_core/agent/providers/factory.py +80 -0
  22. emdash_core/agent/providers/models.py +220 -0
  23. emdash_core/agent/providers/openai_provider.py +463 -0
  24. emdash_core/agent/providers/transformers_provider.py +217 -0
  25. emdash_core/agent/research/__init__.py +81 -0
  26. emdash_core/agent/research/agent.py +143 -0
  27. emdash_core/agent/research/controller.py +254 -0
  28. emdash_core/agent/research/critic.py +428 -0
  29. emdash_core/agent/research/macros.py +469 -0
  30. emdash_core/agent/research/planner.py +449 -0
  31. emdash_core/agent/research/researcher.py +436 -0
  32. emdash_core/agent/research/state.py +523 -0
  33. emdash_core/agent/research/synthesizer.py +594 -0
  34. emdash_core/agent/reviewer_profile.py +475 -0
  35. emdash_core/agent/rules.py +123 -0
  36. emdash_core/agent/runner.py +601 -0
  37. emdash_core/agent/session.py +262 -0
  38. emdash_core/agent/spec_schema.py +66 -0
  39. emdash_core/agent/specification.py +479 -0
  40. emdash_core/agent/subagent.py +397 -0
  41. emdash_core/agent/subagent_prompts.py +13 -0
  42. emdash_core/agent/toolkit.py +482 -0
  43. emdash_core/agent/toolkits/__init__.py +64 -0
  44. emdash_core/agent/toolkits/base.py +96 -0
  45. emdash_core/agent/toolkits/explore.py +47 -0
  46. emdash_core/agent/toolkits/plan.py +55 -0
  47. emdash_core/agent/tools/__init__.py +141 -0
  48. emdash_core/agent/tools/analytics.py +436 -0
  49. emdash_core/agent/tools/base.py +131 -0
  50. emdash_core/agent/tools/coding.py +484 -0
  51. emdash_core/agent/tools/github_mcp.py +592 -0
  52. emdash_core/agent/tools/history.py +13 -0
  53. emdash_core/agent/tools/modes.py +153 -0
  54. emdash_core/agent/tools/plan.py +206 -0
  55. emdash_core/agent/tools/plan_write.py +135 -0
  56. emdash_core/agent/tools/search.py +412 -0
  57. emdash_core/agent/tools/spec.py +341 -0
  58. emdash_core/agent/tools/task.py +262 -0
  59. emdash_core/agent/tools/task_output.py +204 -0
  60. emdash_core/agent/tools/tasks.py +454 -0
  61. emdash_core/agent/tools/traversal.py +588 -0
  62. emdash_core/agent/tools/web.py +179 -0
  63. emdash_core/analytics/__init__.py +5 -0
  64. emdash_core/analytics/engine.py +1286 -0
  65. emdash_core/api/__init__.py +5 -0
  66. emdash_core/api/agent.py +308 -0
  67. emdash_core/api/agents.py +154 -0
  68. emdash_core/api/analyze.py +264 -0
  69. emdash_core/api/auth.py +173 -0
  70. emdash_core/api/context.py +77 -0
  71. emdash_core/api/db.py +121 -0
  72. emdash_core/api/embed.py +131 -0
  73. emdash_core/api/feature.py +143 -0
  74. emdash_core/api/health.py +93 -0
  75. emdash_core/api/index.py +162 -0
  76. emdash_core/api/plan.py +110 -0
  77. emdash_core/api/projectmd.py +210 -0
  78. emdash_core/api/query.py +320 -0
  79. emdash_core/api/research.py +122 -0
  80. emdash_core/api/review.py +161 -0
  81. emdash_core/api/router.py +76 -0
  82. emdash_core/api/rules.py +116 -0
  83. emdash_core/api/search.py +119 -0
  84. emdash_core/api/spec.py +99 -0
  85. emdash_core/api/swarm.py +223 -0
  86. emdash_core/api/tasks.py +109 -0
  87. emdash_core/api/team.py +120 -0
  88. emdash_core/auth/__init__.py +17 -0
  89. emdash_core/auth/github.py +389 -0
  90. emdash_core/config.py +74 -0
  91. emdash_core/context/__init__.py +52 -0
  92. emdash_core/context/models.py +50 -0
  93. emdash_core/context/providers/__init__.py +11 -0
  94. emdash_core/context/providers/base.py +74 -0
  95. emdash_core/context/providers/explored_areas.py +183 -0
  96. emdash_core/context/providers/touched_areas.py +360 -0
  97. emdash_core/context/registry.py +73 -0
  98. emdash_core/context/reranker.py +199 -0
  99. emdash_core/context/service.py +260 -0
  100. emdash_core/context/session.py +352 -0
  101. emdash_core/core/__init__.py +104 -0
  102. emdash_core/core/config.py +454 -0
  103. emdash_core/core/exceptions.py +55 -0
  104. emdash_core/core/models.py +265 -0
  105. emdash_core/core/review_config.py +57 -0
  106. emdash_core/db/__init__.py +67 -0
  107. emdash_core/db/auth.py +134 -0
  108. emdash_core/db/models.py +91 -0
  109. emdash_core/db/provider.py +222 -0
  110. emdash_core/db/providers/__init__.py +5 -0
  111. emdash_core/db/providers/supabase.py +452 -0
  112. emdash_core/embeddings/__init__.py +24 -0
  113. emdash_core/embeddings/indexer.py +534 -0
  114. emdash_core/embeddings/models.py +192 -0
  115. emdash_core/embeddings/providers/__init__.py +7 -0
  116. emdash_core/embeddings/providers/base.py +112 -0
  117. emdash_core/embeddings/providers/fireworks.py +141 -0
  118. emdash_core/embeddings/providers/openai.py +104 -0
  119. emdash_core/embeddings/registry.py +146 -0
  120. emdash_core/embeddings/service.py +215 -0
  121. emdash_core/graph/__init__.py +26 -0
  122. emdash_core/graph/builder.py +134 -0
  123. emdash_core/graph/connection.py +692 -0
  124. emdash_core/graph/schema.py +416 -0
  125. emdash_core/graph/writer.py +667 -0
  126. emdash_core/ingestion/__init__.py +7 -0
  127. emdash_core/ingestion/change_detector.py +150 -0
  128. emdash_core/ingestion/git/__init__.py +5 -0
  129. emdash_core/ingestion/git/commit_analyzer.py +196 -0
  130. emdash_core/ingestion/github/__init__.py +6 -0
  131. emdash_core/ingestion/github/pr_fetcher.py +296 -0
  132. emdash_core/ingestion/github/task_extractor.py +100 -0
  133. emdash_core/ingestion/orchestrator.py +540 -0
  134. emdash_core/ingestion/parsers/__init__.py +10 -0
  135. emdash_core/ingestion/parsers/base_parser.py +66 -0
  136. emdash_core/ingestion/parsers/call_graph_builder.py +121 -0
  137. emdash_core/ingestion/parsers/class_extractor.py +154 -0
  138. emdash_core/ingestion/parsers/function_extractor.py +202 -0
  139. emdash_core/ingestion/parsers/import_analyzer.py +119 -0
  140. emdash_core/ingestion/parsers/python_parser.py +123 -0
  141. emdash_core/ingestion/parsers/registry.py +72 -0
  142. emdash_core/ingestion/parsers/ts_ast_parser.js +313 -0
  143. emdash_core/ingestion/parsers/typescript_parser.py +278 -0
  144. emdash_core/ingestion/repository.py +346 -0
  145. emdash_core/models/__init__.py +38 -0
  146. emdash_core/models/agent.py +68 -0
  147. emdash_core/models/index.py +77 -0
  148. emdash_core/models/query.py +113 -0
  149. emdash_core/planning/__init__.py +7 -0
  150. emdash_core/planning/agent_api.py +413 -0
  151. emdash_core/planning/context_builder.py +265 -0
  152. emdash_core/planning/feature_context.py +232 -0
  153. emdash_core/planning/feature_expander.py +646 -0
  154. emdash_core/planning/llm_explainer.py +198 -0
  155. emdash_core/planning/similarity.py +509 -0
  156. emdash_core/planning/team_focus.py +821 -0
  157. emdash_core/server.py +153 -0
  158. emdash_core/sse/__init__.py +5 -0
  159. emdash_core/sse/stream.py +196 -0
  160. emdash_core/swarm/__init__.py +17 -0
  161. emdash_core/swarm/merge_agent.py +383 -0
  162. emdash_core/swarm/session_manager.py +274 -0
  163. emdash_core/swarm/swarm_runner.py +226 -0
  164. emdash_core/swarm/task_definition.py +137 -0
  165. emdash_core/swarm/worker_spawner.py +319 -0
  166. emdash_core/swarm/worktree_manager.py +278 -0
  167. emdash_core/templates/__init__.py +10 -0
  168. emdash_core/templates/defaults/agent-builder.md.template +82 -0
  169. emdash_core/templates/defaults/focus.md.template +115 -0
  170. emdash_core/templates/defaults/pr-review-enhanced.md.template +309 -0
  171. emdash_core/templates/defaults/pr-review.md.template +80 -0
  172. emdash_core/templates/defaults/project.md.template +85 -0
  173. emdash_core/templates/defaults/research_critic.md.template +112 -0
  174. emdash_core/templates/defaults/research_planner.md.template +85 -0
  175. emdash_core/templates/defaults/research_synthesizer.md.template +128 -0
  176. emdash_core/templates/defaults/reviewer.md.template +81 -0
  177. emdash_core/templates/defaults/spec.md.template +41 -0
  178. emdash_core/templates/defaults/tasks.md.template +78 -0
  179. emdash_core/templates/loader.py +296 -0
  180. emdash_core/utils/__init__.py +45 -0
  181. emdash_core/utils/git.py +84 -0
  182. emdash_core/utils/image.py +502 -0
  183. emdash_core/utils/logger.py +51 -0
  184. emdash_core-0.1.7.dist-info/METADATA +35 -0
  185. emdash_core-0.1.7.dist-info/RECORD +187 -0
  186. emdash_core-0.1.7.dist-info/WHEEL +4 -0
  187. emdash_core-0.1.7.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,397 @@
1
+ """SubAgentRunner - subprocess agent runner for focused tasks.
2
+
3
+ This module provides the SubAgentRunner class for executing sub-agents in
4
+ separate processes, plus a CLI entry point for subprocess execution.
5
+
6
+ Usage:
7
+ # From parent process via Task tool
8
+ result = subprocess.run([
9
+ sys.executable, "-m", "emdash_core.agent.subagent",
10
+ "--type", "Explore",
11
+ "--prompt", "Find authentication handlers",
12
+ "--repo-root", "/path/to/repo",
13
+ ])
14
+
15
+ # Result is JSON on stdout
16
+ """
17
+
18
+ import argparse
19
+ import json
20
+ import os
21
+ import sys
22
+ import time
23
+ import uuid
24
+ from dataclasses import dataclass, asdict
25
+ from pathlib import Path
26
+ from typing import Optional
27
+
28
+ from .toolkits import get_toolkit
29
+ from .prompts import get_subagent_prompt
30
+ from .providers import get_provider
31
+ from .providers.models import ChatModel
32
+ from ..utils.logger import log
33
+
34
+
35
+ # Environment variables for model configuration
36
+ MODEL_ENV_VARS = {
37
+ "fast": "FAST_MODEL",
38
+ "model": "EMDASH_MODEL",
39
+ }
40
+
41
+ # Default models for each tier
42
+ DEFAULT_MODELS = {
43
+ "fast": "accounts/fireworks/models/gpt-oss-120b",
44
+ "model": "accounts/fireworks/models/minimax-m2p1",
45
+ }
46
+
47
+
48
+ def get_model_for_tier(tier: str = "fast") -> str:
49
+ """Get model name from environment variable.
50
+
51
+ Args:
52
+ tier: Model tier (fast, standard, powerful)
53
+
54
+ Returns:
55
+ Model name/path
56
+ """
57
+ env_var = MODEL_ENV_VARS.get(tier, "FAST_MODEL")
58
+ default = DEFAULT_MODELS.get(tier, DEFAULT_MODELS["fast"])
59
+ return os.environ.get(env_var, default)
60
+
61
+
62
+ @dataclass
63
+ class SubAgentResult:
64
+ """Result from a sub-agent execution."""
65
+
66
+ success: bool
67
+ agent_type: str
68
+ agent_id: str
69
+ task: str
70
+
71
+ # Findings
72
+ summary: str
73
+ files_explored: list[str]
74
+ findings: list[dict]
75
+
76
+ # Metadata
77
+ iterations: int
78
+ tools_used: list[str]
79
+ execution_time: float
80
+ error: Optional[str] = None
81
+
82
+ def to_dict(self) -> dict:
83
+ """Convert to dictionary."""
84
+ return asdict(self)
85
+
86
+ def to_json(self) -> str:
87
+ """Convert to JSON string."""
88
+ return json.dumps(self.to_dict(), indent=2)
89
+
90
+
91
+ class SubAgentRunner:
92
+ """Subprocess agent runner for focused tasks.
93
+
94
+ Runs a lightweight agent loop with a type-specific toolkit.
95
+ Designed to be spawned as a subprocess from the parent agent.
96
+ """
97
+
98
+ def __init__(
99
+ self,
100
+ subagent_type: str,
101
+ repo_root: Path,
102
+ model_tier: str = "fast",
103
+ max_turns: int = 10,
104
+ agent_id: Optional[str] = None,
105
+ ):
106
+ """Initialize the sub-agent runner.
107
+
108
+ Args:
109
+ subagent_type: Type of agent (Explore, Plan, etc.)
110
+ repo_root: Root directory of the repository
111
+ model_tier: Model tier (fast, standard, powerful)
112
+ max_turns: Maximum API round-trips before stopping
113
+ agent_id: Optional agent ID for resume support
114
+ """
115
+ self.subagent_type = subagent_type
116
+ self.repo_root = repo_root.resolve()
117
+ self.max_turns = max_turns
118
+ self.agent_id = agent_id or str(uuid.uuid4())[:8]
119
+
120
+ # Get toolkit for this agent type
121
+ self.toolkit = get_toolkit(subagent_type, repo_root)
122
+
123
+ # Get model and create provider
124
+ model_name = get_model_for_tier(model_tier)
125
+ self.provider = get_provider(model_name)
126
+
127
+ # Get system prompt
128
+ self.system_prompt = get_subagent_prompt(subagent_type)
129
+
130
+ # Transcript for resume support
131
+ self.transcript_dir = repo_root / ".emdash" / "agents"
132
+ self.transcript_path = self.transcript_dir / f"{self.agent_id}.jsonl"
133
+
134
+ # Tracking
135
+ self.files_explored: set[str] = set()
136
+ self.tools_used: list[str] = []
137
+
138
+ def _emit_progress(self, event_type: str, data: dict) -> None:
139
+ """Emit progress event to stderr for parent process to capture.
140
+
141
+ Events are JSON lines with format: {"event": "type", "data": {...}}
142
+ """
143
+ import sys
144
+ event = {"event": event_type, "data": data}
145
+ print(json.dumps(event), file=sys.stderr, flush=True)
146
+
147
+ def run(self, prompt: str) -> SubAgentResult:
148
+ """Execute the task and return results.
149
+
150
+ Args:
151
+ prompt: The task to perform
152
+
153
+ Returns:
154
+ SubAgentResult with findings
155
+ """
156
+ start_time = time.time()
157
+
158
+ # Load existing transcript if resuming
159
+ messages = self._load_transcript()
160
+
161
+ # Add user message with prompt
162
+ if not messages or messages[-1].get("role") != "user":
163
+ messages.append({"role": "user", "content": prompt})
164
+
165
+ iterations = 0
166
+ last_content = ""
167
+ error = None
168
+
169
+ try:
170
+ # Emit start event
171
+ self._emit_progress("agent_start", {
172
+ "agent_type": self.subagent_type,
173
+ "agent_id": self.agent_id,
174
+ "max_turns": self.max_turns,
175
+ })
176
+
177
+ # Agent loop
178
+ while iterations < self.max_turns:
179
+ iterations += 1
180
+
181
+ self._emit_progress("turn_start", {
182
+ "turn": iterations,
183
+ "max_turns": self.max_turns,
184
+ })
185
+
186
+ # Call LLM
187
+ response = self.provider.chat(
188
+ messages=messages,
189
+ tools=self.toolkit.get_all_schemas(),
190
+ system=self.system_prompt,
191
+ )
192
+
193
+ # Add assistant response to messages
194
+ assistant_msg = self.provider.format_assistant_message(response)
195
+ if assistant_msg:
196
+ messages.append(assistant_msg)
197
+
198
+ # Save content
199
+ if response.content:
200
+ last_content = response.content
201
+
202
+ # Check if done (no tool calls)
203
+ if not response.tool_calls:
204
+ break
205
+
206
+ # Execute tool calls
207
+ for tool_call in response.tool_calls:
208
+ self.tools_used.append(tool_call.name)
209
+
210
+ # Parse arguments
211
+ try:
212
+ args = json.loads(tool_call.arguments) if tool_call.arguments else {}
213
+ except (json.JSONDecodeError, TypeError):
214
+ args = {}
215
+
216
+ # Emit tool start
217
+ self._emit_progress("tool_start", {
218
+ "name": tool_call.name,
219
+ "args": {k: str(v)[:100] for k, v in args.items()}, # Truncate args
220
+ })
221
+
222
+ # Track file operations
223
+ if "path" in args:
224
+ self.files_explored.add(args["path"])
225
+
226
+ # Execute tool
227
+ result = self.toolkit.execute(tool_call.name, **args)
228
+
229
+ # Emit tool result
230
+ self._emit_progress("tool_result", {
231
+ "name": tool_call.name,
232
+ "success": result.success,
233
+ "summary": str(result.data)[:200] if result.data else None,
234
+ })
235
+
236
+ # Add tool result to messages
237
+ tool_result_msg = self.provider.format_tool_result(
238
+ tool_call.id,
239
+ json.dumps(result.to_dict(), indent=2),
240
+ )
241
+ if tool_result_msg:
242
+ messages.append(tool_result_msg)
243
+
244
+ # Save transcript after each iteration
245
+ self._save_transcript(messages)
246
+
247
+ except Exception as e:
248
+ log.exception("Sub-agent execution failed")
249
+ error = str(e)
250
+ self._emit_progress("agent_error", {"error": str(e)})
251
+
252
+ execution_time = time.time() - start_time
253
+
254
+ # Emit completion event
255
+ self._emit_progress("agent_end", {
256
+ "success": error is None,
257
+ "iterations": iterations,
258
+ "files_explored": len(self.files_explored),
259
+ "tools_used": len(set(self.tools_used)),
260
+ "execution_time": execution_time,
261
+ })
262
+
263
+ # Build result
264
+ return SubAgentResult(
265
+ success=error is None,
266
+ agent_type=self.subagent_type,
267
+ agent_id=self.agent_id,
268
+ task=prompt,
269
+ summary=last_content or "No response generated",
270
+ files_explored=list(self.files_explored),
271
+ findings=self._extract_findings(messages),
272
+ iterations=iterations,
273
+ tools_used=list(set(self.tools_used)),
274
+ execution_time=execution_time,
275
+ error=error,
276
+ )
277
+
278
+ def _load_transcript(self) -> list[dict]:
279
+ """Load transcript from file for resume support."""
280
+ if not self.transcript_path.exists():
281
+ return []
282
+
283
+ messages = []
284
+ try:
285
+ with open(self.transcript_path) as f:
286
+ for line in f:
287
+ if line.strip():
288
+ messages.append(json.loads(line))
289
+ log.info(f"Resumed agent {self.agent_id} with {len(messages)} messages")
290
+ except Exception as e:
291
+ log.warning(f"Failed to load transcript: {e}")
292
+ return []
293
+
294
+ return messages
295
+
296
+ def _save_transcript(self, messages: list[dict]) -> None:
297
+ """Save transcript to file for resume support."""
298
+ try:
299
+ self.transcript_dir.mkdir(parents=True, exist_ok=True)
300
+ with open(self.transcript_path, "w") as f:
301
+ for msg in messages:
302
+ f.write(json.dumps(msg) + "\n")
303
+ except Exception as e:
304
+ log.warning(f"Failed to save transcript: {e}")
305
+
306
+ def _extract_findings(self, messages: list[dict]) -> list[dict]:
307
+ """Extract key findings from tool results.
308
+
309
+ Args:
310
+ messages: Conversation messages
311
+
312
+ Returns:
313
+ List of finding dicts
314
+ """
315
+ findings = []
316
+ for msg in messages:
317
+ if msg and msg.get("role") == "tool":
318
+ try:
319
+ content = json.loads(msg.get("content", "{}"))
320
+ if content and content.get("success") and content.get("data"):
321
+ findings.append(content["data"])
322
+ except (json.JSONDecodeError, TypeError):
323
+ pass
324
+ return findings[-10:] # Limit to last 10 findings
325
+
326
+
327
+ def main():
328
+ """CLI entry point for subprocess execution."""
329
+ parser = argparse.ArgumentParser(
330
+ description="Run a sub-agent task",
331
+ formatter_class=argparse.RawDescriptionHelpFormatter,
332
+ )
333
+ parser.add_argument(
334
+ "--type",
335
+ required=True,
336
+ choices=["Explore", "Plan", "Bash", "Research"],
337
+ help="Type of sub-agent",
338
+ )
339
+ parser.add_argument(
340
+ "--prompt",
341
+ required=True,
342
+ help="Task prompt",
343
+ )
344
+ parser.add_argument(
345
+ "--repo-root",
346
+ required=True,
347
+ type=Path,
348
+ help="Repository root directory",
349
+ )
350
+ parser.add_argument(
351
+ "--model-tier",
352
+ default="fast",
353
+ choices=["fast", "model"],
354
+ help="Model tier to use (fast=cheap/quick, model=standard)",
355
+ )
356
+ parser.add_argument(
357
+ "--max-turns",
358
+ type=int,
359
+ default=10,
360
+ help="Maximum API round-trips",
361
+ )
362
+ parser.add_argument(
363
+ "--agent-id",
364
+ help="Agent ID (for resume)",
365
+ )
366
+
367
+ args = parser.parse_args()
368
+
369
+ try:
370
+ runner = SubAgentRunner(
371
+ subagent_type=args.type,
372
+ repo_root=args.repo_root,
373
+ model_tier=args.model_tier,
374
+ max_turns=args.max_turns,
375
+ agent_id=args.agent_id,
376
+ )
377
+
378
+ result = runner.run(args.prompt)
379
+
380
+ # Output result as JSON to stdout
381
+ print(result.to_json())
382
+ sys.exit(0 if result.success else 1)
383
+
384
+ except Exception as e:
385
+ # Output error as JSON
386
+ error_result = {
387
+ "success": False,
388
+ "error": str(e),
389
+ "agent_type": args.type,
390
+ "task": args.prompt,
391
+ }
392
+ print(json.dumps(error_result, indent=2))
393
+ sys.exit(1)
394
+
395
+
396
+ if __name__ == "__main__":
397
+ main()
@@ -0,0 +1,13 @@
1
+ """System prompts for sub-agent types.
2
+
3
+ DEPRECATED: This module is deprecated. Import from .prompts instead.
4
+
5
+ This file re-exports from .prompts.subagents for backwards compatibility.
6
+ """
7
+
8
+ from .prompts.subagents import SUBAGENT_PROMPTS, get_subagent_prompt
9
+
10
+ # Backwards compatibility alias
11
+ get_system_prompt = get_subagent_prompt
12
+
13
+ __all__ = ["SUBAGENT_PROMPTS", "get_system_prompt", "get_subagent_prompt"]