style: apply ruff's automatic fixes and formatter

Mechanical only, and separated from the judgment calls that follow so the
reviewable changes are not buried in a 98-file whitespace diff.

227 automatic fixes: 60 blank lines carrying whitespace, 60 unsorted import
blocks, 34 Optional[X] to X | None, 28 unused imports, 16 deprecated typing
imports, 12 datetime.timezone.utc to datetime.UTC, and assorted smaller
modernisations. Then `ruff format` over src and tests: 98 files reformatted,
35 already conforming.

No file among the unused-import findings defines __all__ or is an __init__.py,
so nothing here removes a re-export.

`make test`: 658 passed, unchanged from HEAD.

Two things observed while verifying, neither addressed here:

`pytest tests/` cannot collect — tests/e2e/test_orchestration_e2e.py uses an
`e2e` marker that is not registered, and the config is strict about markers.
This fails identically at HEAD, so it predates this change; `make test` passes
because it ignores tests/e2e, tests/integration and tests/contracts.

test_tatlock_tool_call_logging_calculator is flaky. It failed once in a full run
with these changes and passed on the next, passes in isolation with them, and
fails in isolation at HEAD. It is order- or timing-dependent, not a regression
from this commit — established by running the full suite both ways rather than
by reasoning about which change could have caused it.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-11 17:25:18 +02:00
co-authored by Claude
parent 57fa6c13fc
commit 78066fab1b
103 changed files with 1601 additions and 1749 deletions
+21 -20
View File
@@ -4,6 +4,7 @@ Librarian tools for PydanticAI agent.
These tools wrap the library-desk API and are registered with
The Librarian agent for research and knowledge management tasks.
"""
import httpx
from pydantic_ai import ModelRetry
@@ -27,9 +28,8 @@ def _retry_if_transient(e: Exception, what: str) -> None:
status = e.response.status_code
retryable = status >= 500 or status == 429
if retryable:
raise ModelRetry(
f"{what} is temporarily unavailable; please retry."
) from e
raise ModelRetry(f"{what} is temporarily unavailable; please retry.") from e
# Icons keyed by the values library-desk emits in each result's `sources`
# list (search legs) and `source_type` (result origin).
@@ -64,11 +64,7 @@ def _coverage_note(
results, so their absence is normal ranking behavior, not an outage.
"""
if response.source_status:
failed = sorted(
leg
for leg, status in response.source_status.items()
if status == "failed"
)
failed = sorted(leg for leg, status in response.source_status.items() if status == "failed")
if failed:
return (
"⚠️ *Coverage note: results are partial - "
@@ -111,6 +107,7 @@ def _coverage_note(
# HybridRAG Search
# ============================================================================
async def hybrid_search(
query: str,
include_web: bool = True,
@@ -165,9 +162,7 @@ async def hybrid_search(
# Add related dossiers
if response.related_dossiers:
output_parts.append(
f"**Related Dossiers:** {', '.join(response.related_dossiers)}"
)
output_parts.append(f"**Related Dossiers:** {', '.join(response.related_dossiers)}")
output_parts.append("")
@@ -216,6 +211,7 @@ async def hybrid_search(
# Wiki Operations
# ============================================================================
async def search_wiki(
query: str,
limit: int = 10,
@@ -331,9 +327,7 @@ async def list_dossiers() -> str:
output_parts = ["## Research Dossiers\n"]
for dossier in dossiers:
output_parts.append(
f"- **{dossier.name}** ({dossier.page_count} pages)"
)
output_parts.append(f"- **{dossier.name}** ({dossier.page_count} pages)")
return "\n".join(output_parts)
@@ -389,6 +383,7 @@ async def get_dossier_pages(
# Semantic Search
# ============================================================================
async def semantic_search(
query: str,
limit: int = 10,
@@ -420,9 +415,7 @@ async def semantic_search(
output_parts = [f"## Semantic Search: {query}\n"]
for i, result in enumerate(results, 1):
output_parts.append(
f"{i}. **{result.page_title}** (score: {result.score:.2f})"
)
output_parts.append(f"{i}. **{result.page_title}** (score: {result.score:.2f})")
output_parts.append(f" Path: {result.page_path}")
output_parts.append(f" {result.chunk_text[:200]}...")
output_parts.append("")
@@ -439,6 +432,7 @@ async def semantic_search(
# Knowledge Graph
# ============================================================================
async def explore_knowledge_graph(
entity_type: str = "Document",
limit: int = 20,
@@ -565,6 +559,7 @@ async def find_related_entities(
# Web Search & Content Extraction
# ============================================================================
async def search_web(
query: str,
limit: int = 10,
@@ -605,7 +600,9 @@ async def search_web(
return f"No results found for '{query}'"
output_parts = [f"## Web Search: {query}\n"]
output_parts.append(f"*Found {response.total_results} results in {response.search_time_ms}ms*\n")
output_parts.append(
f"*Found {response.total_results} results in {response.search_time_ms}ms*\n"
)
for i, result in enumerate(response.results, 1):
output_parts.append(f"### {i}. {result.title}")
@@ -880,7 +877,9 @@ async def update_wiki_page(
if page.tags:
output_parts.append(f"**Tags:** {', '.join(page.tags)}")
output_parts.append("\n*Vector embeddings and knowledge graph will be updated automatically.*")
output_parts.append(
"\n*Vector embeddings and knowledge graph will be updated automatically.*"
)
logger.info(
"librarian_update_page",
@@ -954,7 +953,9 @@ async def create_wiki_page(
if page.description:
output_parts.append(f"**Description:** {page.description}")
output_parts.append("\n*Vector embeddings and knowledge graph will be updated automatically.*")
output_parts.append(
"\n*Vector embeddings and knowledge graph will be updated automatically.*"
)
logger.info(
"librarian_create_page",