Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions apps/api/app/api/v1/routes/retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ class RetrievalQueryRequest(BaseModel):
internal_recall_k: int | None = Field(
None, ge=1, description="Override per-channel recall count"
)
enable_decomposition: bool | None = Field(
use_agentic: bool | None = Field(
None,
description="Deprecated: agentic mode now always uses workflow decomposition. This field is ignored.",
deprecated=True,
description="Per-request agentic mode toggle. true=force agentic, false=force legacy, null=use server default.",
)

@field_validator("channels")
Expand All @@ -68,32 +67,13 @@ def validate_channels(cls, v: list[str]) -> list[str]:
return v


class WorkflowStepResponse(BaseModel):
step_id: str
sub_query: str
step_kind: Literal["retrieve", "synthesize"]
depends_on: list[str]
output_role: str
status: Literal["done", "skipped", "error", "budget_stop"]
answer_text: str
evidence_text: str | None = None
referenced_chunks: list[dict] = Field(default_factory=list)
budget_snapshot: dict | None = None
child_run_id: str | None = None


class RetrievalQueryResponse(BaseModel):
namespace: str
query: str
router_used: str
answer_text: str | None = None
referenced_chunks: list[dict] = Field(default_factory=list)
results: list[dict] = Field(default_factory=list)
plan: dict | None = None
steps: list[WorkflowStepResponse] | None = None
final_strategy_used: str | None = None
wallet_snapshot: dict | None = None
planner_snapshot: dict | None = None


@router.post("/query", response_model=RetrievalQueryResponse)
Expand All @@ -118,5 +98,5 @@ async def query_retrieval(
rerank=payload.rerank,
threshold=payload.threshold,
internal_recall_k=payload.internal_recall_k,
enable_decomposition=payload.enable_decomposition,
use_agentic=payload.use_agentic,
)
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,6 @@ async def _to_public_response(response: dict[str, Any]) -> dict[str, Any]:
}

# Forward agentic evidence fields when present
if response.get('evidence_text') is not None:
public_response['evidence_text'] = response['evidence_text']
if response.get('answer_text') is not None:
public_response['answer_text'] = response['answer_text']
if response.get('referenced_chunks') is not None:
Expand Down Expand Up @@ -982,7 +980,7 @@ async def run_retrieval_query(
rerank: bool = False,
threshold: float = 0.0,
internal_recall_k: int | None = None,
enable_decomposition: bool | None = None, # deprecated: now always uses workflow
use_agentic: bool | None = None,
) -> dict[str, Any]:
"""Checkerboard retrieval: 3 independent channels -> RRF -> agent/graph union -> assembly."""
t_start = time.monotonic()
Expand Down Expand Up @@ -1100,7 +1098,10 @@ async def run_retrieval_query(
return await _to_public_response(response)

# ══ Route: agentic (unified workflow) vs legacy ══
_agentic_enabled = os.environ.get('RETRIEVAL_AGENTIC_ENABLED', 'true') == 'true'
if use_agentic is not None:
_agentic_enabled = use_agentic
else:
_agentic_enabled = os.environ.get('RETRIEVAL_AGENTIC_ENABLED', 'true') == 'true'
if _agentic_enabled:
# ── Unified agentic path via WorkflowOrchestrator ──
# Simple queries: planner returns a single-step plan (no decomposition).
Expand Down
Loading