You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(search): add LLM-first search with direct TOC-based location
Add new LLM-first search capability that attempts to directly locate
relevant nodes using the table of contents before falling back to
tree traversal algorithms. The search stage now accepts an LLM client
and implements direct TOC-based node location with structured JSON
responses containing top-3 most relevant entries.
The feature includes:
- New `with_llm_client()` method to configure LLM-based search
- TOC flattening utility for LLM consumption with numbered entries
- Structured JSON prompting for precise node selection
- Proper fallback to beam/greedy search when LLM fails
- Metrics tracking for LLM calls and search performance
refactor(indexer): change default summary strategy to full
Change the default summary strategy from selective to full generation
for improved content indexing quality.
debug: add debug logging throughout indexing and retrieval
Add comprehensive debug logging to track indexing flow, pipeline
options building, summary evaluation, and search operations including
pilot interventions for better debugging visibility.
let system_prompt = r#"You are a document navigation assistant. Your task is to locate the most relevant sections in a document hierarchy for a user's query.
304
+
305
+
CRITICAL INSTRUCTIONS:
306
+
1. Analyze the user query carefully to understand the intent
307
+
2. Examine the provided Table of Contents (TOC) with numbered entries
308
+
3. Select the TOP 3 most relevant entries that would contain the answer
309
+
4. You MUST respond with ONLY valid JSON. No markdown code blocks. No explanations outside JSON.
310
+
311
+
Your response must have this EXACT structure:
312
+
{
313
+
"reasoning": "Brief analysis of the query and why you selected these entries",
314
+
"candidates": [
315
+
{"node_id": 1, "relevance_score": 0.95, "reason": "Why this entry matches the query"},
316
+
{"node_id": 2, "relevance_score": 0.80, "reason": "Why this entry is also relevant"},
317
+
{"node_id": 3, "relevance_score": 0.65, "reason": "Why this entry might be relevant"}
318
+
]
319
+
}
320
+
321
+
Rules:
322
+
- node_id: MUST be a number from the provided TOC (the number in [N] brackets)
323
+
- relevance_score: Number between 0.0 and 1.0 (higher = more relevant)
324
+
- reason: Brief explanation for each selection
325
+
- candidates: Must have exactly 3 items, ordered by relevance (highest first)"#;
326
+
327
+
let user_prompt = format!(
328
+
"USER QUERY: {}\n\nDOCUMENT TOC ({} entries):\n{}\n\nBased on the query and TOC above, select the TOP 3 most relevant entries.\n\nRespond with ONLY the JSON object:",
329
+
query,
330
+
node_ids.len(),
331
+
toc_str
332
+
);
333
+
334
+
info!("Attempting LLM-based search for query: '{}'", query);
335
+
336
+
match llm_client.complete(system_prompt,&user_prompt).await{
337
+
Ok(response) => {
338
+
// Parse JSON response
339
+
match serde_json::from_str::<LlmLocateResponse>(&response){
340
+
Ok(llm_response) => {
341
+
letmut candidates = Vec::new();
342
+
343
+
for candidate in llm_response.candidates{
344
+
// node_id is 1-indexed from LLM, convert to 0-indexed
0 commit comments