Implements the first Claude-like agent for codebase exploration: Core Features: - Explore agent with glob, grep, read, and bash tools - Native PydanticAI tool calling with Ollama/Mistral Nemo - Sanitized Ollama provider (fixes content:null issue) - REST API endpoints for agent execution Tool Infrastructure: - BaseTool abstract class with ToolResult dataclass - ReadFileTool, GlobFilesTool, GrepContentTool, BashReadOnlyTool - Path validation and sandboxing support CLI Client (separate package for future extraction): - webber-cli command with chat, explore, status commands - Communicates with Webber API backend - Rich console output with theming Configuration: - Dev server on port 8095 (production uses 8086) - Mistral Nemo optimizations (temp 0.3, tool_choice required) Tests: 24 tests covering tools and API endpoints Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
76 lines
2.1 KiB
Python
76 lines
2.1 KiB
Python
"""
|
|
Tests for agent REST API endpoints.
|
|
"""
|
|
import pytest
|
|
|
|
|
|
class TestAgentListEndpoint:
|
|
"""Tests for GET /agents/ endpoint."""
|
|
|
|
@pytest.mark.anyio
|
|
async def test_list_agents(self, auth_client):
|
|
"""Test listing available agents."""
|
|
response = await auth_client.get("/agents/")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "agents" in data
|
|
assert len(data["agents"]) >= 1
|
|
|
|
# Check explore agent is present
|
|
agent_names = [a["name"] for a in data["agents"]]
|
|
assert "explore" in agent_names
|
|
|
|
|
|
class TestAgentInfoEndpoint:
|
|
"""Tests for GET /agents/{agent_type} endpoint."""
|
|
|
|
@pytest.mark.anyio
|
|
async def test_get_explore_agent_info(self, auth_client):
|
|
"""Test getting explore agent info."""
|
|
response = await auth_client.get("/agents/explore")
|
|
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["name"] == "explore"
|
|
assert "description" in data
|
|
|
|
@pytest.mark.anyio
|
|
async def test_get_unknown_agent(self, auth_client):
|
|
"""Test getting info for unknown agent."""
|
|
response = await auth_client.get("/agents/nonexistent")
|
|
|
|
assert response.status_code == 404
|
|
|
|
|
|
class TestAgentRunEndpoint:
|
|
"""Tests for POST /agents/run endpoint."""
|
|
|
|
@pytest.mark.anyio
|
|
async def test_run_with_unknown_agent(self, auth_client):
|
|
"""Test running unknown agent type."""
|
|
response = await auth_client.post(
|
|
"/agents/run",
|
|
json={
|
|
"prompt": "test",
|
|
"agent_type": "nonexistent",
|
|
"working_dir": "."
|
|
}
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
assert "Unknown agent" in response.json()["detail"]
|
|
|
|
@pytest.mark.anyio
|
|
async def test_run_request_validation(self, auth_client):
|
|
"""Test request validation."""
|
|
# Missing required field
|
|
response = await auth_client.post(
|
|
"/agents/run",
|
|
json={
|
|
"working_dir": "."
|
|
}
|
|
)
|
|
|
|
assert response.status_code == 422 # Validation error
|