Remove defensive app() try/except, let errors propagate if they occur

This commit is contained in:
Yiorgis Gozadinos 2026-01-15 10:17:26 +02:00
parent affffc1013
commit 345807e699
No known key found for this signature in database
2 changed files with 157 additions and 181 deletions

View file

@ -78,12 +78,8 @@ class HaikuRAGApp:
return return
# Connect without going through Store to avoid upgrades/validation writes # Connect without going through Store to avoid upgrades/validation writes
try: db = lancedb.connect(self.db_path)
db = lancedb.connect(self.db_path) table_names = set(db.table_names())
table_names = set(db.table_names())
except Exception as e:
self.console.print(f"[red]Failed to open database: {e}[/red]")
return
versions = get_package_versions() versions = get_package_versions()
@ -418,50 +414,47 @@ class HaikuRAGApp:
read_only=self.read_only, read_only=self.read_only,
before=self.before, before=self.before,
) as self.client: ) as self.client:
try: citations = []
citations = [] if deep:
if deep: graph = build_research_graph(config=self.config)
graph = build_research_graph(config=self.config) context = ResearchContext(original_question=question)
context = ResearchContext(original_question=question) state = ResearchState.from_config(
state = ResearchState.from_config( context=context,
context=context, config=self.config,
config=self.config, max_iterations=2,
max_iterations=2, confidence_threshold=0.0,
confidence_threshold=0.0, )
) state.search_filter = filter
state.search_filter = filter deps = ResearchDeps(client=self.client)
deps = ResearchDeps(client=self.client)
report = await graph.run(state=state, deps=deps) report = await graph.run(state=state, deps=deps)
self.console.print(f"[bold blue]Question:[/bold blue] {question}") self.console.print(f"[bold blue]Question:[/bold blue] {question}")
self.console.print() self.console.print()
if report: if report:
self.console.print("[bold green]Answer:[/bold green]")
self.console.print(Markdown(report.executive_summary))
if report.main_findings:
self.console.print()
self.console.print("[bold cyan]Key Findings:[/bold cyan]")
for finding in report.main_findings:
self.console.print(f"{finding}")
if report.sources_summary:
self.console.print()
self.console.print("[bold cyan]Sources:[/bold cyan]")
self.console.print(report.sources_summary)
else:
self.console.print("[yellow]No answer generated.[/yellow]")
else:
answer, citations = await self.client.ask(question, filter=filter)
self.console.print(f"[bold blue]Question:[/bold blue] {question}")
self.console.print()
self.console.print("[bold green]Answer:[/bold green]") self.console.print("[bold green]Answer:[/bold green]")
self.console.print(Markdown(answer)) self.console.print(Markdown(report.executive_summary))
if cite and citations: if report.main_findings:
for renderable in format_citations_rich(citations): self.console.print()
self.console.print(renderable) self.console.print("[bold cyan]Key Findings:[/bold cyan]")
except Exception as e: for finding in report.main_findings:
self.console.print(f"[red]Error: {e}[/red]") self.console.print(f"{finding}")
if report.sources_summary:
self.console.print()
self.console.print("[bold cyan]Sources:[/bold cyan]")
self.console.print(report.sources_summary)
else:
self.console.print("[yellow]No answer generated.[/yellow]")
else:
answer, citations = await self.client.ask(question, filter=filter)
self.console.print(f"[bold blue]Question:[/bold blue] {question}")
self.console.print()
self.console.print("[bold green]Answer:[/bold green]")
self.console.print(Markdown(answer))
if cite and citations:
for renderable in format_citations_rich(citations):
self.console.print(renderable)
async def research(self, question: str, filter: str | None = None): async def research(self, question: str, filter: str | None = None):
"""Run research via the pydantic-graph pipeline. """Run research via the pydantic-graph pipeline.
@ -476,77 +469,73 @@ class HaikuRAGApp:
read_only=self.read_only, read_only=self.read_only,
before=self.before, before=self.before,
) as client: ) as client:
try: self.console.print("[bold cyan]Starting research[/bold cyan]")
self.console.print("[bold cyan]Starting research[/bold cyan]") self.console.print(f"[bold blue]Question:[/bold blue] {question}")
self.console.print(f"[bold blue]Question:[/bold blue] {question}") self.console.print()
graph = build_research_graph(config=self.config)
context = ResearchContext(original_question=question)
state = ResearchState.from_config(context=context, config=self.config)
state.search_filter = filter
deps = ResearchDeps(client=client)
report = await graph.run(state=state, deps=deps)
if report is None:
self.console.print("[red]Research did not produce a report.[/red]")
return
# Display the report
self.console.print("[bold green]Research Report[/bold green]")
self.console.rule()
# Title and Executive Summary
self.console.print(f"[bold]{report.title}[/bold]")
self.console.print()
self.console.print("[bold cyan]Executive Summary:[/bold cyan]")
self.console.print(report.executive_summary)
self.console.print()
# Confidence (from last evaluation)
if state.last_eval:
conf = state.last_eval.confidence_score # type: ignore[attr-defined]
self.console.print(f"[bold cyan]Confidence:[/bold cyan] {conf:.1%}")
self.console.print() self.console.print()
graph = build_research_graph(config=self.config) # Main Findings
context = ResearchContext(original_question=question) if report.main_findings:
state = ResearchState.from_config(context=context, config=self.config) self.console.print("[bold cyan]Main Findings:[/bold cyan]")
state.search_filter = filter for finding in report.main_findings:
deps = ResearchDeps(client=client) self.console.print(f"{finding}")
report = await graph.run(state=state, deps=deps)
if report is None:
self.console.print("[red]Research did not produce a report.[/red]")
return
# Display the report
self.console.print("[bold green]Research Report[/bold green]")
self.console.rule()
# Title and Executive Summary
self.console.print(f"[bold]{report.title}[/bold]")
self.console.print()
self.console.print("[bold cyan]Executive Summary:[/bold cyan]")
self.console.print(report.executive_summary)
self.console.print() self.console.print()
# Confidence (from last evaluation) # (Themes section removed)
if state.last_eval:
conf = state.last_eval.confidence_score # type: ignore[attr-defined]
self.console.print(f"[bold cyan]Confidence:[/bold cyan] {conf:.1%}")
self.console.print()
# Main Findings # Conclusions
if report.main_findings: if report.conclusions:
self.console.print("[bold cyan]Main Findings:[/bold cyan]") self.console.print("[bold cyan]Conclusions:[/bold cyan]")
for finding in report.main_findings: for conclusion in report.conclusions:
self.console.print(f"{finding}") self.console.print(f"{conclusion}")
self.console.print() self.console.print()
# (Themes section removed) # Recommendations
if report.recommendations:
self.console.print("[bold cyan]Recommendations:[/bold cyan]")
for rec in report.recommendations:
self.console.print(f"{rec}")
self.console.print()
# Conclusions # Limitations
if report.conclusions: if report.limitations:
self.console.print("[bold cyan]Conclusions:[/bold cyan]") self.console.print("[bold yellow]Limitations:[/bold yellow]")
for conclusion in report.conclusions: for limitation in report.limitations:
self.console.print(f"{conclusion}") self.console.print(f"{limitation}")
self.console.print() self.console.print()
# Recommendations # Sources Summary
if report.recommendations: if report.sources_summary:
self.console.print("[bold cyan]Recommendations:[/bold cyan]") self.console.print("[bold cyan]Sources:[/bold cyan]")
for rec in report.recommendations: self.console.print(report.sources_summary)
self.console.print(f"{rec}")
self.console.print()
# Limitations
if report.limitations:
self.console.print("[bold yellow]Limitations:[/bold yellow]")
for limitation in report.limitations:
self.console.print(f"{limitation}")
self.console.print()
# Sources Summary
if report.sources_summary:
self.console.print("[bold cyan]Sources:[/bold cyan]")
self.console.print(report.sources_summary)
except Exception as e:
self.console.print(f"[red]Error during research: {e}[/red]")
async def rebuild(self, mode: RebuildMode = RebuildMode.FULL): async def rebuild(self, mode: RebuildMode = RebuildMode.FULL):
async with HaikuRAG( async with HaikuRAG(
@ -556,89 +545,76 @@ class HaikuRAGApp:
read_only=self.read_only, read_only=self.read_only,
before=self.before, before=self.before,
) as client: ) as client:
try: documents = await client.list_documents()
documents = await client.list_documents() total_docs = len(documents)
total_docs = len(documents)
if total_docs == 0: if total_docs == 0:
self.console.print( self.console.print("[yellow]No documents found in database.[/yellow]")
"[yellow]No documents found in database.[/yellow]" return
)
return
mode_desc = { mode_desc = {
RebuildMode.FULL: "full rebuild", RebuildMode.FULL: "full rebuild",
RebuildMode.RECHUNK: "rechunk", RebuildMode.RECHUNK: "rechunk",
RebuildMode.EMBED_ONLY: "embed only", RebuildMode.EMBED_ONLY: "embed only",
}[mode] }[mode]
self.console.print( self.console.print(
f"[bold cyan]Rebuilding database ({mode_desc}) with {total_docs} documents...[/bold cyan]" f"[bold cyan]Rebuilding database ({mode_desc}) with {total_docs} documents...[/bold cyan]"
) )
with Progress() as progress: with Progress() as progress:
task = progress.add_task("Rebuilding...", total=total_docs) task = progress.add_task("Rebuilding...", total=total_docs)
async for _ in client.rebuild_database(mode=mode): async for _ in client.rebuild_database(mode=mode):
progress.update(task, advance=1) progress.update(task, advance=1)
self.console.print( self.console.print(
"[bold green]Database rebuild completed successfully.[/bold green]" "[bold green]Database rebuild completed successfully.[/bold green]"
) )
except Exception as e:
self.console.print(f"[red]Error rebuilding database: {e}[/red]")
async def vacuum(self): async def vacuum(self):
"""Run database maintenance: optimize and cleanup table history.""" """Run database maintenance: optimize and cleanup table history."""
try: async with HaikuRAG(
async with HaikuRAG( db_path=self.db_path,
db_path=self.db_path, config=self.config,
config=self.config, skip_validation=True,
skip_validation=True, read_only=self.read_only,
read_only=self.read_only, before=self.before,
before=self.before, ) as client:
) as client: await client.vacuum()
await client.vacuum() self.console.print("[bold green]Vacuum completed successfully.[/bold green]")
self.console.print(
"[bold green]Vacuum completed successfully.[/bold green]"
)
except Exception as e:
self.console.print(f"[red]Error during vacuum: {e}[/red]")
async def create_index(self): async def create_index(self):
"""Create vector index on the chunks table.""" """Create vector index on the chunks table."""
try: async with HaikuRAG(
async with HaikuRAG( db_path=self.db_path,
db_path=self.db_path, config=self.config,
config=self.config, skip_validation=True,
skip_validation=True, read_only=self.read_only,
read_only=self.read_only, before=self.before,
before=self.before, ) as client:
) as client: row_count = client.store.chunks_table.count_rows()
row_count = client.store.chunks_table.count_rows() self.console.print(f"Chunks in database: {row_count}")
self.console.print(f"Chunks in database: {row_count}")
if row_count < 256: if row_count < 256:
self.console.print(
f"[yellow]Warning: Need at least 256 chunks to create an index (have {row_count})[/yellow]"
)
return
# Check if index already exists
indices = client.store.chunks_table.list_indices()
has_vector_index = any("vector" in str(idx).lower() for idx in indices)
if has_vector_index:
self.console.print(
"[yellow]Rebuilding existing vector index...[/yellow]"
)
else:
self.console.print("[bold]Creating vector index...[/bold]")
client.store._ensure_vector_index()
self.console.print( self.console.print(
"[bold green]Vector index created successfully.[/bold green]" f"[yellow]Warning: Need at least 256 chunks to create an index (have {row_count})[/yellow]"
) )
except Exception as e: return
self.console.print(f"[red]Error creating index: {e}[/red]")
# Check if index already exists
indices = client.store.chunks_table.list_indices()
has_vector_index = any("vector" in str(idx).lower() for idx in indices)
if has_vector_index:
self.console.print(
"[yellow]Rebuilding existing vector index...[/yellow]"
)
else:
self.console.print("[bold]Creating vector index...[/bold]")
client.store._ensure_vector_index()
self.console.print(
"[bold green]Vector index created successfully.[/bold green]"
)
async def download_models(self): async def download_models(self):
"""Download Docling, HuggingFace tokenizer, and Ollama models per config.""" """Download Docling, HuggingFace tokenizer, and Ollama models per config."""

View file

@ -16,7 +16,7 @@ def run_chat(
""" """
try: try:
from haiku.rag.chat.app import ChatApp from haiku.rag.chat.app import ChatApp
except ImportError as e: except ImportError as e: # pragma: no cover
raise ImportError( raise ImportError(
"textual is not installed. Please install it with `pip install 'haiku.rag-slim[tui]'` or use the full haiku.rag package." "textual is not installed. Please install it with `pip install 'haiku.rag-slim[tui]'` or use the full haiku.rag package."
) from e ) from e