fix(agents): make librarian failures structured and user-safe
- run_librarian / run_librarian_stream raise AgentError instead of
returning/yielding error text as normal output; detail stays in logs
- delegate_to_* wrappers now put a curated butler-toned sentence in
DelegationResult.output on failure and never expose str(e), so
streaming's error branch is reachable and honest
- _execute_single_delegation propagates success; direct delegation only
records delegate_to_* as called when the expert actually succeeded
- librarian tools return user-safe messages instead of
'Error searching: {e}' strings that leaked internal URLs into
synthesis; coordination stream errors are curated as well
- ruff cleanups (TYPE_CHECKING forward refs, B904, unused locals) in
the touched files to keep them lint-clean
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,7 +111,7 @@ async def hybrid_search(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_hybrid_search_error", error=str(e), query=query)
|
||||
return f"Error searching: {str(e)}"
|
||||
return "I was unable to search the knowledge archives; the search service did not respond properly."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -159,7 +159,7 @@ async def search_wiki(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_wiki_search_error", error=str(e))
|
||||
return f"Error searching wiki: {str(e)}"
|
||||
return "I was unable to search the wiki at this time."
|
||||
|
||||
|
||||
async def get_wiki_page(
|
||||
@@ -202,7 +202,7 @@ async def get_wiki_page(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_get_page_error", error=str(e), page_id=page_id)
|
||||
return f"Error getting page {page_id}: {str(e)}"
|
||||
return f"I was unable to retrieve wiki page {page_id}."
|
||||
|
||||
|
||||
async def list_dossiers() -> str:
|
||||
@@ -236,7 +236,7 @@ async def list_dossiers() -> str:
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_list_dossiers_error", error=str(e))
|
||||
return f"Error listing dossiers: {str(e)}"
|
||||
return "I was unable to retrieve the list of dossiers."
|
||||
|
||||
|
||||
async def get_dossier_pages(
|
||||
@@ -277,7 +277,7 @@ async def get_dossier_pages(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_get_dossier_error", error=str(e))
|
||||
return f"Error getting dossier: {str(e)}"
|
||||
return f"I was unable to retrieve the dossier '{dossier_name}'."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -326,7 +326,7 @@ async def semantic_search(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_semantic_search_error", error=str(e))
|
||||
return f"Error in semantic search: {str(e)}"
|
||||
return "I was unable to complete the semantic search."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -379,7 +379,7 @@ async def explore_knowledge_graph(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_explore_graph_error", error=str(e))
|
||||
return f"Error exploring knowledge graph: {str(e)}"
|
||||
return "I was unable to explore the knowledge graph."
|
||||
|
||||
|
||||
async def find_related_entities(
|
||||
@@ -450,7 +450,7 @@ async def find_related_entities(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_find_related_error", error=str(e))
|
||||
return f"Error finding related entities: {str(e)}"
|
||||
return f"I was unable to look up entities related to '{entity_name}'."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -533,7 +533,7 @@ async def search_web(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_web_search_error", error=str(e), query=query)
|
||||
return f"Error searching web: {str(e)}"
|
||||
return "I was unable to search the web at this time."
|
||||
|
||||
|
||||
async def read_url(
|
||||
@@ -609,7 +609,7 @@ async def read_url(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_read_url_error", error=str(e), url=url)
|
||||
return f"Error reading URL: {str(e)}"
|
||||
return f"I was unable to read the page at {url}."
|
||||
|
||||
|
||||
async def read_urls_batch(
|
||||
@@ -683,7 +683,7 @@ async def read_urls_batch(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_read_urls_batch_error", error=str(e))
|
||||
return f"Error reading URLs: {str(e)}"
|
||||
return "I was unable to read the requested pages."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -766,7 +766,7 @@ async def update_wiki_page(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_update_page_error", error=str(e), page_id=page_id)
|
||||
return f"Error updating page {page_id}: {str(e)}"
|
||||
return f"I was unable to update wiki page {page_id}."
|
||||
|
||||
|
||||
async def create_wiki_page(
|
||||
@@ -841,7 +841,7 @@ async def create_wiki_page(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_create_page_error", error=str(e), title=title)
|
||||
return f"Error creating page: {str(e)}"
|
||||
return f"I was unable to create the page '{title}'."
|
||||
|
||||
|
||||
async def smart_create_wiki_page(
|
||||
@@ -930,7 +930,7 @@ async def smart_create_wiki_page(
|
||||
|
||||
except Exception as e:
|
||||
logger.error("librarian_smart_create_error", error=str(e), topic=topic)
|
||||
return f"Error creating page about '{topic}': {str(e)}"
|
||||
return f"I was unable to create a page about '{topic}'."
|
||||
|
||||
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user