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.
- emdash_core/__init__.py +3 -0
- emdash_core/agent/__init__.py +37 -0
- emdash_core/agent/agents.py +225 -0
- emdash_core/agent/code_reviewer.py +476 -0
- emdash_core/agent/compaction.py +143 -0
- emdash_core/agent/context_manager.py +140 -0
- emdash_core/agent/events.py +338 -0
- emdash_core/agent/handlers.py +224 -0
- emdash_core/agent/inprocess_subagent.py +377 -0
- emdash_core/agent/mcp/__init__.py +50 -0
- emdash_core/agent/mcp/client.py +346 -0
- emdash_core/agent/mcp/config.py +302 -0
- emdash_core/agent/mcp/manager.py +496 -0
- emdash_core/agent/mcp/tool_factory.py +213 -0
- emdash_core/agent/prompts/__init__.py +38 -0
- emdash_core/agent/prompts/main_agent.py +104 -0
- emdash_core/agent/prompts/subagents.py +131 -0
- emdash_core/agent/prompts/workflow.py +136 -0
- emdash_core/agent/providers/__init__.py +34 -0
- emdash_core/agent/providers/base.py +143 -0
- emdash_core/agent/providers/factory.py +80 -0
- emdash_core/agent/providers/models.py +220 -0
- emdash_core/agent/providers/openai_provider.py +463 -0
- emdash_core/agent/providers/transformers_provider.py +217 -0
- emdash_core/agent/research/__init__.py +81 -0
- emdash_core/agent/research/agent.py +143 -0
- emdash_core/agent/research/controller.py +254 -0
- emdash_core/agent/research/critic.py +428 -0
- emdash_core/agent/research/macros.py +469 -0
- emdash_core/agent/research/planner.py +449 -0
- emdash_core/agent/research/researcher.py +436 -0
- emdash_core/agent/research/state.py +523 -0
- emdash_core/agent/research/synthesizer.py +594 -0
- emdash_core/agent/reviewer_profile.py +475 -0
- emdash_core/agent/rules.py +123 -0
- emdash_core/agent/runner.py +601 -0
- emdash_core/agent/session.py +262 -0
- emdash_core/agent/spec_schema.py +66 -0
- emdash_core/agent/specification.py +479 -0
- emdash_core/agent/subagent.py +397 -0
- emdash_core/agent/subagent_prompts.py +13 -0
- emdash_core/agent/toolkit.py +482 -0
- emdash_core/agent/toolkits/__init__.py +64 -0
- emdash_core/agent/toolkits/base.py +96 -0
- emdash_core/agent/toolkits/explore.py +47 -0
- emdash_core/agent/toolkits/plan.py +55 -0
- emdash_core/agent/tools/__init__.py +141 -0
- emdash_core/agent/tools/analytics.py +436 -0
- emdash_core/agent/tools/base.py +131 -0
- emdash_core/agent/tools/coding.py +484 -0
- emdash_core/agent/tools/github_mcp.py +592 -0
- emdash_core/agent/tools/history.py +13 -0
- emdash_core/agent/tools/modes.py +153 -0
- emdash_core/agent/tools/plan.py +206 -0
- emdash_core/agent/tools/plan_write.py +135 -0
- emdash_core/agent/tools/search.py +412 -0
- emdash_core/agent/tools/spec.py +341 -0
- emdash_core/agent/tools/task.py +262 -0
- emdash_core/agent/tools/task_output.py +204 -0
- emdash_core/agent/tools/tasks.py +454 -0
- emdash_core/agent/tools/traversal.py +588 -0
- emdash_core/agent/tools/web.py +179 -0
- emdash_core/analytics/__init__.py +5 -0
- emdash_core/analytics/engine.py +1286 -0
- emdash_core/api/__init__.py +5 -0
- emdash_core/api/agent.py +308 -0
- emdash_core/api/agents.py +154 -0
- emdash_core/api/analyze.py +264 -0
- emdash_core/api/auth.py +173 -0
- emdash_core/api/context.py +77 -0
- emdash_core/api/db.py +121 -0
- emdash_core/api/embed.py +131 -0
- emdash_core/api/feature.py +143 -0
- emdash_core/api/health.py +93 -0
- emdash_core/api/index.py +162 -0
- emdash_core/api/plan.py +110 -0
- emdash_core/api/projectmd.py +210 -0
- emdash_core/api/query.py +320 -0
- emdash_core/api/research.py +122 -0
- emdash_core/api/review.py +161 -0
- emdash_core/api/router.py +76 -0
- emdash_core/api/rules.py +116 -0
- emdash_core/api/search.py +119 -0
- emdash_core/api/spec.py +99 -0
- emdash_core/api/swarm.py +223 -0
- emdash_core/api/tasks.py +109 -0
- emdash_core/api/team.py +120 -0
- emdash_core/auth/__init__.py +17 -0
- emdash_core/auth/github.py +389 -0
- emdash_core/config.py +74 -0
- emdash_core/context/__init__.py +52 -0
- emdash_core/context/models.py +50 -0
- emdash_core/context/providers/__init__.py +11 -0
- emdash_core/context/providers/base.py +74 -0
- emdash_core/context/providers/explored_areas.py +183 -0
- emdash_core/context/providers/touched_areas.py +360 -0
- emdash_core/context/registry.py +73 -0
- emdash_core/context/reranker.py +199 -0
- emdash_core/context/service.py +260 -0
- emdash_core/context/session.py +352 -0
- emdash_core/core/__init__.py +104 -0
- emdash_core/core/config.py +454 -0
- emdash_core/core/exceptions.py +55 -0
- emdash_core/core/models.py +265 -0
- emdash_core/core/review_config.py +57 -0
- emdash_core/db/__init__.py +67 -0
- emdash_core/db/auth.py +134 -0
- emdash_core/db/models.py +91 -0
- emdash_core/db/provider.py +222 -0
- emdash_core/db/providers/__init__.py +5 -0
- emdash_core/db/providers/supabase.py +452 -0
- emdash_core/embeddings/__init__.py +24 -0
- emdash_core/embeddings/indexer.py +534 -0
- emdash_core/embeddings/models.py +192 -0
- emdash_core/embeddings/providers/__init__.py +7 -0
- emdash_core/embeddings/providers/base.py +112 -0
- emdash_core/embeddings/providers/fireworks.py +141 -0
- emdash_core/embeddings/providers/openai.py +104 -0
- emdash_core/embeddings/registry.py +146 -0
- emdash_core/embeddings/service.py +215 -0
- emdash_core/graph/__init__.py +26 -0
- emdash_core/graph/builder.py +134 -0
- emdash_core/graph/connection.py +692 -0
- emdash_core/graph/schema.py +416 -0
- emdash_core/graph/writer.py +667 -0
- emdash_core/ingestion/__init__.py +7 -0
- emdash_core/ingestion/change_detector.py +150 -0
- emdash_core/ingestion/git/__init__.py +5 -0
- emdash_core/ingestion/git/commit_analyzer.py +196 -0
- emdash_core/ingestion/github/__init__.py +6 -0
- emdash_core/ingestion/github/pr_fetcher.py +296 -0
- emdash_core/ingestion/github/task_extractor.py +100 -0
- emdash_core/ingestion/orchestrator.py +540 -0
- emdash_core/ingestion/parsers/__init__.py +10 -0
- emdash_core/ingestion/parsers/base_parser.py +66 -0
- emdash_core/ingestion/parsers/call_graph_builder.py +121 -0
- emdash_core/ingestion/parsers/class_extractor.py +154 -0
- emdash_core/ingestion/parsers/function_extractor.py +202 -0
- emdash_core/ingestion/parsers/import_analyzer.py +119 -0
- emdash_core/ingestion/parsers/python_parser.py +123 -0
- emdash_core/ingestion/parsers/registry.py +72 -0
- emdash_core/ingestion/parsers/ts_ast_parser.js +313 -0
- emdash_core/ingestion/parsers/typescript_parser.py +278 -0
- emdash_core/ingestion/repository.py +346 -0
- emdash_core/models/__init__.py +38 -0
- emdash_core/models/agent.py +68 -0
- emdash_core/models/index.py +77 -0
- emdash_core/models/query.py +113 -0
- emdash_core/planning/__init__.py +7 -0
- emdash_core/planning/agent_api.py +413 -0
- emdash_core/planning/context_builder.py +265 -0
- emdash_core/planning/feature_context.py +232 -0
- emdash_core/planning/feature_expander.py +646 -0
- emdash_core/planning/llm_explainer.py +198 -0
- emdash_core/planning/similarity.py +509 -0
- emdash_core/planning/team_focus.py +821 -0
- emdash_core/server.py +153 -0
- emdash_core/sse/__init__.py +5 -0
- emdash_core/sse/stream.py +196 -0
- emdash_core/swarm/__init__.py +17 -0
- emdash_core/swarm/merge_agent.py +383 -0
- emdash_core/swarm/session_manager.py +274 -0
- emdash_core/swarm/swarm_runner.py +226 -0
- emdash_core/swarm/task_definition.py +137 -0
- emdash_core/swarm/worker_spawner.py +319 -0
- emdash_core/swarm/worktree_manager.py +278 -0
- emdash_core/templates/__init__.py +10 -0
- emdash_core/templates/defaults/agent-builder.md.template +82 -0
- emdash_core/templates/defaults/focus.md.template +115 -0
- emdash_core/templates/defaults/pr-review-enhanced.md.template +309 -0
- emdash_core/templates/defaults/pr-review.md.template +80 -0
- emdash_core/templates/defaults/project.md.template +85 -0
- emdash_core/templates/defaults/research_critic.md.template +112 -0
- emdash_core/templates/defaults/research_planner.md.template +85 -0
- emdash_core/templates/defaults/research_synthesizer.md.template +128 -0
- emdash_core/templates/defaults/reviewer.md.template +81 -0
- emdash_core/templates/defaults/spec.md.template +41 -0
- emdash_core/templates/defaults/tasks.md.template +78 -0
- emdash_core/templates/loader.py +296 -0
- emdash_core/utils/__init__.py +45 -0
- emdash_core/utils/git.py +84 -0
- emdash_core/utils/image.py +502 -0
- emdash_core/utils/logger.py +51 -0
- emdash_core-0.1.7.dist-info/METADATA +35 -0
- emdash_core-0.1.7.dist-info/RECORD +187 -0
- emdash_core-0.1.7.dist-info/WHEEL +4 -0
- 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
|
+
)
|