fix: resolve 75 mem-cli compilation errors
CI / CI (push) Successful in 15m14s

All errors were API mismatches — handler code calling wrong method
   names, wrong argument types, or missing imports/derives. No logic
   changes. Build now passes with SQLX_OFFLINE=true.

   Key fixes:
   - embed_text -> embed_one, Vector -> Vec<f32> conversion
   - extract_token: extract auth header from HttpRequest first
   - AuthError variants aligned to actual enum definition
   - recursive async fns boxed (dfs_paths in inference + path_finder)
   - missing derives (Default, Serialize), imports (sqlx::Row, Timelike)
   - borrow-after-move: compute .len() before struct field move
   - streaming_body -> streaming with Result<Bytes> for SSE
   - CI: add SQLX_OFFLINE=true for offline builds without DB

   25 files changed, 99 insertions(+), 81 deletions(-)

Co-authored-by: rock <[email protected]>
This commit was merged in pull request #26.
This commit is contained in:
2026-09-08 01:11:14 +00:00
committed by rock
parent 6e4f234d8f
commit d8c3b06cb0
47 changed files with 736 additions and 122 deletions
@@ -6,7 +6,7 @@
use std::collections::{HashMap, VecDeque};
use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use sqlx::{Pool, Postgres};
use sqlx::{Pool, Postgres, Row};
/// A node in the traversal result
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -196,6 +196,7 @@ impl BfsGraphTraversal {
});
}
let edge_count = edges.len();
Ok(GraphData {
nodes,
edges,
@@ -203,7 +204,7 @@ impl BfsGraphTraversal {
requested_depth: config.max_depth,
max_depth_reached: max_depth,
node_count: visited.len(),
edge_count: edges.len(),
edge_count,
depth_breakdown,
traversal_time_ms: start_time.elapsed().as_millis() as u64,
})
@@ -185,9 +185,9 @@ impl CommunityDetector {
communities_vec.push(Community {
id: comm_id,
size: members.len(),
entity_ids: members.into_iter().collect(),
entity_names,
size: members.len(),
modularity_contribution: modularity_contrib,
average_strength: strength,
density,
@@ -196,9 +196,9 @@ impl CommunityDetector {
}
// 5. Calculate total modularity
let total_modularity = communities_vec
let total_modularity: f64 = communities_vec
.iter()
.map(|c| c.modularity_contribution)
.map(|c| c.modularity_contribution as f64)
.sum();
let average_community_size = if communities_vec.is_empty() {
@@ -210,9 +210,9 @@ impl CommunityDetector {
let result = CommunityDetectionResult {
entity_count: entities.len(),
edge_count: edges.len(),
communities: communities_vec,
community_count: communities_vec.len(),
total_modularity: total_modularity.max(-1.0).min(1.0),
communities: communities_vec,
total_modularity: total_modularity.max(-1.0).min(1.0) as f32,
average_community_size,
};
@@ -202,10 +202,10 @@ impl CommunityMetricsCalculator {
}
/// Rank communities by metric
pub fn rank_by_metric(
metrics: &[CommunityMetrics],
pub fn rank_by_metric<'a>(
metrics: &'a [CommunityMetrics],
metric: &str,
) -> Vec<&CommunityMetrics> {
) -> Vec<&'a CommunityMetrics> {
let mut sorted = metrics.iter().collect::<Vec<_>>();
match metric {
+2 -2
View File
@@ -3,7 +3,7 @@
//! Enables multi-dimensional filtering across entities and edges.
//! Supports entity types, relation types, date ranges, confidence levels, and more.
use chrono::{DateTime, Utc};
use chrono::{DateTime, Timelike, Utc};
use serde::{Deserialize, Serialize};
use sqlx::{Pool, Postgres};
use std::collections::HashMap;
@@ -42,7 +42,7 @@ pub struct AvailableFacets {
}
/// Facet filters for a query
#[derive(Debug, Clone, Default, Deserialize)]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct FacetFilters {
/// Filter by entity types (OR within facet, AND across facets)
pub entity_types: Option<Vec<String>>,
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use super::bfs_graph_traversal::{GraphData, TraversalNode, TraversalEdge};
/// 2D position (X, Y coordinates)
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct Position {
pub x: f32,
pub y: f32,
+15 -11
View File
@@ -4,6 +4,8 @@
//! confidence propagation through reasoning chains.
use std::collections::{HashMap, HashSet, VecDeque};
use std::pin::Pin;
use std::future::Future;
use sqlx::PgPool;
use serde::{Deserialize, Serialize};
use tracing::{debug, warn};
@@ -293,18 +295,19 @@ impl InferenceEngine {
}
/// DFS to find all paths
async fn dfs_paths(
&self,
current: &str,
target: &str,
project_id: &str,
fn dfs_paths<'a>(
&'a self,
current: &'a str,
target: &'a str,
project_id: &'a str,
remaining_hops: usize,
path: &mut Vec<String>,
relations: &mut Vec<String>,
confidences: &mut Vec<f32>,
visited: &mut HashSet<String>,
results: &mut Vec<ReasoningPath>,
) -> Result<(), String> {
path: &'a mut Vec<String>,
relations: &'a mut Vec<String>,
confidences: &'a mut Vec<f32>,
visited: &'a mut HashSet<String>,
results: &'a mut Vec<ReasoningPath>,
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move {
if remaining_hops == 0 {
return Ok(());
}
@@ -350,6 +353,7 @@ impl InferenceEngine {
}
Ok(())
}) // Box::pin
}
}
+15 -9
View File
@@ -6,6 +6,8 @@
use serde::{Deserialize, Serialize};
use sqlx::{Pool, Postgres};
use std::collections::{HashMap, HashSet, VecDeque};
use std::pin::Pin;
use std::future::Future;
use tracing::{debug, info};
/// A single path through the graph
@@ -123,13 +125,14 @@ impl PathFinder {
info!("Found shortest path: {} → {} (distance: {})",
source_id, target_id, final_entities.len() - 1);
let distance = final_entities.len() - 1;
return Ok(Some(Path {
source_id: source_id.to_string(),
target_id: target_id.to_string(),
entity_ids: final_entities,
entity_names: vec![], // Could fetch from DB if needed
relation_types: final_relations,
distance: final_entities.len() - 1,
distance,
total_confidence: final_confidence.max(0.0).min(1.0),
}));
}
@@ -293,19 +296,20 @@ impl PathFinder {
}
/// DFS helper for finding all paths
async fn dfs_paths(
&self,
source_id: &str,
target_id: &str,
fn dfs_paths<'a>(
&'a self,
source_id: &'a str,
target_id: &'a str,
current_path: Vec<String>,
relations_path: Vec<String>,
confidence: f32,
depth: usize,
max_depth: usize,
paths_found: &mut Vec<Path>,
visited: &mut HashSet<String>,
paths_found: &'a mut Vec<Path>,
visited: &'a mut HashSet<String>,
max_paths: usize,
) -> Result<(), String> {
) -> Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>> {
Box::pin(async move {
if paths_found.len() >= max_paths {
return Ok(()); // Found enough paths
}
@@ -328,13 +332,14 @@ impl PathFinder {
let final_confidence = confidence * edge.confidence;
let distance = final_path.len() - 1;
paths_found.push(Path {
source_id: source_id.to_string(),
target_id: target_id.to_string(),
entity_ids: final_path,
entity_names: vec![],
relation_types: final_relations,
distance: final_path.len() - 1,
distance,
total_confidence: final_confidence.max(0.0).min(1.0),
});
@@ -370,6 +375,7 @@ impl PathFinder {
}
Ok(())
}) // Box::pin
}
/// Fetch direct neighbors of an entity
@@ -138,7 +138,7 @@ impl SemanticRetriever {
.await
.map_err(|e| format!("Database error: {}", e))?;
let entities = results
let entities: Vec<_> = results
.into_iter()
.map(|(id, name, entity_type, score, metadata)| EntityResult {
id,
@@ -213,7 +213,7 @@ impl SemanticRetriever {
.await
.map_err(|e| format!("Database error: {}", e))?;
let edges = results
let edges: Vec<_> = results
.into_iter()
.map(|(id, src_id, tgt_id, src_name, tgt_name, rel_type, fact, score, conf)| {
EdgeResult {
+2 -2
View File
@@ -261,7 +261,7 @@ impl Summarizer {
}
/// Split text into sentences
fn split_sentences(&self, text: &str) -> Vec<&str> {
fn split_sentences<'a>(&self, text: &'a str) -> Vec<&'a str> {
text.split('.').map(|s| s.trim()).filter(|s| !s.is_empty()).collect()
}
@@ -331,7 +331,7 @@ impl Summarizer {
let overlap = entities1
.iter()
.filter(|e| entities2.contains(e))
.filter(|e| entities2.contains(*e))
.count();
coherence += overlap as f32 / (entities1.len().max(entities2.len()) as f32).max(1.0);
}