77339d5c58
Merge create_task into create_note (set status='todo' for tasks, omit for notes), merge delete_task into delete_note, consolidate entity tools (create/update_person → save_person, create/update_place → save_place), rename get_note → read_note with clearer descriptions, move calculate out of rag.py into utility.py, and extract shared duplicate detection into check_duplicate() helper. Updates all downstream references in generation_task.py, quick_capture.py, ToolCallCard.vue, and WorkspaceView.vue. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 lines
1.4 KiB
Python
35 lines
1.4 KiB
Python
"""General-purpose utility tools."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fabledassistant.services.tools._registry import tool
|
|
|
|
|
|
@tool(
|
|
name="calculate",
|
|
description=(
|
|
"Evaluate a mathematical expression and return the exact result. Use this for any "
|
|
"arithmetic, percentages, unit conversions, or multi-step calculations where precision "
|
|
"matters. Supports standard math operators (+, -, *, /, **, %) and all Python math "
|
|
"module functions (sqrt, log, sin, cos, floor, ceil, etc.)."
|
|
),
|
|
parameters={
|
|
"expression": {"type": "string", "description": "A valid Python math expression (e.g. '(450 * 1.13) / 12', 'sqrt(144)', 'log(1000, 10)')"},
|
|
},
|
|
required=["expression"],
|
|
)
|
|
async def calculate_tool(*, user_id, arguments, **_ctx):
|
|
import math as _math
|
|
|
|
expr = str(arguments.get("expression", "")).strip()
|
|
if not expr:
|
|
return {"success": False, "error": "expression is required"}
|
|
allowed_names = {k: v for k, v in vars(_math).items() if not k.startswith("_")}
|
|
allowed_names["abs"] = abs
|
|
allowed_names["round"] = round
|
|
try:
|
|
result = eval(expr, {"__builtins__": {}}, allowed_names) # noqa: S307
|
|
except Exception as calc_err:
|
|
return {"success": False, "error": f"Could not evaluate expression: {calc_err}"}
|
|
return {"success": True, "type": "calculation", "data": {"expression": expr, "result": result}}
|