Move web search functionality to The Librarian agent, integrating with
the library-desk /rag/search endpoint for enhanced search capabilities.
Changes:
- Add search_web, read_url, read_urls_batch tools to Librarian
- Add WebSearchResult, ContentExtractionResult models to client
- Add search_web, extract_content, extract_content_batch client methods
- Update Librarian capability with web/url/internet domains
- Remove search_web from tatlock_core tools and toolset
- Update Tatlock system prompt to delegate web search to Librarian
- Add comprehensive unit tests for new Librarian tools
- Clean up legacy src/agents/tools.py
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two-Phase Tatlock Execution:
- orchestrate_tool_calls() for Phase 1 coordination
- synthesize_from_results() for Phase 2 butler-toned synthesis
- Guarantees butler personality in all responses
Automatic Think Slugs:
- Deterministic butler-perspective messages during expert delegation
- ActionType enum: RETRIEVE, RESEARCH, CREATE, CONTROL, RECORD
- HOUSEHOLD_THINK_MESSAGES mapping for all experts
- Streaming delegation wrappers with automatic think messages
Steward Query Enrichment:
- Auto-fill user context (location, timezone) when not specified
- _build_enriched_query() with regex word boundary matching
- enriched_query field in StewardRecommendation schema
Documentation:
- ORCHESTRATION_SCENARIOS.md rewritten with Mermaid diagrams
- New Housekeeper and Biographer scenarios
- TESTING_IMPROVEMENTS.md for future LLM testing patterns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements The Housekeeper, a new expert agent for home automation
following the Librarian pattern. Communicates with core-api service
which wraps Home Assistant REST API.
New agent features:
- CoreAPIClient with 13 home automation methods
- 13 tools: list_areas, list_devices, get_device_state, turn_on,
turn_off, toggle, list_scenes, activate_scene, list_scripts,
run_script, list_automations, toggle_automation, get_history
- PydanticAI agent with butler-friendly system prompt
- HouseholdCapability registration for Steward coordination
- delegate_to_housekeeper() wrapper for orchestration
Also includes:
- Dev port changed from 8123 to 8777 (avoids Home Assistant conflict)
- Config: CORE_API_HOST, CORE_API_KEY, CORE_API_TIMEOUT
- 44 unit tests for client and capability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
### Added
- Environment-aware configuration:
- Auto-selected logging (DEBUG for dev, WARNING for prod)
- Auto-selected default user (llm_tester for dev isolation)
- User context logging at request entry
- Direct delegation bypass:
- Pure memory/librarian requests skip Tatlock LLM
- Reduces latency for memory-only requests
- Text-based delegation fallback:
- Parse [DELEGATE:agent] patterns from LLM output
- Sequential and parallel execution support
- Comprehensive E2E test suite:
- 22 orchestration tests with QdrantVerifier
- assert_llm_behavior() for flexible pattern matching
- Tests for memory, delegation, isolation, scenarios
### Fixed
- Unit test mocks for streaming (async generator)
- Temporal context handling in tests
- LLM non-determinism with pytest.xfail()
- Streaming test timeouts increased
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change `str | None` to `str` with empty default for memory_type
- Remove `keywords` parameter from store_insight (auto-generated anyway)
- Ollama's OpenAI API doesn't handle union types with None properly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add The Biographer household member for user memory management:
Memory Service (direct access layer):
- src/core/memory_service.py for fast, LLM-free lookups
- Profile, preference, and fact management
- Session context with Redis caching
- Steward integration via prefetch_context()
The Biographer Agent:
- src/agents/biographer/ package with PydanticAI agent
- Discreet chronicler personality for privacy
- Tools: recall_semantic, list_memories, store_insight,
update_profile, update_preference, forget_memory
- Registered with Household Registry on startup
Steward Integration:
- Memory context pre-fetch during analysis
- Profile/preferences included in Butler note
- Keyword-based context determination
Also includes:
- delegate_to_biographer() wrapper
- 34 new tests (capability + memory service)
- Version bump to 1.2.0
Documentation cleanup:
- Removed obsolete PHASE2_COMPLETE.md, PHASE2_PLAN.md
- Removed docs/library-desk-requirements.md
- Moved ORCHESTRATION_SCENARIOS.md to project root
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds multi-expert coordination infrastructure:
- ExecutionMode enum (SEQUENTIAL, PARALLEL)
- MultiExpertResult dataclass for aggregating results
- execute_sequential(): Tasks run one after another
- execute_parallel(): Tasks run concurrently via asyncio.gather
- orchestrate_multi_expert(): Streaming think updates during multi-expert work
Supports:
- Stop-on-failure mode for sequential execution
- Partial failure handling (some succeed, some fail)
- Result aggregation with combined output formatting
- Exception handling in parallel execution
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Creates orchestration module for multi-expert coordination:
- parse_delegation_from_steward_note(): Extracts delegation task
- execute_delegation(): Routes to appropriate expert agent
- orchestrate_with_think_updates(): Streams <think> updates around
delegation calls while using run() internally
This enables real-time user feedback while avoiding Ollama's
streaming+tool call bugs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Updates Steward's output format to structured delegation format:
- DELEGATE: [capability] to [action] [task]
- REASON: [explanation]
- COMPLEXITY: [simple/moderate/complex]
- CONTEXT: [relevant history or "none"]
Also adds guidance for conversation memory queries (handled by
Tatlock directly, not delegated to Librarian).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces agent-as-tool pattern infrastructure:
- DelegationTask: Structured representation of expert work
- DelegationResult: Typed result from expert delegation
- delegate_to_librarian(): Wrapper for Librarian agent calls
This implements PydanticAI's recommended delegation pattern where
parent agents call child agents via tool wrappers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PydanticAI + Ollama streaming with tool calls has known issues:
- Issue #1292: Streaming stops after tool call due to empty TextPart
- Issue #2256: Empty text part causes run to end prematurely
This change uses run() for the actual tool execution while still
yielding the response in chunks to maintain the streaming UX.
The orchestration loop can emit <think> updates between await calls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update Librarian capability description to highlight CREATE/UPDATE/SEARCH
- Add specific Steward guidelines for wiki creation, updates, and research
- Add dynamic time injection to user prompts for temporal awareness
- Expand domains to include 'create', 'write', 'update'
- Update test to match new capability description
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- CoordinationEngine for task orchestration between agents
- Routing tasks to appropriate expert agents
- Sequential and parallel execution support
- Result aggregation from multiple agents
- Graceful error handling and degradation
- Streaming delegation support
- Convenience functions: delegate_to_librarian(), delegate_to_librarian_stream()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Library-Desk API Client:
- Async HTTP client with httpx for library-desk API
- HybridRAG search (vector + graph + web)
- Wiki operations (search, get, list, create, update)
- Smart page creation with HybridRAG research
- Semantic vector search and knowledge graph queries
- Dossier browsing and health checks
Librarian Tools (11 total):
- Research: hybrid_search, search_wiki, get_wiki_page, semantic_search
- Browse: list_dossiers, get_dossier_pages, explore_knowledge_graph
- Graph: find_related_entities
- Write: create_wiki_page, update_wiki_page, smart_create_wiki_page
Agent:
- PydanticAI agent with research assistant personality
- System prompt with research and writing workflows
- Streaming support via run_librarian_stream()
Capability:
- LIBRARIAN_CAPABILITY definition for Household Registry
- Automatic registration on startup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix streaming issues that caused text repetition and broken tool execution
in Open WebUI. Implements real LLM streaming using PydanticAI's run_stream()
with delta=True instead of artificial word-by-word chunking.
**Fixed:**
- Text repetition in streaming output (was accumulating instead of deltas)
- Broken tool execution (tools now execute properly in streaming mode)
- Invalid 'thinking' parameter in ReasoningOutputItem schema
**Changes:**
- Add run_with_scoped_tools_stream() method to TatlockAgent
- Uses PydanticAI's run_stream() with delta=True for real deltas
- Properly streams LLM output with tool execution
- Update StreamingCoordinator.stream_response_with_steward()
- Uses new streaming method instead of fake word-by-word streaming
- Removes invalid thinking parameter from ReasoningOutputItem
- All streaming now uses actual LLM deltas, not accumulated text
Resolves streaming issues reported in Open WebUI where responses showed
repetitive text and tool calls appeared as raw JSON instead of executed results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add two major features to enhance Tatlock's capabilities:
1. Conversation History Support:
- Convert OpenAI-format messages to PydanticAI ModelRequest/ModelResponse
- Pass full conversation context via message_history parameter
- Filter empty messages to prevent Ollama errors
- Add debug logging for message history construction
- Tatlock now remembers previous turns in multi-turn conversations
2. Tool Call Logging:
- Implement ToolCallTracker dependency for per-request tracking
- Tools log usage via RunContext deps parameter
- Web search: "🔍 Searching for: 'query'"
- Calculator: "🧮 Calculating: expression"
- Date/time: "🕐 Calculating date offset: description"
- Tool logs appear in reasoning output as <think> tags in Open WebUI
Both features improve user experience by maintaining conversation context
and providing transparency into tool usage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Convert Tatlock from mock to real PydanticAI agent:
- Connect to Ollama backend (mistral-nemo:latest)
- British butler personality with research-oriented mindset
- Lazy initialization pattern for better testability
- Register permanent tools (calculator, date/time, search)
- Streaming response support with reasoning output
- Error handling for PydanticAI exceptions
- Update registry tests for tools capability
- Add integration test for streaming functionality
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>