Add agent interface and model implementations

Implements Phase 1: Agent abstraction layer with multiple model support

Features:
- Abstract AgentInterface base class with standard contract
- LoremTesterAgent: Full-featured mock agent with realistic behavior
  - Configurable reasoning effort levels (none to xhigh)
  - Random tool/function call generation
  - Error triggers for testing (rate_limit, context_overflow)
  - Temperature-based response variation
- TatlockAgent: Placeholder for future PydanticAI integration
- ModelRegistry: Centralized model management and discovery

Testing:
- 9 unit tests for lorem-tester agent behavior
- 9 unit tests for registry operations
- Coverage: Agent abstraction fully tested

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-06 19:36:53 +01:00
co-authored by Claude
parent 62edb111bd
commit 4e6ca4466b
8 changed files with 975 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
"""
Tatlock agent - Placeholder for future real agent.
This is a minimal placeholder implementation. In the future, this will
be the production agent using PydanticAI and Ollama for real LLM inference.
For now, it returns a simple placeholder message to show up in the
model list and allow basic testing.
"""
import secrets
from typing import AsyncGenerator, Any
from src.agents.base import AgentInterface, OutputItem
def generate_id() -> str:
"""Generate unique ID for output items."""
return secrets.token_hex(16)
class TatlockAgent(AgentInterface):
"""
Placeholder for future Tatlock reasoning agent.
TODO: Integrate PydanticAI and Ollama for real LLM inference
TODO: Implement memory modules
TODO: Implement expert modules
TODO: Add reasoning/thinking capabilities
TODO: Add tool/function calling
"""
async def generate_response(
self,
messages: list[dict],
reasoning: dict | None = None,
tools: list[dict] | None = None,
temperature: float = 1.0,
max_tokens: int | None = None,
stop: list[str] | None = None,
**kwargs: Any
) -> AsyncGenerator[OutputItem, None]:
"""
Generate minimal placeholder response.
In the future, this will call PydanticAI with Ollama backend.
"""
# Simple placeholder message
yield OutputItem(
type="message",
id=f"msg_{generate_id()}",
role="assistant",
content=[{
"type": "output_text",
"text": "Tatlock agent is not yet implemented. Please use lorem-tester for testing.",
"annotations": []
}],
status="completed"
)
async def supports_tools(self) -> bool:
"""Tools not yet implemented."""
return False
async def supports_reasoning(self) -> bool:
"""Reasoning not yet implemented."""
return False
async def get_capabilities(self) -> dict:
"""Return minimal capabilities."""
return {
"streaming": True, # Basic streaming works
"reasoning": False, # Not yet implemented
"tools": False, # Not yet implemented
"vision": False, # Future
"audio": False, # Future
}