from __future__ import annotations import tempfile import unittest from pathlib import Path from src.agent_tools import build_tool_context, default_tool_registry, execute_tool from src.agent_types import AgentPermissions, AgentRuntimeConfig from src.lsp_runtime import LSPRuntime class ExtendedToolTests(unittest.TestCase): def test_web_fetch_rejects_file_url(self) -> None: """Verify that file:// URLs are blocked to prevent SSRF attacks.""" with tempfile.TemporaryDirectory() as tmp_dir: workspace = Path(tmp_dir) target = workspace / 'page.txt' target.write_text('hello from web fetch\n', encoding='utf-8') context = build_tool_context( AgentRuntimeConfig(cwd=workspace), tool_registry=default_tool_registry(), ) result = execute_tool( default_tool_registry(), 'web_fetch', {'url': target.resolve().as_uri()}, context, ) self.assertFalse(result.ok) self.assertIn('http or https', result.content) def test_tool_search_lists_matching_tools(self) -> None: registry = default_tool_registry() with tempfile.TemporaryDirectory() as tmp_dir: context = build_tool_context( AgentRuntimeConfig(cwd=Path(tmp_dir)), tool_registry=registry, ) result = execute_tool( registry, 'tool_search', {'query': 'file'}, context, ) self.assertTrue(result.ok) self.assertIn('# Tool Search', result.content) self.assertIn('read_file', result.content) self.assertIn('write_file', result.content) def test_sleep_tool_waits_briefly_and_returns_metadata(self) -> None: registry = default_tool_registry() with tempfile.TemporaryDirectory() as tmp_dir: context = build_tool_context( AgentRuntimeConfig(cwd=Path(tmp_dir)), tool_registry=registry, ) result = execute_tool( registry, 'sleep', {'seconds': 0.01}, context, ) self.assertTrue(result.ok) self.assertIn('slept for', result.content) self.assertEqual(result.metadata.get('action'), 'sleep') def test_notebook_edit_updates_ipynb_cell(self) -> None: registry = default_tool_registry() with tempfile.TemporaryDirectory() as tmp_dir: workspace = Path(tmp_dir) notebook = workspace / 'demo.ipynb' notebook.write_text( '{\n' ' "cells": [\n' ' {"cell_type": "code", "metadata": {}, "source": ["print(1)\\n"], "outputs": [], "execution_count": null}\n' ' ],\n' ' "metadata": {},\n' ' "nbformat": 4,\n' ' "nbformat_minor": 5\n' '}\n', encoding='utf-8', ) context = build_tool_context( AgentRuntimeConfig( cwd=workspace, permissions=AgentPermissions(allow_file_write=True), ), tool_registry=registry, ) result = execute_tool( registry, 'notebook_edit', {'path': 'demo.ipynb', 'cell_index': 0, 'source': 'print(2)\n'}, context, ) updated = notebook.read_text(encoding='utf-8') self.assertTrue(result.ok) self.assertIn('updated notebook cell 0', result.content) self.assertIn('print(2)', updated) self.assertEqual(result.metadata.get('action'), 'notebook_edit') def test_lsp_tool_returns_definition_report(self) -> None: registry = default_tool_registry() with tempfile.TemporaryDirectory() as tmp_dir: workspace = Path(tmp_dir) (workspace / 'sample.py').write_text( 'def helper(value):\n' ' return value * 2\n' '\n' 'def run(item):\n' ' return helper(item)\n', encoding='utf-8', ) context = build_tool_context( AgentRuntimeConfig(cwd=workspace), tool_registry=registry, lsp_runtime=LSPRuntime.from_workspace(workspace), ) result = execute_tool( registry, 'LSP', { 'operation': 'goToDefinition', 'file_path': 'sample.py', 'line': 5, 'character': 12, }, context, ) self.assertTrue(result.ok) self.assertIn('# LSP Definition', result.content) self.assertIn('function helper', result.content) self.assertEqual(result.metadata.get('action'), 'lsp_query') self.assertEqual(result.metadata.get('operation'), 'goToDefinition')