diff --git a/api/app/routers/tools.py b/api/app/routers/tools.py index 7d6291f..79f24e9 100644 --- a/api/app/routers/tools.py +++ b/api/app/routers/tools.py @@ -109,12 +109,6 @@ TOOL_ICON_MAP = { } TOOL_HTTP_DEFAULTS = { - "current_time": { - "http_method": "GET", - "http_url": "https://worldtimeapi.org/api/ip", - "http_headers": {}, - "http_timeout_ms": 10000, - }, } @@ -126,7 +120,7 @@ def _normalize_http_method(method: Optional[str]) -> str: def _requires_http_request(category: str, tool_id: Optional[str]) -> bool: if category != "query": return False - return str(tool_id or "").strip() not in {"calculator", "code_interpreter"} + return str(tool_id or "").strip() not in {"calculator", "code_interpreter", "current_time"} def _validate_query_http_config(*, category: str, tool_id: Optional[str], http_url: Optional[str]) -> None: diff --git a/engine/core/tool_executor.py b/engine/core/tool_executor.py index 97d4c3d..407e199 100644 --- a/engine/core/tool_executor.py +++ b/engine/core/tool_executor.py @@ -3,6 +3,7 @@ import asyncio import ast import operator +from datetime import datetime from typing import Any, Dict import aiohttp @@ -241,7 +242,21 @@ async def execute_server_tool(tool_call: Dict[str, Any]) -> Dict[str, Any]: "status": {"code": 422, "message": "invalid_code"}, } - if tool_name and tool_name not in {"calculator", "code_interpreter"}: + if tool_name == "current_time": + now = datetime.now().astimezone() + return { + "tool_call_id": call_id, + "name": tool_name, + "output": { + "local_time": now.strftime("%Y-%m-%d %H:%M:%S"), + "iso": now.isoformat(), + "timezone": str(now.tzinfo or ""), + "timestamp": int(now.timestamp()), + }, + "status": {"code": 200, "message": "ok"}, + } + + if tool_name and tool_name not in {"calculator", "code_interpreter", "current_time"}: resource = await fetch_tool_resource(tool_name) if resource and str(resource.get("category") or "") == "query": method = str(resource.get("http_method") or "GET").strip().upper() diff --git a/engine/tests/test_tool_executor.py b/engine/tests/test_tool_executor.py index a6bde28..17345c7 100644 --- a/engine/tests/test_tool_executor.py +++ b/engine/tests/test_tool_executor.py @@ -31,3 +31,27 @@ async def test_code_interpreter_blocks_import_and_io(): ) assert result["status"]["code"] == 422 assert result["status"]["message"] == "invalid_code" + + +@pytest.mark.asyncio +async def test_current_time_uses_local_system_clock(monkeypatch): + async def _should_not_be_called(_tool_id): + raise AssertionError("fetch_tool_resource should not be called for current_time") + + monkeypatch.setattr("core.tool_executor.fetch_tool_resource", _should_not_be_called) + + result = await execute_server_tool( + { + "id": "call_time_ok", + "function": { + "name": "current_time", + "arguments": "{}", + }, + } + ) + + assert result["status"]["code"] == 200 + assert result["status"]["message"] == "ok" + assert "local_time" in result["output"] + assert "iso" in result["output"] + assert "timestamp" in result["output"]