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,179 @@
1
+ """Web search and fetch tool."""
2
+
3
+ from typing import Optional
4
+
5
+ from .base import BaseTool, ToolResult, ToolCategory
6
+ from ...utils.logger import log
7
+
8
+
9
+ class WebTool(BaseTool):
10
+ """Tool for web search and page fetching."""
11
+
12
+ name = "web"
13
+ description = """Search the web or fetch content from a URL.
14
+
15
+ Use mode 'search' to search the web for information.
16
+ Use mode 'fetch' to get content from a specific URL.
17
+
18
+ Useful for:
19
+ - Finding documentation
20
+ - Looking up error messages
21
+ - Getting latest library information
22
+ - Reading external resources"""
23
+ category = ToolCategory.SEARCH
24
+
25
+ def execute(
26
+ self,
27
+ mode: str = "search",
28
+ query: Optional[str] = None,
29
+ url: Optional[str] = None,
30
+ max_results: int = 5,
31
+ ) -> ToolResult:
32
+ """Execute web operation.
33
+
34
+ Args:
35
+ mode: 'search' or 'fetch'
36
+ query: Search query (for search mode)
37
+ url: URL to fetch (for fetch mode)
38
+ max_results: Max search results
39
+
40
+ Returns:
41
+ ToolResult with web content
42
+ """
43
+ if mode == "search":
44
+ if not query:
45
+ return ToolResult.error_result(
46
+ "Query required for search mode",
47
+ )
48
+ return self._search(query, max_results)
49
+ elif mode == "fetch":
50
+ if not url:
51
+ return ToolResult.error_result(
52
+ "URL required for fetch mode",
53
+ )
54
+ return self._fetch(url)
55
+ else:
56
+ return ToolResult.error_result(
57
+ f"Unknown mode: {mode}",
58
+ suggestions=["Use mode 'search' or 'fetch'"],
59
+ )
60
+
61
+ def _search(self, query: str, max_results: int) -> ToolResult:
62
+ """Perform web search.
63
+
64
+ Args:
65
+ query: Search query
66
+ max_results: Maximum results
67
+
68
+ Returns:
69
+ ToolResult with search results
70
+ """
71
+ try:
72
+ # Try DuckDuckGo search
73
+ from duckduckgo_search import DDGS
74
+
75
+ results = []
76
+ with DDGS() as ddgs:
77
+ for r in ddgs.text(query, max_results=max_results):
78
+ results.append({
79
+ "title": r.get("title", ""),
80
+ "url": r.get("href", ""),
81
+ "snippet": r.get("body", ""),
82
+ })
83
+
84
+ return ToolResult.success_result(
85
+ data={
86
+ "query": query,
87
+ "results": results,
88
+ "count": len(results),
89
+ },
90
+ )
91
+
92
+ except ImportError:
93
+ return ToolResult.error_result(
94
+ "Web search not available",
95
+ suggestions=["Install duckduckgo-search: pip install duckduckgo-search"],
96
+ )
97
+ except Exception as e:
98
+ log.exception("Web search failed")
99
+ return ToolResult.error_result(f"Search failed: {str(e)}")
100
+
101
+ def _fetch(self, url: str) -> ToolResult:
102
+ """Fetch content from URL.
103
+
104
+ Args:
105
+ url: URL to fetch
106
+
107
+ Returns:
108
+ ToolResult with page content
109
+ """
110
+ try:
111
+ import httpx
112
+ from bs4 import BeautifulSoup
113
+
114
+ # Fetch the page
115
+ response = httpx.get(url, timeout=30, follow_redirects=True)
116
+ response.raise_for_status()
117
+
118
+ # Parse HTML
119
+ soup = BeautifulSoup(response.text, "html.parser")
120
+
121
+ # Remove script and style elements
122
+ for element in soup(["script", "style", "nav", "header", "footer"]):
123
+ element.decompose()
124
+
125
+ # Get text content
126
+ text = soup.get_text(separator="\n", strip=True)
127
+
128
+ # Truncate if too long
129
+ if len(text) > 10000:
130
+ text = text[:10000] + "\n\n[Content truncated...]"
131
+
132
+ # Get title
133
+ title = ""
134
+ if soup.title:
135
+ title = soup.title.string or ""
136
+
137
+ return ToolResult.success_result(
138
+ data={
139
+ "url": url,
140
+ "title": title,
141
+ "content": text,
142
+ "length": len(text),
143
+ },
144
+ )
145
+
146
+ except ImportError:
147
+ return ToolResult.error_result(
148
+ "Web fetch not available",
149
+ suggestions=["Install httpx and beautifulsoup4"],
150
+ )
151
+ except Exception as e:
152
+ log.exception("Web fetch failed")
153
+ return ToolResult.error_result(f"Fetch failed: {str(e)}")
154
+
155
+ def get_schema(self) -> dict:
156
+ """Get OpenAI function schema."""
157
+ return self._make_schema(
158
+ properties={
159
+ "mode": {
160
+ "type": "string",
161
+ "enum": ["search", "fetch"],
162
+ "description": "Operation mode: 'search' for web search, 'fetch' for URL content",
163
+ },
164
+ "query": {
165
+ "type": "string",
166
+ "description": "Search query (required for search mode)",
167
+ },
168
+ "url": {
169
+ "type": "string",
170
+ "description": "URL to fetch (required for fetch mode)",
171
+ },
172
+ "max_results": {
173
+ "type": "integer",
174
+ "description": "Maximum search results",
175
+ "default": 5,
176
+ },
177
+ },
178
+ required=["mode"],
179
+ )
@@ -0,0 +1,5 @@
1
+ """Graph analytics module."""
2
+
3
+ from .engine import AnalyticsEngine
4
+
5
+ __all__ = ['AnalyticsEngine']