mirror of
https://github.com/perstarkse/minne.git
synced 2026-06-30 10:01:40 +02:00
refactor: better separation of dependencies to crates
node stuff to html crate only
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
use config::{Config, ConfigError, File};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AppConfig {
|
||||
pub surrealdb_address: String,
|
||||
pub surrealdb_username: String,
|
||||
pub surrealdb_password: String,
|
||||
pub surrealdb_namespace: String,
|
||||
pub surrealdb_database: String,
|
||||
}
|
||||
|
||||
pub fn get_config() -> Result<AppConfig, ConfigError> {
|
||||
let config = Config::builder()
|
||||
.add_source(File::with_name("config"))
|
||||
.build()?;
|
||||
|
||||
Ok(AppConfig {
|
||||
surrealdb_address: config.get_string("SURREALDB_ADDRESS")?,
|
||||
surrealdb_username: config.get_string("SURREALDB_USERNAME")?,
|
||||
surrealdb_password: config.get_string("SURREALDB_PASSWORD")?,
|
||||
surrealdb_namespace: config.get_string("SURREALDB_NAMESPACE")?,
|
||||
surrealdb_database: config.get_string("SURREALDB_DATABASE")?,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
use async_openai::types::CreateEmbeddingRequestArgs;
|
||||
|
||||
use crate::error::AppError;
|
||||
/// Generates an embedding vector for the given input text using OpenAI's embedding model.
|
||||
///
|
||||
/// This function takes a text input and converts it into a numerical vector representation (embedding)
|
||||
/// using OpenAI's text-embedding-3-small model. These embeddings can be used for semantic similarity
|
||||
/// comparisons, vector search, and other natural language processing tasks.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client`: The OpenAI client instance used to make API requests.
|
||||
/// * `input`: The text string to generate embeddings for.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a `Result` containing either:
|
||||
/// * `Ok(Vec<f32>)`: A vector of 32-bit floating point numbers representing the text embedding
|
||||
/// * `Err(ProcessingError)`: An error if the embedding generation fails
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function can return a `AppError` in the following cases:
|
||||
/// * If the OpenAI API request fails
|
||||
/// * If the request building fails
|
||||
/// * If no embedding data is received in the response
|
||||
pub async fn generate_embedding(
|
||||
client: &async_openai::Client<async_openai::config::OpenAIConfig>,
|
||||
input: &str,
|
||||
) -> Result<Vec<f32>, AppError> {
|
||||
let request = CreateEmbeddingRequestArgs::default()
|
||||
.model("text-embedding-3-small")
|
||||
.input([input])
|
||||
.build()?;
|
||||
|
||||
// Send the request to OpenAI
|
||||
let response = client.embeddings().create(request).await?;
|
||||
|
||||
// Extract the embedding vector
|
||||
let embedding: Vec<f32> = response
|
||||
.data
|
||||
.first()
|
||||
.ok_or_else(|| AppError::LLMParsing("No embedding data received".into()))?
|
||||
.embedding
|
||||
.clone();
|
||||
|
||||
Ok(embedding)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod config;
|
||||
pub mod embedding;
|
||||
pub mod template_engine;
|
||||
@@ -0,0 +1,96 @@
|
||||
pub use minijinja::{path_loader, Environment, Value};
|
||||
pub use minijinja_autoreload::AutoReloader;
|
||||
pub use minijinja_contrib;
|
||||
pub use minijinja_embed;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait ProvidesTemplateEngine {
|
||||
fn template_engine(&self) -> &Arc<TemplateEngine>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum TemplateEngine {
|
||||
// Use AutoReload for debug builds (debug_assertions is true)
|
||||
#[cfg(debug_assertions)]
|
||||
AutoReload(Arc<AutoReloader>),
|
||||
// Use Embedded for release builds (debug_assertions is false)
|
||||
#[cfg(not(debug_assertions))]
|
||||
Embedded(Arc<Environment<'static>>),
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! create_template_engine {
|
||||
// Macro takes the relative path to the templates dir as input
|
||||
($relative_path:expr) => {{
|
||||
// Code for debug builds (AutoReload)
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
// These lines execute in the CALLING crate's context
|
||||
let crate_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
let template_path = crate_dir.join($relative_path);
|
||||
let reloader = $crate::utils::template_engine::AutoReloader::new(move |notifier| {
|
||||
let mut env = $crate::utils::template_engine::Environment::new();
|
||||
env.set_loader($crate::utils::template_engine::path_loader(&template_path));
|
||||
notifier.set_fast_reload(true);
|
||||
notifier.watch_path(&template_path, true);
|
||||
// Add contrib filters/functions
|
||||
$crate::utils::template_engine::minijinja_contrib::add_to_environment(&mut env);
|
||||
Ok(env)
|
||||
});
|
||||
$crate::utils::template_engine::TemplateEngine::AutoReload(std::sync::Arc::new(
|
||||
reloader,
|
||||
))
|
||||
}
|
||||
// Code for release builds (Embedded)
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
// These lines also execute in the CALLING crate's context
|
||||
let mut env = $crate::utils::template_engine::Environment::new();
|
||||
$crate::utils::template_engine::minijinja_embed::load_templates!(&mut env);
|
||||
// Add contrib filters/functions
|
||||
$crate::utils::template_engine::minijinja_contrib::add_to_environment(&mut env);
|
||||
$crate::utils::template_engine::TemplateEngine::Embedded(std::sync::Arc::new(env))
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
impl TemplateEngine {
|
||||
pub fn render(&self, name: &str, ctx: &Value) -> Result<String, minijinja::Error> {
|
||||
match self {
|
||||
// Only compile this arm for debug builds
|
||||
#[cfg(debug_assertions)]
|
||||
TemplateEngine::AutoReload(reloader) => {
|
||||
let env = reloader.acquire_env()?;
|
||||
env.get_template(name)?.render(ctx)
|
||||
}
|
||||
// Only compile this arm for release builds
|
||||
#[cfg(not(debug_assertions))]
|
||||
TemplateEngine::Embedded(env) => env.get_template(name)?.render(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_block(
|
||||
&self,
|
||||
template_name: &str,
|
||||
block_name: &str,
|
||||
context: &Value,
|
||||
) -> Result<String, minijinja::Error> {
|
||||
match self {
|
||||
// Only compile this arm for debug builds
|
||||
#[cfg(debug_assertions)]
|
||||
TemplateEngine::AutoReload(reloader) => {
|
||||
let env = reloader.acquire_env()?;
|
||||
let template = env.get_template(template_name)?;
|
||||
let mut state = template.eval_to_state(context)?;
|
||||
state.render_block(block_name)
|
||||
}
|
||||
// Only compile this arm for release builds
|
||||
#[cfg(not(debug_assertions))]
|
||||
TemplateEngine::Embedded(env) => {
|
||||
let template = env.get_template(template_name)?;
|
||||
let mut state = template.eval_to_state(context)?;
|
||||
state.render_block(block_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user