cortex.6.sol / tests /test_tools.py
asdfasdfqrqwer's picture
feat(cortex-ai): agent engine, tool registry, OpenAI-compatible API, fine-tuning pipeline
c63bc31
Raw History Blame Contribute Delete
3.57 kB
"""Tests for the tool registry."""
import pytest
from cortex_ai.tools import ToolError, ToolRegistry, default_registry, registry_from_names, tool
def test_default_registry_exposes_expected_tools():
reg = default_registry()
assert set(reg.names()) == {"calculate", "cortex_identity", "current_time", "text_stats"}
assert len(reg) == 4
def test_openai_schema_shape():
reg = default_registry()
schemas = {s["function"]["name"]: s for s in reg.to_openai_schemas()}
calc = schemas["calculate"]
assert calc["type"] == "function"
assert calc["function"]["parameters"]["type"] == "object"
assert calc["function"]["parameters"]["properties"]["expression"]["type"] == "string"
assert calc["function"]["parameters"]["required"] == ["expression"]
def test_calculate_returns_the_right_value():
reg = default_registry()
assert reg.call("calculate", {"expression": "2*(3+4)"}) == "14"
assert reg.call("calculate", {"expression": "10/4"}) == "2.5"
def test_calculate_rejects_non_arithmetic_input():
reg = default_registry()
# A rejected expression surfaces as an ERROR string, not an exception: the
# model must be able to read the failure and react to it.
assert reg.call("calculate", {"expression": "__import__('os')"}).startswith("ERROR:")
assert reg.call("calculate", {"expression": "9**9**9"}).startswith("ERROR:")
assert "exponentiation" in reg.call("calculate", {"expression": "9**9**9"})
assert reg.call("calculate", {"expression": "1/0"}).startswith("ERROR:")
def test_calculate_rejects_oversized_input():
reg = default_registry()
assert reg.call("calculate", {"expression": "1+" * 200 + "1"}).startswith("ERROR:")
def test_arguments_may_be_a_json_string():
reg = default_registry()
assert reg.call("calculate", '{"expression": "3+4"}') == "7"
def test_unknown_tool_raises():
reg = default_registry()
with pytest.raises(ToolError, match="unknown tool"):
reg.call("does_not_exist", {})
def test_missing_required_argument_raises():
reg = default_registry()
with pytest.raises(ToolError, match="missing required argument"):
reg.call("calculate", {})
def test_unknown_argument_raises():
reg = default_registry()
with pytest.raises(ToolError, match="unknown argument"):
reg.call("calculate", {"expression": "1+1", "bogus": 1})
def test_invalid_json_arguments_raise():
reg = default_registry()
with pytest.raises(ToolError, match="not valid JSON"):
reg.call("calculate", "{not json")
def test_registry_from_names_restricts_and_orders():
reg = registry_from_names(["text_stats", "calculate"])
assert reg.names() == ["calculate", "text_stats"]
def test_registry_from_empty_names_returns_everything():
assert len(registry_from_names([])) == 4
def test_cortex_identity_tool_reports_project_attribution():
from cortex_ai.identity import IDENTITY_STATEMENT
assert default_registry().call("cortex_identity", {}) == IDENTITY_STATEMENT
def test_custom_tool_via_decorator():
@tool(description="Ajoute deux entiers.")
def ajouter(a: int, b: int) -> str:
return str(a + b)
reg = ToolRegistry([ajouter])
assert reg.names() == ["ajouter"]
assert reg.call("ajouter", {"a": 2, "b": 3}) == "5"
assert reg.to_openai_schemas()[0]["function"]["parameters"]["required"] == ["a", "b"]
def test_tool_returning_a_dict_is_json_encoded():
reg = default_registry()
out = reg.call("text_stats", {"text": "un deux trois"})
assert '"mots": 3' in out