Files
Heimgeist/backend/tests/test_agent_registry.py

72 lines
2.9 KiB
Python
Raw Normal View History

import asyncio
import unittest
from backend.agent.registry import (
NativeToolProvider,
SchemaValidationError,
ToolDefinition,
ToolExecutionContext,
)
INPUT = {
"type": "object",
"properties": {"value": {"type": "string"}},
"required": ["value"],
"additionalProperties": False,
}
OUTPUT = {
"type": "object",
"properties": {"result": {"type": "string"}},
"required": ["result"],
"additionalProperties": False,
}
def context(registry):
return ToolExecutionContext(
run_id="run", workflow_id="workflow", node_id="node", session_id=None,
selection_mode="explicit", explicit_user_action=True,
emit=lambda *_args: asyncio.sleep(0), cancellation_event=asyncio.Event(),
db_factory=lambda: None, registry=registry,
)
class RegistryTests(unittest.IsolatedAsyncioTestCase):
async def test_duplicate_names_are_rejected(self):
async def handler(arguments, _context): return {"result": arguments["value"]}
registry = NativeToolProvider()
definition = ToolDefinition("test.echo", "echo", INPUT, OUTPUT, handler)
registry.register(definition)
with self.assertRaises(ValueError):
registry.register(definition)
async def test_arguments_and_outputs_are_validated(self):
async def handler(arguments, _context): return {"result": arguments["value"]}
registry = NativeToolProvider()
registry.register(ToolDefinition("test.echo", "echo", INPUT, OUTPUT, handler))
self.assertEqual((await registry.call_tool("test.echo", {"value": "ok"}, context(registry)))["result"], "ok")
with self.assertRaises(SchemaValidationError):
await registry.call_tool("test.echo", {"value": 1}, context(registry))
async def invalid_output(_arguments, _context): return {"result": 1}
invalid = NativeToolProvider()
invalid.register(ToolDefinition("test.invalid", "invalid", INPUT, OUTPUT, invalid_output))
with self.assertRaises(SchemaValidationError):
await invalid.call_tool("test.invalid", {"value": "x"}, context(invalid))
async def test_timeout_and_result_size_are_enforced(self):
async def slow(_arguments, _context):
await asyncio.sleep(0.05)
return {"result": "ok"}
registry = NativeToolProvider()
registry.register(ToolDefinition("test.slow", "slow", INPUT, OUTPUT, slow, timeout_seconds=0.01))
with self.assertRaises(TimeoutError):
await registry.call_tool("test.slow", {"value": "x"}, context(registry))
async def large(_arguments, _context): return {"result": "x" * 100}
limited = NativeToolProvider()
limited.register(ToolDefinition("test.large", "large", INPUT, OUTPUT, large, result_size_limit=20))
with self.assertRaises(ValueError):
await limited.call_tool("test.large", {"value": "x"}, context(limited))