fix: complete web search integration with query enrichment
Build and Push / build (release) Successful in 52s

Fixes several issues with the web search migration to Librarian:

- Update Steward routing guidelines for web search/weather → Librarian
- Register search_web, read_url, read_urls_batch tools with Librarian agent
- Update Librarian system prompt with web search documentation
- Fix query enrichment not being passed to delegations (location context)
- Add URL reading keywords to RESEARCH action type detection

Weather queries now automatically include user's stored location from
the Biographer, enabling location-aware search results.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-15 22:51:18 +01:00
co-authored by Claude Opus 4.5
parent add9b74207
commit 74f47097c2
6 changed files with 58 additions and 9 deletions
+23
View File
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [1.8.0] - 2025-12-15
### Fixed
#### Steward Routing for Web Search
- Updated Steward guidelines to route web searches, weather, news → Librarian with `search_web`
- Added URL/article reading → Librarian with `read_url` to routing guidelines
- Added examples showing `search_web` and `read_url` tool usage
#### Librarian Agent Tool Registration
- Registered `search_web`, `read_url`, `read_urls_batch` tools with the Librarian PydanticAI agent
- Updated Librarian system prompt with Web Search & Content Extraction section
- Fixed tool count in agent logger (11 → 14 tools)
#### Query Enrichment Integration
- Fixed enriched query (with location/timezone context) not being passed to delegations
- Response service now uses `enriched_query` from Steward recommendation for all delegations
- Weather queries now automatically include user's stored location
#### Action Type Detection
- Added "read", "fetch", "url", "http" keywords to RESEARCH action type for Librarian
- Ensures proper think messages for URL reading tasks
## [1.7.0] - 2025-12-15
### Added
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "tatlock"
version = "1.7.0"
version = "1.8.0"
description = "OpenAI-compatible API with Ollama backend"
requires-python = ">=3.12"
dependencies = []
+3
View File
@@ -100,10 +100,13 @@ def _detect_action_type(expert: str, task: str) -> ActionType:
task_lower = task.lower()
if expert == "librarian":
# Web search, URL reading = RESEARCH (fresh external data)
if any(w in task_lower for w in ["search", "find", "look up", "research"]):
if any(w in task_lower for w in ["web", "online", "internet"]):
return ActionType.RESEARCH
return ActionType.RETRIEVE
if any(w in task_lower for w in ["read", "fetch", "url", "http"]):
return ActionType.RESEARCH # Reading URLs is research
if any(w in task_lower for w in ["create", "write", "add", "make", "new"]):
return ActionType.CREATE
return ActionType.RETRIEVE
+21 -4
View File
@@ -19,6 +19,9 @@ from src.agents.librarian.tools import (
get_wiki_page,
hybrid_search,
list_dossiers,
read_url,
read_urls_batch,
search_web,
search_wiki,
semantic_search,
smart_create_wiki_page,
@@ -47,8 +50,17 @@ Your role is to help users find, understand, synthesize, and manage information
## Your Tools
### Research Tools
- **hybrid_search**: Your primary research tool - searches all sources at once
### Web Search & Content Extraction
- **search_web**: Search the internet for current information (weather, news, facts)
- Use for: weather forecasts, current events, recent developments, external facts
- Returns extracted content from search results, not just snippets
- **read_url**: Read and extract content from a specific URL
- Use when: user provides a URL or you need to read a specific webpage
- **read_urls_batch**: Read multiple URLs in parallel (up to 20)
- Use for: comparing multiple sources, gathering info from several pages
### Internal Research Tools
- **hybrid_search**: Your primary research tool - searches wiki, graph, and web at once
- **search_wiki**: Find specific wiki pages by keyword
- **semantic_search**: Find conceptually similar content
- **explore_knowledge_graph** / **find_related_entities**: Discover connections
@@ -130,7 +142,7 @@ def _create_librarian_agent() -> Agent[None, str]:
retries=2,
)
# Register research tools
# Register research tools (internal knowledge)
agent.tool_plain(hybrid_search)
agent.tool_plain(search_wiki)
agent.tool_plain(semantic_search)
@@ -139,6 +151,11 @@ def _create_librarian_agent() -> Agent[None, str]:
agent.tool_plain(explore_knowledge_graph)
agent.tool_plain(find_related_entities)
# Register web search & content extraction tools
agent.tool_plain(search_web)
agent.tool_plain(read_url)
agent.tool_plain(read_urls_batch)
# Register wiki read tools
agent.tool_plain(get_wiki_page)
@@ -150,7 +167,7 @@ def _create_librarian_agent() -> Agent[None, str]:
logger.info(
"librarian_agent_created",
model=config.OLLAMA_DEFAULT_MODEL,
tool_count=11,
tool_count=14, # 7 research + 3 web + 1 wiki read + 3 wiki write
)
return agent
+5 -2
View File
@@ -58,8 +58,9 @@ GUIDELINES:
- Simple greetings/chat → no capabilities needed (conversational response only)
- Questions about prior conversation ("what did I say", "my name", "what we discussed") → no capabilities (Tatlock has full history)
- Math/calculations → tatlock_core
- Quick web searches → tatlock_core
- Time/date queries → tatlock_core
- Web searches, weather, news, current information → librarian with search_web
- Read a URL or article → librarian with read_url
- Wiki creation ("create a page about X", "add X to wiki") → librarian with smart_create
- Wiki updates ("update the page", "add to dossier") → librarian with update
- Research queries ("find info", "what do we know about", "search for") → librarian with hybrid_search
@@ -74,8 +75,10 @@ COMPLEXITY: [simple/moderate/complex]
CONTEXT: [any relevant conversation context, or "none"]
EXAMPLES:
- "DELEGATE: librarian to search_web for tomorrow's weather forecast"
- "DELEGATE: librarian to create a wiki page about CI/CD pipelines"
- "DELEGATE: librarian to search for information about Docker networking"
- "DELEGATE: librarian to hybrid_search for information about Docker networking"
- "DELEGATE: librarian to read_url https://example.com/article"
- "DELEGATE: tatlock_core to calculate the result"
- "DELEGATE: none (conversational response only)"
+5 -2
View File
@@ -515,15 +515,18 @@ async def create_response_with_steward(request: ResponseRequest) -> Response:
from src.agents.tatlock import TatlockAgent
tatlock = TatlockAgent()
# Use enriched query (with location/timezone context) if available
effective_query = enriched.recommendation.enriched_query or user_message
if delegation_only:
# Direct delegation path - collect results then synthesize
orchestration_results = await _direct_delegation_with_results(
user_message, enriched.recommendation, tracker, conversation_id
effective_query, enriched.recommendation, tracker, conversation_id
)
else:
# Phase 1: Orchestrate tool calls
orchestration_results = await tatlock.orchestrate_tool_calls(
user_message=user_message,
user_message=effective_query,
steward_note=enriched.steward_note,
scoped_tools=enriched.scoped_tools,
message_history=conversation_history,