Remove dead code from iterative research planning refactor

This commit is contained in:
Yiorgis Gozadinos 2026-01-31 10:36:11 +02:00
parent 42f2d0fd0e
commit ac76ecee86
No known key found for this signature in database
14 changed files with 20 additions and 76 deletions

View file

@ -9,6 +9,13 @@
- Simpler flow: `plan_next``search_one` → loop back until complete → `synthesize`
- Consolidated `build_conversational_graph()` into `build_research_graph(output_mode="conversational")`
### Removed
- **Dead config options**: Removed vestigial fields from iterative planning refactor
- `confidence_threshold` from `ResearchConfig` and `ResearchState` (LLM decides completion via `is_complete`)
- `max_sub_questions` from `QAConfig` (iterative flow uses one question at a time)
- `sub_questions` field from `ResearchContext` (no longer populated)
## [0.27.2] - 2026-01-29
### Added

View file

@ -244,7 +244,6 @@ custom_config = AppConfig(
provider="openai",
model="gpt-4o-mini",
max_iterations=5,
confidence_threshold=0.85,
max_concurrency=3,
)
)

View file

@ -255,7 +255,7 @@ Flags:
- `--context`: Background context for the research
- `--context-file`: Path to a file containing background context
Research parameters like `max_iterations`, `confidence_threshold`, and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.
Research parameters like `max_iterations` and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.
## Server

View file

@ -85,7 +85,6 @@ qa:
provider: ollama
name: gpt-oss
enable_thinking: false
max_sub_questions: 3
max_iterations: 2
max_concurrency: 1
@ -95,7 +94,6 @@ research:
name: ""
enable_thinking: false
max_iterations: 3
confidence_threshold: 0.8
max_concurrency: 1
search:

View file

@ -32,17 +32,15 @@ qa:
provider: ollama
name: gpt-oss
enable_thinking: false
max_sub_questions: 3 # Maximum sub-questions for deep QA
max_iterations: 2 # Maximum search iterations per sub-question
max_concurrency: 1 # Sub-questions processed in parallel
max_iterations: 2 # Maximum search iterations
max_concurrency: 1 # Concurrent search operations
```
- **model**: LLM configuration (see [Providers](providers.md#model-settings))
- **max_sub_questions**: For deep QA mode, maximum number of sub-questions to generate (default: 3)
- **max_iterations**: Maximum search/evaluate cycles per sub-question (default: 2)
- **max_concurrency**: Number of sub-questions to process in parallel (default: 1)
- **max_iterations**: Maximum search iterations (default: 2)
- **max_concurrency**: Number of concurrent search operations (default: 1)
Deep QA mode (`haiku-rag ask --deep`) decomposes complex questions into sub-questions, processes them in parallel batches, and synthesizes the results.
Deep QA mode (`haiku-rag ask --deep`) uses the research graph with a single iteration for quick, focused answers.
## Research Configuration
@ -55,13 +53,11 @@ research:
name: "" # Empty to use qa model
enable_thinking: false
max_iterations: 3
confidence_threshold: 0.8
max_concurrency: 1
```
- **model**: LLM configuration. Leave provider/model empty to inherit from `qa` (see [Providers](providers.md#model-settings))
- **max_iterations**: Maximum search/evaluate cycles (default: 3)
- **confidence_threshold**: Stop when confidence score meets/exceeds this (default: 0.8)
- **max_concurrency**: Sub-questions searched in parallel per iteration (default: 1)
- **max_iterations**: Maximum planning/search iterations (default: 3)
- **max_concurrency**: Concurrent search operations (default: 1)
The research workflow plans sub-questions, searches in parallel batches, evaluates findings, and iterates until reaching the confidence threshold or max iterations.
The research workflow uses an iterative feedback loop: the planner proposes one question at a time, sees the answer, then decides whether to continue or synthesize. This continues until the planner marks research as complete or `max_iterations` is reached.

View file

@ -249,7 +249,6 @@ def create_chat_agent(config: AppConfig) -> Agent[ChatDeps, str]:
state = ResearchState(
context=context,
max_iterations=1,
confidence_threshold=0.0,
search_filter=doc_filter,
max_concurrency=ctx.deps.config.research.max_concurrency,
)

View file

@ -13,9 +13,6 @@ class ResearchContext(BaseModel):
"""Context shared across research agents."""
original_question: str = Field(description="The original research question")
sub_questions: list[str] = Field(
default_factory=list, description="Decomposed sub-questions"
)
qa_responses: list[Any] = Field(
default_factory=list, description="Structured QA pairs used during research"
)

View file

@ -27,17 +27,8 @@ from haiku.rag.config.models import AppConfig
from haiku.rag.utils import build_prompt, get_model
def format_context_for_prompt(
context: ResearchContext,
include_pending_questions: bool = True,
) -> str:
"""Format the research context as XML for prompts.
Args:
context: The research context to format.
include_pending_questions: Whether to include pending sub-questions.
Set to False for synthesis prompts where pending questions aren't relevant.
"""
def format_context_for_prompt(context: ResearchContext) -> str:
"""Format the research context as XML for prompts."""
context_data: dict[str, object] = {}
if context.session_context:
@ -45,9 +36,6 @@ def format_context_for_prompt(
context_data["question"] = context.original_question
if include_pending_questions and context.sub_questions:
context_data["pending_questions"] = context.sub_questions
if context.qa_responses:
context_data["prior_answers"] = [
{
@ -267,9 +255,7 @@ def build_research_graph(
deps_type=ResearchDependencies,
)
context_xml = format_context_for_prompt(
state.context, include_pending_questions=False
)
context_xml = format_context_for_prompt(state.context)
prompt = (
"Generate a comprehensive research report based on all gathered information.\n\n"
f"{context_xml}\n\n"
@ -301,9 +287,7 @@ def build_research_graph(
deps_type=ResearchDependencies,
)
context_xml = format_context_for_prompt(
state.context, include_pending_questions=False
)
context_xml = format_context_for_prompt(state.context)
prompt = (
f"Answer the question based on the gathered evidence.\n\n{context_xml}"
)

View file

@ -29,9 +29,6 @@ class ResearchState(BaseModel):
)
iterations: int = Field(default=0, description="Current iteration number")
max_iterations: int = Field(default=3, description="Maximum allowed iterations")
confidence_threshold: float = Field(
default=0.8, description="Confidence threshold for completion", ge=0.0, le=1.0
)
max_concurrency: int = Field(
default=1, description="Maximum concurrent search operations", ge=1
)
@ -45,7 +42,6 @@ class ResearchState(BaseModel):
context: ResearchContext,
config: "AppConfig",
max_iterations: int | None = None,
confidence_threshold: float | None = None,
) -> "ResearchState":
"""Create a ResearchState from an AppConfig.
@ -53,15 +49,11 @@ class ResearchState(BaseModel):
context: The ResearchContext containing the question
config: The AppConfig object
max_iterations: Override max iterations (None uses config default)
confidence_threshold: Override threshold (None uses config, 0.0 disables check)
"""
return cls(
context=context,
max_iterations=max_iterations
if max_iterations is not None
else config.research.max_iterations,
confidence_threshold=confidence_threshold
if confidence_threshold is not None
else config.research.confidence_threshold,
max_concurrency=config.research.max_concurrency,
)

View file

@ -399,7 +399,6 @@ class HaikuRAGApp:
context=context,
config=self.config,
max_iterations=1,
confidence_threshold=0.0,
)
state.search_filter = filter
deps = ResearchDeps(client=self.client)

View file

@ -78,7 +78,6 @@ class QAConfig(BaseModel):
enable_thinking=False,
)
)
max_sub_questions: int = 3
max_iterations: int = 2
max_concurrency: int = 1
@ -92,7 +91,6 @@ class ResearchConfig(BaseModel):
)
)
max_iterations: int = 3
confidence_threshold: float = 0.8
max_concurrency: int = 1

