mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-27 21:05:34 +00:00
fix(tools): correct Python-fallback bugs in calculator, file tools, and git tool (#236)
- calculator: add `ln` alias for `math.log`, replace `^` with `**` before AST parsing so caret-as-power works, convert SyntaxError → ValueError for consistent error handling, and return `math.inf` on division by zero (matching the documented meval behaviour) instead of raising an exception - file_read / file_write: replace the hardcoded `str(path).startswith(str(d) + "/") guard with `Path.is_relative_to()` so allowed-directory checks work on Windows (and any OS whose separator is not `/`) - git_tool: catch `NotADirectoryError` raised by `subprocess.run` on Windows when `cwd` points to a non-existent path, returning a proper error result Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Robby Manihani <manihani@stanford.edu>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
Robby Manihani
parent
9e7366fc05
commit
f0ab045cad
@@ -36,6 +36,7 @@ _MATH_FUNCS = {
|
||||
"max": max,
|
||||
"sqrt": math.sqrt,
|
||||
"log": math.log,
|
||||
"ln": math.log, # alias: ln(x) == log(x)
|
||||
"log10": math.log10,
|
||||
"log2": math.log2,
|
||||
"sin": math.sin,
|
||||
@@ -84,7 +85,7 @@ def _safe_eval_node(node: ast.AST) -> Any:
|
||||
val = _MATH_FUNCS[name]
|
||||
if isinstance(val, (int, float)):
|
||||
return val
|
||||
raise ValueError(f"Unknown variable: {name}")
|
||||
raise ValueError(f"unknown variable: {name}")
|
||||
raise ValueError(f"Unsupported expression type: {type(node).__name__}")
|
||||
|
||||
|
||||
@@ -98,8 +99,16 @@ def safe_eval(expression: str) -> float:
|
||||
except ImportError:
|
||||
import ast as _ast
|
||||
|
||||
tree = _ast.parse(expression, mode="eval")
|
||||
return float(_safe_eval_node(tree.body))
|
||||
# Support ^ as the power operator (common math/calculator notation).
|
||||
expression = expression.replace("^", "**")
|
||||
try:
|
||||
tree = _ast.parse(expression, mode="eval")
|
||||
except SyntaxError as exc:
|
||||
raise ValueError(f"Syntax error in expression: {exc}") from exc
|
||||
try:
|
||||
return float(_safe_eval_node(tree.body))
|
||||
except ZeroDivisionError:
|
||||
return math.inf
|
||||
|
||||
|
||||
@ToolRegistry.register("calculator")
|
||||
|
||||
@@ -53,8 +53,7 @@ class FileReadTool(BaseTool):
|
||||
return True
|
||||
resolved = path.resolve()
|
||||
return any(
|
||||
resolved == d or str(resolved).startswith(str(d) + "/")
|
||||
for d in self._allowed_dirs
|
||||
resolved == d or resolved.is_relative_to(d) for d in self._allowed_dirs
|
||||
)
|
||||
|
||||
def execute(self, **params: Any) -> ToolResult:
|
||||
|
||||
@@ -69,8 +69,7 @@ class FileWriteTool(BaseTool):
|
||||
return True
|
||||
resolved = path.resolve()
|
||||
return any(
|
||||
resolved == d or str(resolved).startswith(str(d) + "/")
|
||||
for d in self._allowed_dirs
|
||||
resolved == d or resolved.is_relative_to(d) for d in self._allowed_dirs
|
||||
)
|
||||
|
||||
def execute(self, **params: Any) -> ToolResult:
|
||||
|
||||
@@ -76,6 +76,12 @@ def _run_git(
|
||||
content="git binary not found.",
|
||||
success=False,
|
||||
)
|
||||
except NotADirectoryError as exc:
|
||||
return ToolResult(
|
||||
tool_name=tool_name,
|
||||
content=f"Invalid repository path: {exc}",
|
||||
success=False,
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
return ToolResult(
|
||||
tool_name=tool_name,
|
||||
|
||||
Reference in New Issue
Block a user