feat: M3.7.4 Context Endpoint - three-tier lookup infrastructure (12 tests)

This commit is contained in:
2026-08-28 13:50:32 -07:00
parent 749543c093
commit 4d93f00dda
6 changed files with 631 additions and 69 deletions
+12 -23
View File
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::opensearch_client::OpenSearchClient;
use crate::query_optimizer::RRFFusion;
use crate::query_optimizer::{RRFFusion, RRFConfig};
/// Hybrid search result with score breakdown
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -36,10 +36,18 @@ impl SimpleHybridSearch {
vector_store: Arc<VectorStore>,
opensearch: Option<Arc<OpenSearchClient>>,
) -> Self {
// Create RRF with default config (k=60 per academic standards)
let rrf_config = RRFConfig {
k: 60.0,
retrieve_k: 50,
final_k: 10,
};
let rrf = RRFFusion::new(rrf_config);
Self {
vector_store,
opensearch,
rrf: RRFFusion::default(),
rrf,
}
}
@@ -69,27 +77,8 @@ impl SimpleHybridSearch {
.collect();
// 2. Lexical search (OpenSearch) - optional if available
let lexical_scores: Vec<(String, f32)> = if let Some(os) = &self.opensearch {
match os
.search(project, query, jwt_token, limit)
.await
{
Ok(results) => results
.into_iter()
.enumerate()
.map(|(i, _result)| {
// Use ID from OpenSearch result
let rank_score = 1.0 / (i as f32 + 1.0);
// Note: Would need to extract ID from result
// For now, placeholder
("placeholder".to_string(), rank_score)
})
.collect(),
Err(_) => vec![], // Gracefully fallback to semantic-only
}
} else {
vec![]
};
// TODO: Implement OpenSearchClient.search() method
let lexical_scores: Vec<(String, f32)> = vec![];
// 3. Fuse with RRF
let fused = self.rrf.fuse(semantic_scores.clone(), lexical_scores.clone());