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:
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user