hanzo-mcp 0.6.10__py3-none-any.whl → 0.6.13__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 hanzo-mcp might be problematic. Click here for more details.
- hanzo_mcp/__init__.py +11 -2
- hanzo_mcp/cli.py +69 -19
- hanzo_mcp/cli_enhanced.py +15 -12
- hanzo_mcp/cli_plugin.py +91 -0
- hanzo_mcp/config/__init__.py +1 -1
- hanzo_mcp/config/settings.py +75 -8
- hanzo_mcp/config/tool_config.py +2 -2
- hanzo_mcp/dev_server.py +20 -15
- hanzo_mcp/prompts/project_system.py +1 -1
- hanzo_mcp/server.py +18 -4
- hanzo_mcp/server_enhanced.py +69 -0
- hanzo_mcp/tools/__init__.py +78 -30
- hanzo_mcp/tools/agent/__init__.py +1 -1
- hanzo_mcp/tools/agent/agent_tool.py +2 -2
- hanzo_mcp/tools/common/__init__.py +15 -1
- hanzo_mcp/tools/common/base.py +4 -4
- hanzo_mcp/tools/common/batch_tool.py +1 -1
- hanzo_mcp/tools/common/config_tool.py +2 -2
- hanzo_mcp/tools/common/context.py +2 -2
- hanzo_mcp/tools/common/context_fix.py +26 -0
- hanzo_mcp/tools/common/critic_tool.py +196 -0
- hanzo_mcp/tools/common/decorators.py +208 -0
- hanzo_mcp/tools/common/enhanced_base.py +106 -0
- hanzo_mcp/tools/common/mode.py +116 -0
- hanzo_mcp/tools/common/mode_loader.py +105 -0
- hanzo_mcp/tools/common/permissions.py +1 -1
- hanzo_mcp/tools/common/personality.py +936 -0
- hanzo_mcp/tools/common/plugin_loader.py +287 -0
- hanzo_mcp/tools/common/stats.py +4 -4
- hanzo_mcp/tools/common/tool_list.py +1 -1
- hanzo_mcp/tools/common/validation.py +1 -1
- hanzo_mcp/tools/config/__init__.py +3 -1
- hanzo_mcp/tools/config/config_tool.py +1 -1
- hanzo_mcp/tools/config/mode_tool.py +209 -0
- hanzo_mcp/tools/database/__init__.py +1 -1
- hanzo_mcp/tools/editor/__init__.py +1 -1
- hanzo_mcp/tools/filesystem/__init__.py +19 -14
- hanzo_mcp/tools/filesystem/batch_search.py +3 -3
- hanzo_mcp/tools/filesystem/diff.py +2 -2
- hanzo_mcp/tools/filesystem/rules_tool.py +235 -0
- hanzo_mcp/tools/filesystem/{unified_search.py → search_tool.py} +12 -12
- hanzo_mcp/tools/filesystem/{symbols_unified.py → symbols_tool.py} +104 -5
- hanzo_mcp/tools/filesystem/watch.py +3 -2
- hanzo_mcp/tools/jupyter/__init__.py +2 -2
- hanzo_mcp/tools/jupyter/jupyter.py +1 -1
- hanzo_mcp/tools/llm/__init__.py +3 -3
- hanzo_mcp/tools/llm/llm_tool.py +648 -143
- hanzo_mcp/tools/mcp/__init__.py +2 -2
- hanzo_mcp/tools/mcp/{mcp_unified.py → mcp_tool.py} +3 -3
- hanzo_mcp/tools/shell/__init__.py +6 -6
- hanzo_mcp/tools/shell/base_process.py +4 -2
- hanzo_mcp/tools/shell/bash_session_executor.py +8 -5
- hanzo_mcp/tools/shell/{bash_unified.py → bash_tool.py} +1 -1
- hanzo_mcp/tools/shell/command_executor.py +8 -6
- hanzo_mcp/tools/shell/{npx_unified.py → npx_tool.py} +1 -1
- hanzo_mcp/tools/shell/open.py +2 -2
- hanzo_mcp/tools/shell/{process_unified.py → process_tool.py} +1 -1
- hanzo_mcp/tools/shell/run_command_windows.py +1 -1
- hanzo_mcp/tools/shell/uvx.py +47 -2
- hanzo_mcp/tools/shell/uvx_background.py +47 -2
- hanzo_mcp/tools/shell/{uvx_unified.py → uvx_tool.py} +1 -1
- hanzo_mcp/tools/todo/__init__.py +14 -19
- hanzo_mcp/tools/todo/todo.py +22 -1
- hanzo_mcp/tools/vector/__init__.py +7 -3
- hanzo_mcp/tools/vector/ast_analyzer.py +12 -4
- hanzo_mcp/tools/vector/infinity_store.py +11 -5
- hanzo_mcp/tools/vector/project_manager.py +4 -2
- hanzo_mcp-0.6.13.dist-info/METADATA +359 -0
- {hanzo_mcp-0.6.10.dist-info → hanzo_mcp-0.6.13.dist-info}/RECORD +73 -65
- {hanzo_mcp-0.6.10.dist-info → hanzo_mcp-0.6.13.dist-info}/entry_points.txt +1 -0
- hanzo_mcp/tools/common/palette.py +0 -344
- hanzo_mcp/tools/common/palette_loader.py +0 -108
- hanzo_mcp/tools/config/palette_tool.py +0 -179
- hanzo_mcp/tools/llm/llm_unified.py +0 -851
- hanzo_mcp-0.6.10.dist-info/METADATA +0 -339
- {hanzo_mcp-0.6.10.dist-info → hanzo_mcp-0.6.13.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.6.10.dist-info → hanzo_mcp-0.6.13.dist-info}/licenses/LICENSE +0 -0
- {hanzo_mcp-0.6.10.dist-info → hanzo_mcp-0.6.13.dist-info}/top_level.txt +0 -0
hanzo_mcp/tools/mcp/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""MCP management tools."""
|
|
2
2
|
|
|
3
|
-
from hanzo_mcp.tools.mcp.
|
|
3
|
+
from hanzo_mcp.tools.mcp.mcp_tool import MCPTool
|
|
4
4
|
|
|
5
5
|
# Legacy imports
|
|
6
6
|
from hanzo_mcp.tools.mcp.mcp_add import McpAddTool
|
|
@@ -8,7 +8,7 @@ from hanzo_mcp.tools.mcp.mcp_remove import McpRemoveTool
|
|
|
8
8
|
from hanzo_mcp.tools.mcp.mcp_stats import McpStatsTool
|
|
9
9
|
|
|
10
10
|
__all__ = [
|
|
11
|
-
"
|
|
11
|
+
"MCPTool",
|
|
12
12
|
"McpAddTool",
|
|
13
13
|
"McpRemoveTool",
|
|
14
14
|
"McpStatsTool",
|
|
@@ -74,7 +74,7 @@ ConfigValue = Annotated[
|
|
|
74
74
|
AutoStart = Annotated[
|
|
75
75
|
bool,
|
|
76
76
|
Field(
|
|
77
|
-
description="Auto-start server when Hanzo
|
|
77
|
+
description="Auto-start server when Hanzo AI starts",
|
|
78
78
|
default=True,
|
|
79
79
|
),
|
|
80
80
|
]
|
|
@@ -93,8 +93,8 @@ class MCPParams(TypedDict, total=False):
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
@final
|
|
96
|
-
class
|
|
97
|
-
"""
|
|
96
|
+
class MCPTool(BaseTool):
|
|
97
|
+
"""Tool for managing MCP servers."""
|
|
98
98
|
|
|
99
99
|
# Config file
|
|
100
100
|
CONFIG_FILE = Path.home() / ".hanzo" / "mcp" / "servers.json"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Shell tools package for Hanzo
|
|
1
|
+
"""Shell tools package for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This package provides tools for executing shell commands and scripts.
|
|
4
4
|
"""
|
|
@@ -8,11 +8,11 @@ from mcp.server import FastMCP
|
|
|
8
8
|
from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
|
|
9
9
|
from hanzo_mcp.tools.common.permissions import PermissionManager
|
|
10
10
|
|
|
11
|
-
# Import
|
|
12
|
-
from hanzo_mcp.tools.shell.
|
|
13
|
-
from hanzo_mcp.tools.shell.
|
|
14
|
-
from hanzo_mcp.tools.shell.
|
|
15
|
-
from hanzo_mcp.tools.shell.
|
|
11
|
+
# Import tools
|
|
12
|
+
from hanzo_mcp.tools.shell.bash_tool import bash_tool
|
|
13
|
+
from hanzo_mcp.tools.shell.npx_tool import npx_tool
|
|
14
|
+
from hanzo_mcp.tools.shell.uvx_tool import uvx_tool
|
|
15
|
+
from hanzo_mcp.tools.shell.process_tool import process_tool
|
|
16
16
|
from hanzo_mcp.tools.shell.open import open_tool
|
|
17
17
|
|
|
18
18
|
# Export all tool classes
|
|
@@ -130,7 +130,8 @@ class BaseProcessTool(BaseTool):
|
|
|
130
130
|
"""
|
|
131
131
|
# Check permissions if manager is available
|
|
132
132
|
if self.permission_manager and cwd:
|
|
133
|
-
self.permission_manager.
|
|
133
|
+
if not self.permission_manager.is_path_allowed(str(cwd)):
|
|
134
|
+
raise PermissionError(f"Access denied to path: {cwd}")
|
|
134
135
|
|
|
135
136
|
# Get command arguments
|
|
136
137
|
cmd_args = self.get_command_args(command, **kwargs)
|
|
@@ -179,7 +180,8 @@ class BaseProcessTool(BaseTool):
|
|
|
179
180
|
"""
|
|
180
181
|
# Check permissions if manager is available
|
|
181
182
|
if self.permission_manager and cwd:
|
|
182
|
-
self.permission_manager.
|
|
183
|
+
if not self.permission_manager.is_path_allowed(str(cwd)):
|
|
184
|
+
raise PermissionError(f"Access denied to path: {cwd}")
|
|
183
185
|
|
|
184
186
|
# Generate process ID and log file
|
|
185
187
|
process_id = f"{self.get_tool_name()}_{uuid.uuid4().hex[:8]}"
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
"""Bash session executor for Hanzo
|
|
1
|
+
"""Bash session executor for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This module provides a BashSessionExecutor class that replaces the old CommandExecutor
|
|
4
4
|
implementation with the new BashSession-based approach for better persistent execution.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
|
+
import logging
|
|
8
9
|
import os
|
|
9
10
|
import shlex
|
|
10
11
|
import subprocess
|
|
@@ -64,16 +65,18 @@ class BashSessionExecutor:
|
|
|
64
65
|
if data is not None:
|
|
65
66
|
try:
|
|
66
67
|
import json
|
|
67
|
-
|
|
68
|
+
logger = logging.getLogger(__name__)
|
|
68
69
|
if isinstance(data, (dict, list)):
|
|
69
70
|
data_str = json.dumps(data)
|
|
70
71
|
else:
|
|
71
72
|
data_str = str(data)
|
|
72
|
-
|
|
73
|
+
logger.debug(f"{message}: {data_str}")
|
|
73
74
|
except Exception:
|
|
74
|
-
|
|
75
|
+
logger = logging.getLogger(__name__)
|
|
76
|
+
logger.debug(f"{message}: {data}")
|
|
75
77
|
else:
|
|
76
|
-
|
|
78
|
+
logger = logging.getLogger(__name__)
|
|
79
|
+
logger.debug(f"{message}")
|
|
77
80
|
|
|
78
81
|
def allow_command(self, command: str) -> None:
|
|
79
82
|
"""Allow a specific command that might otherwise be excluded.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Command executor tools for Hanzo
|
|
1
|
+
"""Command executor tools for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This module provides tools for executing shell commands and scripts with
|
|
4
4
|
comprehensive error handling, permissions checking, and progress tracking.
|
|
@@ -22,7 +22,7 @@ from hanzo_mcp.tools.shell.base import CommandResult
|
|
|
22
22
|
|
|
23
23
|
@final
|
|
24
24
|
class CommandExecutor:
|
|
25
|
-
"""Command executor tools for Hanzo
|
|
25
|
+
"""Command executor tools for Hanzo AI.
|
|
26
26
|
|
|
27
27
|
This class provides tools for executing shell commands and scripts with
|
|
28
28
|
comprehensive error handling, permissions checking, and progress tracking.
|
|
@@ -183,16 +183,18 @@ class CommandExecutor:
|
|
|
183
183
|
if data is not None:
|
|
184
184
|
try:
|
|
185
185
|
import json
|
|
186
|
-
|
|
186
|
+
logger = logging.getLogger(__name__)
|
|
187
187
|
if isinstance(data, (dict, list)):
|
|
188
188
|
data_str = json.dumps(data)
|
|
189
189
|
else:
|
|
190
190
|
data_str = str(data)
|
|
191
|
-
|
|
191
|
+
logger.debug(f"{message}: {data_str}")
|
|
192
192
|
except Exception:
|
|
193
|
-
|
|
193
|
+
logger = logging.getLogger(__name__)
|
|
194
|
+
logger.debug(f"{message}: {data}")
|
|
194
195
|
else:
|
|
195
|
-
|
|
196
|
+
logger = logging.getLogger(__name__)
|
|
197
|
+
logger.debug(f"{message}")
|
|
196
198
|
|
|
197
199
|
def is_command_allowed(self, command: str) -> bool:
|
|
198
200
|
"""Check if a command is allowed based on exclusion lists.
|
hanzo_mcp/tools/shell/open.py
CHANGED
hanzo_mcp/tools/shell/uvx.py
CHANGED
|
@@ -129,11 +129,56 @@ For long-running servers, use uvx_background instead.
|
|
|
129
129
|
|
|
130
130
|
# Check if uvx is available
|
|
131
131
|
if not shutil.which("uvx"):
|
|
132
|
-
|
|
132
|
+
await tool_ctx.info("uvx not found, attempting to install...")
|
|
133
|
+
|
|
134
|
+
# Try to auto-install uvx
|
|
135
|
+
install_cmd = "curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
# Run installation
|
|
139
|
+
install_result = subprocess.run(
|
|
140
|
+
install_cmd,
|
|
141
|
+
shell=True,
|
|
142
|
+
capture_output=True,
|
|
143
|
+
text=True,
|
|
144
|
+
timeout=60
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if install_result.returncode == 0:
|
|
148
|
+
await tool_ctx.info("uvx installed successfully!")
|
|
149
|
+
|
|
150
|
+
# Add to PATH for current session
|
|
151
|
+
import os
|
|
152
|
+
home = os.path.expanduser("~")
|
|
153
|
+
os.environ["PATH"] = f"{home}/.cargo/bin:{os.environ.get('PATH', '')}"
|
|
154
|
+
|
|
155
|
+
# Check again
|
|
156
|
+
if not shutil.which("uvx"):
|
|
157
|
+
return """Error: uvx installed but not found in PATH.
|
|
158
|
+
Please add ~/.cargo/bin to your PATH and restart your shell.
|
|
159
|
+
|
|
160
|
+
Add to ~/.zshrc or ~/.bashrc:
|
|
161
|
+
export PATH="$HOME/.cargo/bin:$PATH"
|
|
162
|
+
"""
|
|
163
|
+
else:
|
|
164
|
+
return f"""Error: Failed to install uvx automatically.
|
|
165
|
+
|
|
166
|
+
Install manually with:
|
|
133
167
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
134
168
|
|
|
135
169
|
Or on macOS:
|
|
136
|
-
brew install uv
|
|
170
|
+
brew install uv
|
|
171
|
+
|
|
172
|
+
Error details: {install_result.stderr}"""
|
|
173
|
+
|
|
174
|
+
except subprocess.TimeoutExpired:
|
|
175
|
+
return """Error: Installation timed out. Install uvx manually with:
|
|
176
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
177
|
+
except Exception as e:
|
|
178
|
+
return f"""Error: Failed to auto-install uvx: {str(e)}
|
|
179
|
+
|
|
180
|
+
Install manually with:
|
|
181
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
137
182
|
|
|
138
183
|
# Build command
|
|
139
184
|
cmd = ["uvx"]
|
|
@@ -150,11 +150,56 @@ Use 'processes' to list running processes and 'pkill' to stop them.
|
|
|
150
150
|
|
|
151
151
|
# Check if uvx is available
|
|
152
152
|
if not shutil.which("uvx"):
|
|
153
|
-
|
|
153
|
+
await tool_ctx.info("uvx not found, attempting to install...")
|
|
154
|
+
|
|
155
|
+
# Try to auto-install uvx
|
|
156
|
+
install_cmd = "curl -LsSf https://astral.sh/uv/install.sh | sh"
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
# Run installation
|
|
160
|
+
install_result = subprocess.run(
|
|
161
|
+
install_cmd,
|
|
162
|
+
shell=True,
|
|
163
|
+
capture_output=True,
|
|
164
|
+
text=True,
|
|
165
|
+
timeout=60
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
if install_result.returncode == 0:
|
|
169
|
+
await tool_ctx.info("uvx installed successfully!")
|
|
170
|
+
|
|
171
|
+
# Add to PATH for current session
|
|
172
|
+
import os
|
|
173
|
+
home = os.path.expanduser("~")
|
|
174
|
+
os.environ["PATH"] = f"{home}/.cargo/bin:{os.environ.get('PATH', '')}"
|
|
175
|
+
|
|
176
|
+
# Check again
|
|
177
|
+
if not shutil.which("uvx"):
|
|
178
|
+
return """Error: uvx installed but not found in PATH.
|
|
179
|
+
Please add ~/.cargo/bin to your PATH and restart your shell.
|
|
180
|
+
|
|
181
|
+
Add to ~/.zshrc or ~/.bashrc:
|
|
182
|
+
export PATH="$HOME/.cargo/bin:$PATH"
|
|
183
|
+
"""
|
|
184
|
+
else:
|
|
185
|
+
return f"""Error: Failed to install uvx automatically.
|
|
186
|
+
|
|
187
|
+
Install manually with:
|
|
154
188
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
155
189
|
|
|
156
190
|
Or on macOS:
|
|
157
|
-
brew install uv
|
|
191
|
+
brew install uv
|
|
192
|
+
|
|
193
|
+
Error details: {install_result.stderr}"""
|
|
194
|
+
|
|
195
|
+
except subprocess.TimeoutExpired:
|
|
196
|
+
return """Error: Installation timed out. Install uvx manually with:
|
|
197
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
198
|
+
except Exception as e:
|
|
199
|
+
return f"""Error: Failed to auto-install uvx: {str(e)}
|
|
200
|
+
|
|
201
|
+
Install manually with:
|
|
202
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh"""
|
|
158
203
|
|
|
159
204
|
# Build command
|
|
160
205
|
cmd = ["uvx"]
|
hanzo_mcp/tools/todo/__init__.py
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
"""Todo tools package for Hanzo
|
|
1
|
+
"""Todo tools package for Hanzo AI.
|
|
2
2
|
|
|
3
|
-
This package provides
|
|
4
|
-
|
|
3
|
+
This package provides a unified todo management tool for organizing tasks
|
|
4
|
+
within Claude Desktop sessions.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from mcp.server import FastMCP
|
|
8
8
|
|
|
9
9
|
from hanzo_mcp.tools.common.base import BaseTool, ToolRegistry
|
|
10
|
-
from hanzo_mcp.tools.todo.
|
|
11
|
-
from hanzo_mcp.tools.todo.todo_write import TodoWriteTool
|
|
10
|
+
from hanzo_mcp.tools.todo.todo import TodoTool
|
|
12
11
|
|
|
13
12
|
# Export all tool classes
|
|
14
13
|
__all__ = [
|
|
15
|
-
"
|
|
16
|
-
"TodoWriteTool",
|
|
14
|
+
"TodoTool",
|
|
17
15
|
"get_todo_tools",
|
|
18
16
|
"register_todo_tools",
|
|
19
17
|
]
|
|
@@ -26,8 +24,7 @@ def get_todo_tools() -> list[BaseTool]:
|
|
|
26
24
|
List of todo tool instances
|
|
27
25
|
"""
|
|
28
26
|
return [
|
|
29
|
-
|
|
30
|
-
TodoWriteTool(),
|
|
27
|
+
TodoTool(),
|
|
31
28
|
]
|
|
32
29
|
|
|
33
30
|
|
|
@@ -44,23 +41,21 @@ def register_todo_tools(
|
|
|
44
41
|
Returns:
|
|
45
42
|
List of registered tools
|
|
46
43
|
"""
|
|
47
|
-
# Define tool mapping
|
|
44
|
+
# Define tool mapping - single unified todo tool
|
|
48
45
|
tool_classes = {
|
|
49
|
-
"
|
|
50
|
-
"todo_write": TodoWriteTool,
|
|
46
|
+
"todo": TodoTool,
|
|
51
47
|
}
|
|
52
|
-
|
|
48
|
+
|
|
53
49
|
tools = []
|
|
54
|
-
|
|
50
|
+
|
|
55
51
|
if enabled_tools:
|
|
56
52
|
# Use individual tool configuration
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
tools.append(tool_class())
|
|
53
|
+
# Support both old names and new name for backward compatibility
|
|
54
|
+
if enabled_tools.get("todo", True) or enabled_tools.get("todo_read", True) or enabled_tools.get("todo_write", True):
|
|
55
|
+
tools.append(TodoTool())
|
|
61
56
|
else:
|
|
62
57
|
# Use all tools (backward compatibility)
|
|
63
58
|
tools = get_todo_tools()
|
|
64
|
-
|
|
59
|
+
|
|
65
60
|
ToolRegistry.register_tools(mcp_server, tools)
|
|
66
61
|
return tools
|
hanzo_mcp/tools/todo/todo.py
CHANGED
|
@@ -260,6 +260,27 @@ todo --filter in_progress
|
|
|
260
260
|
self.write_todos([])
|
|
261
261
|
return f"Cleared all {count} todo(s)"
|
|
262
262
|
|
|
263
|
+
@override
|
|
263
264
|
def register(self, mcp_server) -> None:
|
|
264
265
|
"""Register this tool with the MCP server."""
|
|
265
|
-
|
|
266
|
+
tool_self = self # Create a reference to self for use in the closure
|
|
267
|
+
|
|
268
|
+
@mcp_server.tool(name=self.name, description=self.description)
|
|
269
|
+
async def todo(
|
|
270
|
+
action: Action = "list",
|
|
271
|
+
content: Content = None,
|
|
272
|
+
id: TodoId = None,
|
|
273
|
+
status: Status = None,
|
|
274
|
+
priority: Priority = None,
|
|
275
|
+
filter: Filter = None,
|
|
276
|
+
ctx: MCPContext = None,
|
|
277
|
+
) -> str:
|
|
278
|
+
return await tool_self.call(
|
|
279
|
+
ctx,
|
|
280
|
+
action=action,
|
|
281
|
+
content=content,
|
|
282
|
+
id=id,
|
|
283
|
+
status=status,
|
|
284
|
+
priority=priority,
|
|
285
|
+
filter=filter,
|
|
286
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Vector database tools for Hanzo
|
|
1
|
+
"""Vector database tools for Hanzo AI.
|
|
2
2
|
|
|
3
3
|
This package provides tools for working with local vector databases for semantic search,
|
|
4
4
|
document indexing, and retrieval-augmented generation (RAG) workflows.
|
|
@@ -62,7 +62,9 @@ try:
|
|
|
62
62
|
# Auto-detect projects from search paths for new manager
|
|
63
63
|
if search_paths:
|
|
64
64
|
detected_projects = project_manager.detect_projects(search_paths)
|
|
65
|
-
|
|
65
|
+
import logging
|
|
66
|
+
logger = logging.getLogger(__name__)
|
|
67
|
+
logger.info(f"Detected {len(detected_projects)} projects with LLM.md files")
|
|
66
68
|
|
|
67
69
|
# Register individual tools if enabled
|
|
68
70
|
if tool_enabled.get("index", True):
|
|
@@ -85,7 +87,9 @@ except ImportError:
|
|
|
85
87
|
|
|
86
88
|
def register_vector_tools(*args, **kwargs) -> list[BaseTool]:
|
|
87
89
|
"""Vector tools not available - missing dependencies."""
|
|
88
|
-
|
|
90
|
+
import logging
|
|
91
|
+
logger = logging.getLogger(__name__)
|
|
92
|
+
logger.warning("Vector tools not available. Install infinity-embedded: pip install infinity-embedded")
|
|
89
93
|
return []
|
|
90
94
|
|
|
91
95
|
|
|
@@ -94,7 +94,9 @@ class ASTAnalyzer:
|
|
|
94
94
|
# Python parser
|
|
95
95
|
self.parsers['python'] = tree_sitter.Language(tspython.language())
|
|
96
96
|
except Exception as e:
|
|
97
|
-
|
|
97
|
+
import logging
|
|
98
|
+
logger = logging.getLogger(__name__)
|
|
99
|
+
logger.warning(f"Could not initialize Python parser: {e}")
|
|
98
100
|
|
|
99
101
|
def analyze_file(self, file_path: str) -> Optional[FileAST]:
|
|
100
102
|
"""Analyze a file and extract AST information and symbols.
|
|
@@ -127,7 +129,9 @@ class ASTAnalyzer:
|
|
|
127
129
|
return self._analyze_generic_file(file_path, content, file_hash, language)
|
|
128
130
|
|
|
129
131
|
except Exception as e:
|
|
130
|
-
|
|
132
|
+
import logging
|
|
133
|
+
logger = logging.getLogger(__name__)
|
|
134
|
+
logger.error(f"Error analyzing file {file_path}: {e}")
|
|
131
135
|
return None
|
|
132
136
|
|
|
133
137
|
def _detect_language(self, path: Path) -> Optional[str]:
|
|
@@ -194,9 +198,13 @@ class ASTAnalyzer:
|
|
|
194
198
|
ast_nodes = self._extract_tree_sitter_nodes(ts_tree.root_node, content)
|
|
195
199
|
|
|
196
200
|
except SyntaxError as e:
|
|
197
|
-
|
|
201
|
+
import logging
|
|
202
|
+
logger = logging.getLogger(__name__)
|
|
203
|
+
logger.error(f"Syntax error in {file_path}: {e}")
|
|
198
204
|
except Exception as e:
|
|
199
|
-
|
|
205
|
+
import logging
|
|
206
|
+
logger = logging.getLogger(__name__)
|
|
207
|
+
logger.error(f"Error parsing Python file {file_path}: {e}")
|
|
200
208
|
|
|
201
209
|
return FileAST(
|
|
202
210
|
file_path=file_path,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Infinity vector database integration for Hanzo
|
|
1
|
+
"""Infinity vector database integration for Hanzo AI."""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import hashlib
|
|
@@ -45,7 +45,7 @@ class SymbolSearchResult:
|
|
|
45
45
|
|
|
46
46
|
@dataclass
|
|
47
47
|
class UnifiedSearchResult:
|
|
48
|
-
"""
|
|
48
|
+
"""Search result combining text, vector, and symbol search."""
|
|
49
49
|
type: str # 'document', 'symbol', 'reference'
|
|
50
50
|
content: str
|
|
51
51
|
file_path: str
|
|
@@ -528,7 +528,9 @@ class InfinityVectorStore:
|
|
|
528
528
|
return file_ast
|
|
529
529
|
|
|
530
530
|
except Exception as e:
|
|
531
|
-
|
|
531
|
+
import logging
|
|
532
|
+
logger = logging.getLogger(__name__)
|
|
533
|
+
logger.error(f"Error searching AST nodes: {e}")
|
|
532
534
|
return None
|
|
533
535
|
|
|
534
536
|
def get_file_references(self, file_path: str) -> List[Dict[str, Any]]:
|
|
@@ -555,7 +557,9 @@ class InfinityVectorStore:
|
|
|
555
557
|
return references
|
|
556
558
|
|
|
557
559
|
except Exception as e:
|
|
558
|
-
|
|
560
|
+
import logging
|
|
561
|
+
logger = logging.getLogger(__name__)
|
|
562
|
+
logger.error(f"Error getting file references: {e}")
|
|
559
563
|
return []
|
|
560
564
|
|
|
561
565
|
def search(
|
|
@@ -803,7 +807,9 @@ class InfinityVectorStore:
|
|
|
803
807
|
|
|
804
808
|
return True
|
|
805
809
|
except Exception as e:
|
|
806
|
-
|
|
810
|
+
import logging
|
|
811
|
+
logger = logging.getLogger(__name__)
|
|
812
|
+
logger.error(f"Error clearing vector store: {e}")
|
|
807
813
|
return False
|
|
808
814
|
|
|
809
815
|
async def index_document(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Project-aware vector database management for Hanzo
|
|
1
|
+
"""Project-aware vector database management for Hanzo AI."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
@@ -294,7 +294,9 @@ class ProjectVectorManager:
|
|
|
294
294
|
project_name = project_names[i]
|
|
295
295
|
if isinstance(result, Exception):
|
|
296
296
|
# Log error but continue
|
|
297
|
-
|
|
297
|
+
import logging
|
|
298
|
+
logger = logging.getLogger(__name__)
|
|
299
|
+
logger.error(f"Error searching project {project_name}: {result}")
|
|
298
300
|
combined_results[project_name] = []
|
|
299
301
|
else:
|
|
300
302
|
combined_results[project_name] = result
|