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>
94 lines
3.0 KiB
Python
94 lines
3.0 KiB
Python
"""
|
|
Steward agent schemas.
|
|
|
|
Defines the structured output models for Steward's request analysis
|
|
and capability recommendations.
|
|
"""
|
|
from typing import Literal, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ConversationContext(BaseModel):
|
|
"""
|
|
Contextual information extracted from conversation history.
|
|
|
|
The Steward analyzes the full conversation to identify references
|
|
to previous topics, helping the Butler maintain context.
|
|
"""
|
|
has_previous_context: bool = Field(
|
|
description="Whether the current request references previous conversation turns"
|
|
)
|
|
relevant_turns: list[int] = Field(
|
|
default_factory=list,
|
|
description="0-indexed turn numbers that are relevant to the current request"
|
|
)
|
|
context_summary: str = Field(
|
|
default="",
|
|
description="Brief summary of relevant context for the Butler"
|
|
)
|
|
|
|
|
|
class StewardRecommendation(BaseModel):
|
|
"""
|
|
Structured recommendation from Steward's request analysis.
|
|
|
|
This is the output format for the Steward agent, providing:
|
|
- Which household capabilities are needed
|
|
- Why those capabilities were chosen
|
|
- Complexity assessment
|
|
- Conversation context
|
|
- Missing capabilities (if any)
|
|
"""
|
|
recommended_capabilities: list[str] = Field(
|
|
description="List of household member names to include (e.g., ['tatlock_core'])"
|
|
)
|
|
reasoning: str = Field(
|
|
description="Explanation of why these capabilities were recommended"
|
|
)
|
|
estimated_complexity: Literal["simple", "moderate", "complex"] = Field(
|
|
description="Complexity assessment: simple (1 tool), moderate (2-3 tools), complex (multiple tools/steps)"
|
|
)
|
|
conversation_context: ConversationContext = Field(
|
|
description="Contextual information from conversation history"
|
|
)
|
|
missing_capabilities: Optional[str] = Field(
|
|
default=None,
|
|
description="Description of capabilities that would be helpful but aren't available"
|
|
)
|
|
|
|
def format_for_butler(self) -> str:
|
|
"""
|
|
Format recommendation as a note for the Butler.
|
|
|
|
Returns:
|
|
Formatted string suitable for prepending to user request
|
|
"""
|
|
lines = []
|
|
|
|
# Header
|
|
lines.append("📋 Steward's Analysis")
|
|
lines.append("=" * 40)
|
|
|
|
# Complexity
|
|
lines.append(f"Complexity: {self.estimated_complexity.upper()}")
|
|
|
|
# Recommended capabilities
|
|
if self.recommended_capabilities:
|
|
caps = ", ".join(self.recommended_capabilities)
|
|
lines.append(f"Recommended tools: {caps}")
|
|
else:
|
|
lines.append("Recommended tools: None (conversational response)")
|
|
|
|
# Context summary
|
|
if self.conversation_context.has_previous_context:
|
|
lines.append(f"Context: {self.conversation_context.context_summary}")
|
|
|
|
# Missing capabilities warning
|
|
if self.missing_capabilities:
|
|
lines.append(f"⚠️ Missing: {self.missing_capabilities}")
|
|
|
|
lines.append("=" * 40)
|
|
|
|
return "\n".join(lines)
|