mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-23 09:18:36 +02:00
storing nodes
This commit is contained in:
@@ -14,7 +14,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
info!("Starting RabbitMQ consumer");
|
info!("Starting RabbitMQ consumer");
|
||||||
|
|
||||||
// Set up RabbitMQ config
|
// Set up RabbitMQ config
|
||||||
let config = RabbitMQConfig {
|
let config = RabbitMQConfig {
|
||||||
amqp_addr: "amqp://localhost".to_string(),
|
amqp_addr: "amqp://localhost".to_string(),
|
||||||
exchange: "my_exchange".to_string(),
|
exchange: "my_exchange".to_string(),
|
||||||
queue: "my_queue".to_string(),
|
queue: "my_queue".to_string(),
|
||||||
|
|||||||
@@ -322,6 +322,7 @@ impl FileInfo {
|
|||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// * `Result<(), FileError>` - Empty result or an error.
|
/// * `Result<(), FileError>` - Empty result or an error.
|
||||||
|
|
||||||
async fn create_record(file_info: &FileInfo, db_client: &SurrealDbClient) -> Result<(), FileError> {
|
async fn create_record(file_info: &FileInfo, db_client: &SurrealDbClient) -> Result<(), FileError> {
|
||||||
// Create the record
|
// Create the record
|
||||||
let _created: Option<Record> = db_client
|
let _created: Option<Record> = db_client
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use std::collections::HashMap;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// Represents a generic knowledge entity in the graph.
|
/// Represents a generic knowledge entity in the graph.
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct KnowledgeEntity {
|
pub struct KnowledgeEntity {
|
||||||
pub id: Uuid, // Generated in Rust
|
pub id: String, // Generated in Rust
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub entity_type: KnowledgeEntityType,
|
pub entity_type: KnowledgeEntityType,
|
||||||
pub source_id: Option<Uuid>, // Links to FileInfo or TextContent
|
pub source_id: String, // Links to FileInfo or TextContent
|
||||||
pub metadata: Option<serde_json::Value>, // Additional metadata
|
pub metadata: Option<serde_json::Value>, // Additional metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,12 +48,6 @@ pub struct KnowledgeRelationship {
|
|||||||
pub metadata: Option<serde_json::Value>, // Additional metadata
|
pub metadata: Option<serde_json::Value>, // Additional metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::utils::llm::LLMGraphAnalysisResult;
|
|
||||||
use crate::utils::llm::LLMKnowledgeEntity;
|
|
||||||
use crate::utils::llm::LLMRelationship;
|
|
||||||
|
|
||||||
/// Intermediate struct to hold mapping between LLM keys and generated IDs.
|
/// Intermediate struct to hold mapping between LLM keys and generated IDs.
|
||||||
pub struct GraphMapper {
|
pub struct GraphMapper {
|
||||||
pub key_to_id: HashMap<String, Uuid>,
|
pub key_to_id: HashMap<String, Uuid>,
|
||||||
@@ -77,28 +72,3 @@ impl GraphMapper {
|
|||||||
self.key_to_id.get(key)
|
self.key_to_id.get(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&LLMKnowledgeEntity> for KnowledgeEntity {
|
|
||||||
fn from(llm_entity: &LLMKnowledgeEntity) -> Self {
|
|
||||||
KnowledgeEntity {
|
|
||||||
id: Uuid::new_v4(),
|
|
||||||
name: llm_entity.name.clone(),
|
|
||||||
description: llm_entity.description.clone(),
|
|
||||||
entity_type: KnowledgeEntityType::from(llm_entity.entity_type.clone()),
|
|
||||||
source_id: None, // To be linked externally if needed
|
|
||||||
metadata: None, // Populate if metadata is provided
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&LLMRelationship> for KnowledgeRelationship {
|
|
||||||
fn from(llm_rel: &LLMRelationship) -> Self {
|
|
||||||
KnowledgeRelationship {
|
|
||||||
id: Uuid::new_v4(),
|
|
||||||
in_: Uuid::nil(), // Placeholder; to be set after mapping
|
|
||||||
out: Uuid::nil(), // Placeholder; to be set after mapping
|
|
||||||
relationship_type: llm_rel.type_.clone(),
|
|
||||||
metadata: None, // Populate if metadata is provided
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tracing::info;
|
use surrealdb::RecordId;
|
||||||
|
use tracing::{debug, info};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::{models::file_info::FileInfo, utils::llm::create_json_ld};
|
use crate::{models::file_info::FileInfo, surrealdb::{SurrealDbClient, SurrealError}, utils::llm::create_json_ld};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use super::graph_entities::{KnowledgeEntity, KnowledgeRelationship};
|
use super::graph_entities::{KnowledgeEntity, KnowledgeRelationship};
|
||||||
@@ -16,11 +17,23 @@ pub struct TextContent {
|
|||||||
pub category: String,
|
pub category: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Deserialize)]
|
||||||
|
struct Record {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
id: RecordId,
|
||||||
|
}
|
||||||
|
|
||||||
/// Error types for processing `TextContent`.
|
/// Error types for processing `TextContent`.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ProcessingError {
|
pub enum ProcessingError {
|
||||||
#[error("LLM processing error: {0}")]
|
#[error("LLM processing error: {0}")]
|
||||||
LLMError(String),
|
LLMError(String),
|
||||||
|
|
||||||
|
#[error("SurrealDB error: {0}")]
|
||||||
|
SurrealError(#[from] SurrealError),
|
||||||
|
|
||||||
|
#[error("SurrealDb error: {0}")]
|
||||||
|
SurrealDbError(#[from] surrealdb::Error),
|
||||||
|
|
||||||
#[error("Graph DB storage error: {0}")]
|
#[error("Graph DB storage error: {0}")]
|
||||||
GraphDBError(String),
|
GraphDBError(String),
|
||||||
@@ -36,15 +49,15 @@ pub enum ProcessingError {
|
|||||||
impl TextContent {
|
impl TextContent {
|
||||||
/// Processes the `TextContent` by sending it to an LLM, storing in a graph DB, and vector DB.
|
/// Processes the `TextContent` by sending it to an LLM, storing in a graph DB, and vector DB.
|
||||||
pub async fn process(&self) -> Result<(), ProcessingError> {
|
pub async fn process(&self) -> Result<(), ProcessingError> {
|
||||||
// let client = Neo4jClient::new("127.0.0.1:7687", "neo4j", "neo4j").await.expect("Failed to create Neo4j client");
|
// Store TextContent
|
||||||
|
|
||||||
// Step 1: Send to LLM for analysis
|
// Step 1: Send to LLM for analysis
|
||||||
let analysis = create_json_ld(&self.category, &self.instructions, &self.text).await?;
|
let analysis = create_json_ld(&self.category, &self.instructions, &self.text).await?;
|
||||||
// info!("{:#?}", &analysis);
|
// info!("{:#?}", &analysis);
|
||||||
|
|
||||||
|
|
||||||
// Step 2: Convert LLM analysis to database entities
|
// Step 2: Convert LLM analysis to database entities
|
||||||
let (entities, relationships) = analysis.to_database_entities();
|
let (entities, relationships) = analysis.to_database_entities(&self.id);
|
||||||
|
|
||||||
// Step 3: Store in database
|
// Step 3: Store in database
|
||||||
self.store_in_graph_db(entities, relationships).await?;
|
self.store_in_graph_db(entities, relationships).await?;
|
||||||
@@ -61,8 +74,18 @@ impl TextContent {
|
|||||||
entities: Vec<KnowledgeEntity>,
|
entities: Vec<KnowledgeEntity>,
|
||||||
relationships: Vec<KnowledgeRelationship>
|
relationships: Vec<KnowledgeRelationship>
|
||||||
) -> Result<(), ProcessingError> {
|
) -> Result<(), ProcessingError> {
|
||||||
for entity in entities {
|
let db_client = SurrealDbClient::new().await?;
|
||||||
|
|
||||||
|
for entity in entities {
|
||||||
info!("{:?}", entity);
|
info!("{:?}", entity);
|
||||||
|
|
||||||
|
let _created: Option<Record> = db_client
|
||||||
|
.client
|
||||||
|
.create(("knowledge_entity", &entity.id.to_string()))
|
||||||
|
.content(entity)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
info!("{:?}",_created);
|
||||||
}
|
}
|
||||||
|
|
||||||
for relationship in relationships {
|
for relationship in relationships {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ pub struct LLMGraphAnalysisResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LLMGraphAnalysisResult {
|
impl LLMGraphAnalysisResult {
|
||||||
pub fn to_database_entities(&self) -> (Vec<KnowledgeEntity>, Vec<KnowledgeRelationship>) {
|
pub fn to_database_entities(&self, source_id: &Uuid) -> (Vec<KnowledgeEntity>, Vec<KnowledgeRelationship>) {
|
||||||
let mut mapper = GraphMapper::new();
|
let mut mapper = GraphMapper::new();
|
||||||
|
|
||||||
// First pass: Create all entities and map their keys to UUIDs
|
// First pass: Create all entities and map their keys to UUIDs
|
||||||
@@ -47,11 +47,11 @@ impl LLMGraphAnalysisResult {
|
|||||||
.map(|llm_entity| {
|
.map(|llm_entity| {
|
||||||
let id = mapper.assign_id(&llm_entity.key);
|
let id = mapper.assign_id(&llm_entity.key);
|
||||||
KnowledgeEntity {
|
KnowledgeEntity {
|
||||||
id,
|
id: id.to_string(),
|
||||||
name: llm_entity.name.clone(),
|
name: llm_entity.name.clone(),
|
||||||
description: llm_entity.description.clone(),
|
description: llm_entity.description.clone(),
|
||||||
entity_type: KnowledgeEntityType::from(llm_entity.entity_type.clone()),
|
entity_type: KnowledgeEntityType::from(llm_entity.entity_type.clone()),
|
||||||
source_id: None,
|
source_id: source_id.to_string(),
|
||||||
metadata: None,
|
metadata: None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user