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
2 changes: 1 addition & 1 deletion apps/api/app/mcp/retrieval_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ async def query_documents(
top_k=top_k,
exclude_document_ids=exclude_document_ids,
exclude_sections=[item for item in exclude_sections],
use_agentic=True,
use_agentic=None,
)
return to_mcp_query_response(response)

Expand Down
152 changes: 0 additions & 152 deletions packages/shared-python/shared/services/ai/llm_mock.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Helpers for deterministic mock responses from OpenAI-compatible LLM calls."""

import json
import re
from typing import Any, Dict, List

from loguru import logger
Expand All @@ -20,13 +18,6 @@ def build_mock_chat_completion_response(
model_name,
task_name,
)
# For agentic tasks that need dynamic content extraction, build the response here.
if task_name == "agentic-planner":
return _build_planner_mock_response(prompt_text)
if task_name == "agentic-navigate":
return _build_navigate_mock_response(prompt_text)
if task_name == "agentic-discovery-select":
return _build_discovery_select_mock_response(prompt_text)
return _build_mock_response(task_name)


Expand Down Expand Up @@ -77,23 +68,6 @@ def _detect_mock_task(prompt_text: str) -> str:
"""Infer the prompt task so the mock can return a compatible response shape."""
normalized_prompt = prompt_text.lower()

# ── Agentic retrieval prompts (check first — they are structurally distinct) ──
if (
"you are a retrieval workflow planner" in normalized_prompt
and "concat_final_parts" in normalized_prompt
):
return "agentic-planner"
if (
"you are a document navigation agent" in normalized_prompt
and "=== section tree ==" in normalized_prompt
):
return "agentic-navigate"
if (
"=== discovery candidates ==" in normalized_prompt
and "\"selections\"" in normalized_prompt
):
return "agentic-discovery-select"

# ── Document parsing / ingestion prompts ──
if (
"generate a concise title" in normalized_prompt
Expand Down Expand Up @@ -149,135 +123,9 @@ def _detect_mock_task(prompt_text: str) -> str:
return "default"


def _extract_first_section_path(prompt_text: str) -> str | None:
"""Pull the first path value from a COLLECTOR_PROMPT section tree block.

The section tree is rendered by section_prompt_projection.format_items_for_llm()
and each item line looks like::

▸ [L1] path="Root" [text=1] ~100 tokens [Leaf]
└ [L2] path="Root / Sub" [text=2] ~200 tokens

We extract the value inside path="..." from the first matching line
within the === Section Tree === block.
"""
tree_match = re.search(
r"=== Section Tree ===(.*?)=== End Section Tree ===",
prompt_text,
re.DOTALL | re.IGNORECASE,
)
if not tree_match:
return None
tree_block = tree_match.group(1)
# Match path="..." in the section tree — this is the canonical format
path_match = re.search(r'path="([^"]+)"', tree_block)
if path_match:
return path_match.group(1)
return None



def _extract_user_query(prompt_text: str) -> str:
"""Extract the user query line from a planner/navigation prompt.

The PLANNER_PROMPT and COLLECTOR_PROMPT both contain::
User query: {query}
"""
match = re.search(r"User query:\s*(.+)", prompt_text)
if match:
return match.group(1).strip()
return "mock query"


def _build_planner_mock_response(prompt_text: str) -> str:
"""Return a valid single-step QueryPlan JSON using the real query from the prompt."""
query = _extract_user_query(prompt_text)
response = {
"reasoning_summary": "mock single-step plan",
"steps": [
{
"id": "s1",
"sub_query": query,
"step_kind": "retrieve",
"depends_on": [],
"output_role": "final_part",
"top_k": 10,
}
],
"final_strategy": "concat_final_parts",
}
return json.dumps(response)


def _build_navigate_mock_response(prompt_text: str) -> str:
"""Return a mock COLLECTOR_PROMPT response that COLLECTs the first visible path."""
path = _extract_first_section_path(prompt_text)
if path:
response = {
"collect": [{"path": path, "confidence": 0.9, "outline": False}],
"action": "STOP",
"drill_into": None,
"tools": [],
"reason": "Mock: collected first available section",
}
else:
# No path found — STOP without collecting (safe fallback)
response = {
"collect": [],
"action": "STOP",
"drill_into": None,
"tools": [],
"reason": "Mock: no section path found in tree",
}
return json.dumps(response)


def _extract_first_discovery_path(prompt_text: str) -> str | None:
"""Pull the first path value from a DISCOVERY_SELECT_PROMPT candidates block.

Discovery hints are rendered by selection._project_discovery_hints() as::

▸ path="Findings"
<summary text>

We extract the value inside path="..." from the candidates block.
"""
candidates_match = re.search(
r"=== Discovery Candidates ===(.*?)=== End Discovery Candidates ===",
prompt_text,
re.DOTALL | re.IGNORECASE,
)
if not candidates_match:
return None
block = candidates_match.group(1)
# Match path="..." — same canonical format as section tree
path_match = re.search(r'path="([^"]+)"', block)
if path_match:
return path_match.group(1)
return None


def _build_discovery_select_mock_response(prompt_text: str) -> str:
"""Return a mock DISCOVERY_SELECT_PROMPT response selecting the first candidate."""
path = _extract_first_discovery_path(prompt_text)
if path:
response = {"selections": [{"path": path, "confidence": 0.85}]}
else:
response = {"selections": []}
return json.dumps(response)


def _build_mock_response(task_name: str) -> str:
"""Return a canned response compatible with the inferred task contract."""
response_by_task: Dict[str, str] = {
# Agentic retrieval — static fallbacks (dynamic responses built elsewhere)
"agentic-planner": (
'{"reasoning_summary": "mock single-step plan", '
'"steps": [{"id": "s1", "sub_query": "mock query", '
'"step_kind": "retrieve", "depends_on": [], '
'"output_role": "final_part", "top_k": 10}], '
'"final_strategy": "concat_final_parts"}'
),
# Document parsing / ingestion tasks
"fragment-title": "Mock Fragment Title",
"detect-toc-range": '{"toc_start": null, "toc_end": null, "confidence": "low"}',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def _cache_shape_digest(
threshold: float = 0.0,
internal_recall_k: int | None = None,
use_agentic: bool | None = None,
decomposition_enabled: bool | None = None,
llm_text_model: str | None = None,
llm_vision_model: str | None = None,
) -> str:
normalized_excludes = sorted(exclude_document_ids)
normalized_sections = _normalize_exclude_sections(exclude_sections)
Expand All @@ -61,7 +62,8 @@ def _cache_shape_digest(
str(threshold),
str(internal_recall_k),
str(use_agentic),
str(decomposition_enabled),
str(llm_text_model or ""),
str(llm_vision_model or ""),
]
)
payload = f"{query}|{top_k}|{'|'.join(normalized_excludes)}|{'|'.join(normalized_sections)}|{extra}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def build_cache_extra(self) -> dict[str, Any]:
"threshold": self.threshold,
"internal_recall_k": self.internal_recall_k,
"use_agentic": self.use_agentic,
"decomposition_enabled": True,
"llm_text_model": text_model,
"llm_vision_model": vision_model,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def to_public_source(row: dict[str, Any]) -> dict[str, Any]:
async def enrich_referenced_chunks_with_asset_url(refs: list[dict[str, Any]]) -> list[dict[str, Any]]:
return await enrich_rows_with_retrieval_asset_url(
refs,
log_context='agentic referenced chunk',
log_context='mapnav referenced chunk',
)


Expand Down
167 changes: 0 additions & 167 deletions packages/shared-python/shared/services/retrieval/llm_adapter.py

This file was deleted.

Loading
Loading