From 557a2963410e0397a8fc05965d7e44b23ccc60b4 Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Mon, 15 Dec 2025 13:43:13 +0200 Subject: [PATCH] Update ag-ui example --- CHANGELOG.md | 21 ++ examples/ag-ui-research/README.md | 10 +- examples/ag-ui-research/backend/README.md | 4 +- examples/ag-ui-research/backend/agent.py | 3 +- .../frontend/components/Agent.tsx | 31 -- .../frontend/components/StateDisplay.tsx | 329 ------------------ .../haiku/rag/graph/common/nodes.py | 2 +- 7 files changed, 28 insertions(+), 372 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2defdf9c..e986e0b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,17 @@ ### Changed - **Chunker Sets Order**: Chunkers now set `chunk.order` directly +- **Unified Research Graph**: Simplified and unified research and deep QA into a single configurable graph + - Removed `analyze_insights` node - graph now flows directly from `collect_answers` to `decide` + - Simplified `EvaluationResult` to: `is_sufficient`, `confidence_score`, `reasoning`, `new_questions` + - Simplified `ResearchContext` - removed insight/gap tracking methods + - `ask --deep` now uses research graph with `max_iterations=2`, `confidence_threshold=0.0` + - `ask --deep` output now shows executive summary, key findings, and sources + - Added `include_plan` parameter to `build_research_graph()` for plan-less execution + - Added `max_iterations` and `confidence_threshold` overrides to `ResearchState.from_config()` +- **Improved Synthesis Prompt**: Updated synthesis agent prompt to produce direct answers + - Executive summary now directly answers the question instead of describing the report + - Added explicit examples of good vs bad output style - **Evaluations Vacuum Strategy**: `populate_db` now uses periodic vacuum to prevent disk exhaustion with large datasets - Disables auto_vacuum during population, vacuums every N documents with retention=0 - New `--vacuum-interval` CLI option (default: 100) to control vacuum frequency @@ -23,6 +34,16 @@ - Added dedicated Methodology section explaining MRR, MAP, and QA Accuracy metrics - Organized results by dataset with retrieval and QA subsections +### Removed + +- **Deep QA Graph**: Removed `haiku.rag.graph.deep_qa` module entirely + - Use `build_research_graph()` with appropriate parameters instead + - `ask --deep` CLI command now uses research graph internally +- **Insight/Gap Tracking**: Removed over-engineered insight and gap tracking from research graph + - Removed `InsightRecord`, `GapRecord`, `InsightAnalysis`, `InsightStatus`, `GapSeverity` models + - Removed `format_analysis_for_prompt()` helper + - Removed `INSIGHT_AGENT_PROMPT` from prompts + ## [0.20.2] - 2025-12-12 ### Fixed diff --git a/examples/ag-ui-research/README.md b/examples/ag-ui-research/README.md index 085222a5..df6850dc 100644 --- a/examples/ag-ui-research/README.md +++ b/examples/ag-ui-research/README.md @@ -6,10 +6,9 @@ Research assistant powered by [haiku.rag](https://ggozad.github.io/haiku.rag/), ## Features -- **Multi-iteration research graph**: Automated question decomposition, search, insight extraction, and gap analysis +- **Multi-iteration research graph**: Automated question decomposition and search - **Intelligent evaluation**: Confidence-based decision making with automatic iteration until sufficient information is gathered - **Live state synchronization**: Real-time delta updates of research progress via AG-UI protocol -- **Insight & gap tracking**: Structured insights with provenance and automatic gap identification - **Rich reporting**: Generates comprehensive research reports with findings, conclusions, and sources ## Quick Start @@ -81,9 +80,8 @@ Research assistant powered by [haiku.rag](https://ggozad.github.io/haiku.rag/), - Gathers initial context about the topic 3. **Research iterations**: The graph autonomously: - Searches the knowledge base for each sub-question in parallel - - Extracts structured insights with source provenance - - Identifies information gaps and assesses confidence - - Generates new follow-up questions for gaps + - Assesses confidence in gathered information + - Generates new follow-up questions if needed - Iterates until confidence threshold is met or max iterations reached 4. **Synthesis**: Generates a comprehensive research report with: - Executive summary @@ -126,7 +124,7 @@ This example demonstrates the **agent+graph** architecture pattern: - CopilotKit for AG-UI protocol integration - Split-pane UI: chat on left, live research state on right - Real-time state synchronization via Server-Sent Events (SSE) - - `StateDisplay` component with collapsible sections for questions, insights, and gaps + - `StateDisplay` component with collapsible sections for questions and report ## Configuration diff --git a/examples/ag-ui-research/backend/README.md b/examples/ag-ui-research/backend/README.md index 9b0751e9..8b6da3df 100644 --- a/examples/ag-ui-research/backend/README.md +++ b/examples/ag-ui-research/backend/README.md @@ -15,13 +15,11 @@ The server starts on `http://localhost:8000` and uses [haiku.rag configuration]( The backend uses `create_agui_server()` from `haiku.rag.graph.agui.server` which provides: -- **Research graph execution**: Multi-iteration research workflow with insight/gap tracking +- **Research graph execution**: Multi-iteration research workflow - **AG-UI protocol**: Server-Sent Events (SSE) streaming for real-time state updates - **Delta state updates**: Efficient incremental state synchronization using JSON Patch operations -- **Both research and deep_qa endpoints**: `/agent/research` and `/agent/deep_qa` ## Endpoints - `GET /health` - Health check with configuration info - `POST /agent/research/stream` - Research graph streaming endpoint (AG-UI protocol) -- `POST /agent/deep_qa/stream` - Deep QA graph streaming endpoint (AG-UI protocol) diff --git a/examples/ag-ui-research/backend/agent.py b/examples/ag-ui-research/backend/agent.py index 3dce81ac..e697145f 100644 --- a/examples/ag-ui-research/backend/agent.py +++ b/examples/ag-ui-research/backend/agent.py @@ -56,7 +56,7 @@ How to decide: - "Tell me about Y" → Use run_research tool When you use run_research, the graph will decompose questions, search the knowledge base, -extract insights, and generate a comprehensive report. +and generate a comprehensive report. Be friendly and conversational in all responses.""", ) @@ -100,7 +100,6 @@ Main Findings: Conclusions: {chr(10).join(f"- {conclusion}" for conclusion in result.conclusions[:2])} -Total insights gathered: {len(state.context.insights)} Confidence: {f"{state.last_eval.confidence_score:.0%}" if state.last_eval else "N/A"} Iterations completed: {state.iterations} diff --git a/examples/ag-ui-research/frontend/components/Agent.tsx b/examples/ag-ui-research/frontend/components/Agent.tsx index 8a98a3dd..75429a91 100644 --- a/examples/ag-ui-research/frontend/components/Agent.tsx +++ b/examples/ag-ui-research/frontend/components/Agent.tsx @@ -6,26 +6,6 @@ import "@copilotkit/react-ui/styles.css"; import DocumentSelector from "./DocumentSelector"; import StateDisplay from "./StateDisplay"; -interface InsightRecord { - id: string; - summary: string; - status: string; - notes?: string; - supporting_sources: string[]; - originating_questions: string[]; -} - -interface GapRecord { - id: string; - description: string; - severity: string; - blocking: boolean; - resolved: boolean; - notes?: string; - supporting_sources: string[]; - resolved_by: string[]; -} - interface Citation { document_id: string; chunk_id: string; @@ -48,14 +28,10 @@ interface ResearchContext { original_question: string; sub_questions: string[]; qa_responses: SearchAnswer[]; - insights: InsightRecord[]; - gaps: GapRecord[]; } interface EvaluationResult { - key_insights: string[]; new_questions: string[]; - gaps: string[]; confidence_score: number; is_sufficient: boolean; reasoning: string; @@ -78,10 +54,6 @@ interface ResearchState { confidence_threshold: number; max_concurrency: number; last_eval: EvaluationResult | null; - last_analysis: { - insights_extracted: InsightRecord[]; - gaps_identified: GapRecord[]; - } | null; result?: ResearchReport; current_activity?: string; current_activity_message?: string; @@ -96,15 +68,12 @@ function AgentContent() { original_question: "", sub_questions: [], qa_responses: [], - insights: [], - gaps: [], }, iterations: 0, max_iterations: 3, confidence_threshold: 0.8, max_concurrency: 1, last_eval: null, - last_analysis: null, documentFilter: [], }, }); diff --git a/examples/ag-ui-research/frontend/components/StateDisplay.tsx b/examples/ag-ui-research/frontend/components/StateDisplay.tsx index c0ad3291..387b4a57 100644 --- a/examples/ag-ui-research/frontend/components/StateDisplay.tsx +++ b/examples/ag-ui-research/frontend/components/StateDisplay.tsx @@ -11,26 +11,6 @@ interface VisualGroundingState { error: string | null; } -interface InsightRecord { - id: string; - summary: string; - status: string; - notes?: string; - supporting_sources: string[]; - originating_questions: string[]; -} - -interface GapRecord { - id: string; - description: string; - severity: string; - blocking: boolean; - resolved: boolean; - notes?: string; - supporting_sources: string[]; - resolved_by: string[]; -} - interface Citation { document_id: string; chunk_id: string; @@ -53,14 +33,10 @@ interface ResearchContext { original_question: string; sub_questions: string[]; qa_responses: SearchAnswer[]; - insights: InsightRecord[]; - gaps: GapRecord[]; } interface EvaluationResult { - key_insights: string[]; new_questions: string[]; - gaps: string[]; confidence_score: number; is_sufficient: boolean; reasoning: string; @@ -83,10 +59,6 @@ interface ResearchState { confidence_threshold: number; max_concurrency: number; last_eval: EvaluationResult | null; - last_analysis: { - insights_extracted: InsightRecord[]; - gaps_identified: GapRecord[]; - } | null; result?: ResearchReport; current_activity?: string; current_activity_message?: string; @@ -101,8 +73,6 @@ export default function StateDisplay({ state }: StateDisplayProps) { Record >({ questions: true, - insights: true, - gaps: true, report: true, }); @@ -694,305 +664,6 @@ export default function StateDisplay({ state }: StateDisplayProps) { )} - {/* Insights */} - {state.context.insights.length > 0 && ( -
- - {expandedSections.insights && ( -
- {state.context.insights.map((insight) => ( -
-
- - {insight.status} - - - {insight.supporting_sources.length} sources - -
-
- -
- {insight.notes && ( -
- -
- )} - {insight.supporting_sources.length > 0 && ( -
- Sources: - {insight.supporting_sources.map((source, srcIdx) => ( - - {srcIdx > 0 && ", "} - {source} - - ))} -
- )} -
- ))} -
- )} -
- )} - - {/* Knowledge Gaps */} - {state.context.gaps.length > 0 && ( -
- - {expandedSections.gaps && ( -
- {state.context.gaps.map((gap) => ( -
-
-
- - {gap.severity} - - {gap.blocking && ( - - Blocking - - )} - {gap.resolved && ( - - Resolved - - )} -
-
-
- -
- {gap.notes && ( -
- -
- )} - {gap.resolved && gap.resolved_by.length > 0 && ( -
- Resolved by: - {gap.resolved_by.map((source, srcIdx) => ( - - {srcIdx > 0 && ", "} - {source} - - ))} -
- )} -
- ))} -
- )} -
- )} - {/* Final Report */} {state.result && (