Add comprehensive two-tier architecture where Steward analyzes requests and Tatlock executes with scoped tools. Includes full infrastructure for request preprocessing, tool tracking, benchmarking, and streaming. **Added:** - Steward agent for request analysis and capability recommendation - Household Registry for centralized capability management - Request preprocessing pipeline (Steward → Tatlock flow) - Tool usage tracking and benchmarking system - Streaming transparency (Steward reasoning visible in streams) - Structured logging with operation timing - Redis benchmark storage with 30-day expiry - Benchmark analysis CLI tools **Infrastructure:** - src/agents/steward/ - Steward agent implementation - src/agents/tatlock_core/ - Tatlock capability domain - src/core/preprocessing.py - Request preprocessing pipeline - src/core/tool_tracking.py - Tool call tracking - src/core/benchmarks.py - Benchmark recording system - src/core/household_registry.py - Capability registry - src/core/startup.py - Application startup coordination - src/core/logging_config.py - Structured logging setup **Integration:** - Responses API uses Steward for Tatlock requests - Chat Completions wraps Responses API for OpenAI compatibility - Streaming coordinator supports Steward + Tatlock flow - Tool scoping per request based on Steward recommendations **Testing:** - Integration tests for Steward-Tatlock flow - Benchmark and registry unit tests - Steward streaming tests See PHASE2_PLAN.md and PHASE2_COMPLETE.md for detailed documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
167 lines
6.2 KiB
Python
167 lines
6.2 KiB
Python
"""
|
|
Tests for Steward schemas.
|
|
|
|
Tests the structured output models for conversation context and recommendations.
|
|
"""
|
|
import pytest
|
|
|
|
from src.agents.steward.schemas import ConversationContext, StewardRecommendation
|
|
|
|
|
|
class TestConversationContext:
|
|
"""Test ConversationContext model."""
|
|
|
|
def test_context_creation_with_defaults(self):
|
|
"""Test creating context with default values."""
|
|
context = ConversationContext(has_previous_context=False)
|
|
|
|
assert context.has_previous_context is False
|
|
assert context.relevant_turns == []
|
|
assert context.context_summary == ""
|
|
|
|
def test_context_creation_with_values(self):
|
|
"""Test creating context with explicit values."""
|
|
context = ConversationContext(
|
|
has_previous_context=True,
|
|
relevant_turns=[0, 2, 4],
|
|
context_summary="User discussed weather in turns 0 and 2"
|
|
)
|
|
|
|
assert context.has_previous_context is True
|
|
assert context.relevant_turns == [0, 2, 4]
|
|
assert "weather" in context.context_summary
|
|
|
|
|
|
class TestStewardRecommendation:
|
|
"""Test StewardRecommendation model."""
|
|
|
|
def test_recommendation_simple(self):
|
|
"""Test simple recommendation with no capabilities needed."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=[],
|
|
reasoning="Simple greeting requires no tools",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
)
|
|
|
|
assert rec.recommended_capabilities == []
|
|
assert rec.estimated_complexity == "simple"
|
|
assert rec.missing_capabilities is None
|
|
|
|
def test_recommendation_with_capabilities(self):
|
|
"""Test recommendation with specific capabilities."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=["tatlock_core"],
|
|
reasoning="Mathematical calculation requires calculator",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
)
|
|
|
|
assert "tatlock_core" in rec.recommended_capabilities
|
|
assert rec.estimated_complexity == "simple"
|
|
|
|
def test_recommendation_with_missing_capabilities(self):
|
|
"""Test recommendation noting missing capabilities."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=[],
|
|
reasoning="Image generation is not available",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
missing_capabilities="Image generation capability would be needed",
|
|
)
|
|
|
|
assert rec.missing_capabilities is not None
|
|
assert "Image generation" in rec.missing_capabilities
|
|
|
|
def test_recommendation_complexity_levels(self):
|
|
"""Test all complexity levels."""
|
|
for complexity in ["simple", "moderate", "complex"]:
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=[],
|
|
reasoning=f"Testing {complexity} complexity",
|
|
estimated_complexity=complexity,
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
)
|
|
assert rec.estimated_complexity == complexity
|
|
|
|
def test_recommendation_with_context(self):
|
|
"""Test recommendation with conversation context."""
|
|
context = ConversationContext(
|
|
has_previous_context=True,
|
|
relevant_turns=[1, 3],
|
|
context_summary="User asked about calculation in turn 1, now wants explanation"
|
|
)
|
|
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=["tatlock_core"],
|
|
reasoning="User wants explanation of previous calculation",
|
|
estimated_complexity="moderate",
|
|
conversation_context=context,
|
|
)
|
|
|
|
assert rec.conversation_context.has_previous_context is True
|
|
assert len(rec.conversation_context.relevant_turns) == 2
|
|
|
|
def test_format_for_butler_simple(self):
|
|
"""Test formatting recommendation for Butler - simple case."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=["tatlock_core"],
|
|
reasoning="Math calculation needed",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
)
|
|
|
|
formatted = rec.format_for_butler()
|
|
|
|
assert "📋 Steward's Analysis" in formatted
|
|
assert "SIMPLE" in formatted
|
|
assert "tatlock_core" in formatted
|
|
|
|
def test_format_for_butler_with_context(self):
|
|
"""Test formatting with conversation context."""
|
|
context = ConversationContext(
|
|
has_previous_context=True,
|
|
relevant_turns=[0],
|
|
context_summary="Previous calculation mentioned"
|
|
)
|
|
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=["tatlock_core"],
|
|
reasoning="Follow-up calculation",
|
|
estimated_complexity="moderate",
|
|
conversation_context=context,
|
|
)
|
|
|
|
formatted = rec.format_for_butler()
|
|
|
|
assert "Context:" in formatted
|
|
assert "Previous calculation" in formatted
|
|
|
|
def test_format_for_butler_with_missing_capabilities(self):
|
|
"""Test formatting with missing capabilities warning."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=[],
|
|
reasoning="No suitable tools available",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
missing_capabilities="Image generation would be needed",
|
|
)
|
|
|
|
formatted = rec.format_for_butler()
|
|
|
|
assert "⚠️ Missing:" in formatted
|
|
assert "Image generation" in formatted
|
|
|
|
def test_format_for_butler_no_capabilities(self):
|
|
"""Test formatting when no tools needed (conversational)."""
|
|
rec = StewardRecommendation(
|
|
recommended_capabilities=[],
|
|
reasoning="Simple greeting",
|
|
estimated_complexity="simple",
|
|
conversation_context=ConversationContext(has_previous_context=False),
|
|
)
|
|
|
|
formatted = rec.format_for_butler()
|
|
|
|
assert "None (conversational response)" in formatted
|