View file

@ -199,7 +199,6 @@ def create_mcp_server(
context=context,
config=config,
max_iterations=2,
confidence_threshold=0.0,
)
deps = ResearchDeps(client=rag)

View file

@ -30,7 +30,6 @@ async def test_graph_end_to_end(allow_model_requests, temp_db_path, qa_corpus):
state = ResearchState(
context=ResearchContext(original_question=doc["question"]),
max_iterations=1,
confidence_threshold=0.5,
max_concurrency=1,
)
@ -155,27 +154,6 @@ def test_format_context_for_prompt_with_session_context():
assert "What is Y?" in result
def test_format_context_for_prompt_excludes_pending_questions():
"""Test format_context_for_prompt can exclude pending questions."""
from haiku.rag.agents.research.dependencies import ResearchContext
from haiku.rag.agents.research.graph import format_context_for_prompt
context = ResearchContext(
original_question="Main question?",
sub_questions=["Sub Q1?", "Sub Q2?"],
)
# With pending questions (default)
with_pending = format_context_for_prompt(context, include_pending_questions=True)
assert "Sub Q1?" in with_pending
# Without pending questions (for synthesis)
without_pending = format_context_for_prompt(
context, include_pending_questions=False
)
assert "Sub Q1?" not in without_pending
def test_format_context_for_prompt_with_prior_answers():
"""Test format_context_for_prompt includes prior_answers."""
from haiku.rag.agents.research.dependencies import ResearchContext

View file

@ -78,7 +78,6 @@ async def test_research_graph_uses_search_filter(
state = ResearchState(
context=ResearchContext(original_question="Tell me about animals"),
max_iterations=1,
confidence_threshold=0.5,
search_filter=filter_clause,
)
@ -116,7 +115,6 @@ async def test_search_filter_none_searches_all(allow_model_requests, client_with
state = ResearchState(
context=ResearchContext(original_question="Tell me about animals"),
max_iterations=1,
confidence_threshold=0.5,
search_filter=None,
)