This commit is contained in:
parent
e17e0e36a0
commit
9a4bab6de6
8 changed files with 32 additions and 68 deletions
35
src/main.rs
35
src/main.rs
|
@ -3,13 +3,12 @@ use actix_web::http::header;
|
||||||
use actix_web::{web, App, HttpServer};
|
use actix_web::{web, App, HttpServer};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
|
||||||
use services::script
|
|
||||||
::*;
|
|
||||||
use services::config::*;
|
use services::config::*;
|
||||||
use services::email::*;
|
use services::email::*;
|
||||||
use services::file::*;
|
use services::file::*;
|
||||||
use services::state::*;
|
|
||||||
use services::llm::*;
|
use services::llm::*;
|
||||||
|
use services::script::*;
|
||||||
|
use services::state::*;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
//use services:: find::*;
|
//use services:: find::*;
|
||||||
mod services;
|
mod services;
|
||||||
|
@ -35,37 +34,29 @@ async fn main() -> std::io::Result<()> {
|
||||||
minio_client: minio_client.into(),
|
minio_client: minio_client.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let script_service = ScriptService::new(&app_state.clone());
|
let script_service = ScriptService::new(&app_state.clone());
|
||||||
|
|
||||||
let script = r#"
|
const TEXT : &str = include_str!("prompts/business/data-enrichment.bas");
|
||||||
let items = FIND "gb.rob", "ACTION=EMUL1"
|
|
||||||
FOR EACH item IN items
|
match script_service.compile(TEXT) {
|
||||||
let text = GET "example.com"
|
Ok(ast) => match script_service.run(&ast) {
|
||||||
PRINT item.name
|
Ok(result) => println!("Script executed successfully: {:?}", result),
|
||||||
NEXT item "#;
|
Err(e) => eprintln!("Error executing script: {}", e),
|
||||||
|
|
||||||
match script_service.compile(script) {
|
|
||||||
Ok(ast) => {
|
|
||||||
match script_service.run(&ast) {
|
|
||||||
Ok(result) => println!("Script executed successfully: {:?}", result),
|
|
||||||
Err(e) => eprintln!("Error executing script: {}", e),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Err(e) => eprintln!("Error compiling script: {}", e),
|
Err(e) => eprintln!("Error compiling script: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Start HTTP server
|
// Start HTTP server
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let cors = Cors::default()
|
let cors = Cors::default()
|
||||||
.allowed_origin("http://localhost:3000") // Your Next.js port
|
.send_wildcard()
|
||||||
|
.allowed_origin("*")
|
||||||
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
|
.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])
|
||||||
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
|
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
|
||||||
.allowed_header(header::CONTENT_TYPE)
|
.allowed_header(header::CONTENT_TYPE)
|
||||||
.max_age(3600);
|
.max_age(3600);
|
||||||
App::new()
|
App::new()
|
||||||
//.wrap(cors)
|
.wrap(cors)
|
||||||
.app_data(app_state.clone())
|
.app_data(app_state.clone())
|
||||||
.service(upload_file)
|
.service(upload_file)
|
||||||
.service(list_file)
|
.service(list_file)
|
||||||
|
|
5
src/prompts/business/data-enrichment.bas
Normal file
5
src/prompts/business/data-enrichment.bas
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
let items = FIND "gb.rob", "ACTION=EMUL1"
|
||||||
|
FOR EACH item IN items
|
||||||
|
let text = GET "example.com"
|
||||||
|
PRINT item.name
|
||||||
|
NEXT item
|
|
@ -2,7 +2,7 @@ pub mod config;
|
||||||
|
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod email;
|
pub mod email;
|
||||||
pub mod find;
|
pub mod keywords;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod llm;
|
pub mod llm;
|
||||||
pub mod script;
|
pub mod script;
|
|
@ -42,16 +42,12 @@ pub struct EmailConfig {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub reject_unauthorized: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AIConfig {
|
pub struct AIConfig {
|
||||||
pub image_model: String,
|
|
||||||
pub embedding_model: String,
|
|
||||||
pub instance: String,
|
pub instance: String,
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub llm_model: String,
|
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub endpoint: String,
|
pub endpoint: String,
|
||||||
}
|
}
|
||||||
|
@ -124,18 +120,11 @@ impl AppConfig {
|
||||||
.expect("EMAIL_PORT must be a number"),
|
.expect("EMAIL_PORT must be a number"),
|
||||||
username: env::var("EMAIL_USER").expect("EMAIL_USER not set"),
|
username: env::var("EMAIL_USER").expect("EMAIL_USER not set"),
|
||||||
password: env::var("EMAIL_PASS").expect("EMAIL_PASS not set"),
|
password: env::var("EMAIL_PASS").expect("EMAIL_PASS not set"),
|
||||||
reject_unauthorized: env::var("EMAIL_REJECT_UNAUTHORIZED")
|
|
||||||
.unwrap_or_else(|_| "false".to_string())
|
|
||||||
.parse()
|
|
||||||
.unwrap_or(false),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ai = AIConfig {
|
let ai = AIConfig {
|
||||||
image_model: env::var("AI_IMAGE_MODEL").expect("AI_IMAGE_MODEL not set"),
|
|
||||||
embedding_model: env::var("AI_EMBEDDING_MODEL").expect("AI_EMBEDDING_MODEL not set"),
|
|
||||||
instance: env::var("AI_INSTANCE").expect("AI_INSTANCE not set"),
|
instance: env::var("AI_INSTANCE").expect("AI_INSTANCE not set"),
|
||||||
key: env::var("AI_KEY").expect("AI_KEY not set"),
|
key: env::var("AI_KEY").expect("AI_KEY not set"),
|
||||||
llm_model: env::var("AI_LLM_MODEL").expect("AI_LLM_MODEL not set"),
|
|
||||||
version: env::var("AI_VERSION").expect("AI_VERSION not set"),
|
version: env::var("AI_VERSION").expect("AI_VERSION not set"),
|
||||||
endpoint: env::var("AI_ENDPOINT").expect("AI_ENDPOINT not set"),
|
endpoint: env::var("AI_ENDPOINT").expect("AI_ENDPOINT not set"),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use sqlx::postgres::PgPoolOptions;
|
|
||||||
use sqlx::Column; // Required for .name() method
|
use sqlx::Column; // Required for .name() method
|
||||||
use sqlx::TypeInfo; // Required for .type_info() method
|
use sqlx::TypeInfo; // Required for .type_info() method
|
||||||
use sqlx::{postgres::PgRow, PgPool, Row};
|
use sqlx::{postgres::PgRow, PgPool, Row};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn execute_find(
|
pub async fn execute_find(
|
1
src/services/keywords/mod.rs
Normal file
1
src/services/keywords/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod find;
|
|
@ -16,7 +16,6 @@ use langchain_rust::{
|
||||||
template_fstring,
|
template_fstring,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
use crate::services::{config::AIConfig, state::AppState};
|
use crate::services::{config::AIConfig, state::AppState};
|
||||||
|
|
||||||
pub fn from_config(config: &AIConfig) -> AzureConfig {
|
pub fn from_config(config: &AIConfig) -> AzureConfig {
|
||||||
|
@ -30,9 +29,8 @@ pub fn from_config(config: &AIConfig) -> AzureConfig {
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
struct ChatRequest {
|
struct ChatRequest {
|
||||||
input: String,
|
input: String,
|
||||||
context: String,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Serialize)]
|
#[derive(serde::Serialize)]
|
||||||
struct ChatResponse {
|
struct ChatResponse {
|
||||||
text: String,
|
text: String,
|
||||||
|
@ -58,11 +56,14 @@ pub async fn chat(
|
||||||
// Parse the context JSON
|
// Parse the context JSON
|
||||||
let context: serde_json::Value = match serde_json::from_str(&request) {
|
let context: serde_json::Value = match serde_json::from_str(&request) {
|
||||||
Ok(ctx) => ctx,
|
Ok(ctx) => ctx,
|
||||||
Err(_) => serde_json::json!({})
|
Err(_) => serde_json::json!({}),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check view type and prepare appropriate prompt
|
// Check view type and prepare appropriate prompt
|
||||||
let view_type = context.get("viewType").and_then(|v| v.as_str()).unwrap_or("");
|
let view_type = context
|
||||||
|
.get("viewType")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
.unwrap_or("");
|
||||||
let (prompt, might_trigger_action) = match view_type {
|
let (prompt, might_trigger_action) = match view_type {
|
||||||
"email" => (
|
"email" => (
|
||||||
format!(
|
format!(
|
||||||
|
@ -109,7 +110,6 @@ pub async fn chat_stream(
|
||||||
let azure_config = from_config(&state.config.clone().unwrap().ai);
|
let azure_config = from_config(&state.config.clone().unwrap().ai);
|
||||||
let open_ai = OpenAI::new(azure_config);
|
let open_ai = OpenAI::new(azure_config);
|
||||||
|
|
||||||
|
|
||||||
let prompt = message_formatter![
|
let prompt = message_formatter![
|
||||||
fmt_message!(Message::new_system_message(
|
fmt_message!(Message::new_system_message(
|
||||||
"You are world class technical documentation writer."
|
"You are world class technical documentation writer."
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
use anyhow::Error;
|
use rhai::{Array, Dynamic, Engine};
|
||||||
use rhai::module_resolvers::StaticModuleResolver;
|
use rhai::{EvalAltResult};
|
||||||
use rhai::{Array, Dynamic, Engine, FnPtr, Scope};
|
|
||||||
use rhai::{EvalAltResult, ImmutableString, LexError, ParseError, ParseErrorType, Position};
|
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use smartstring::SmartString;
|
use smartstring::SmartString;
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use crate::services::find::execute_find;
|
use crate::services::keywords::find::execute_find;
|
||||||
use crate::services::state::AppState;
|
use crate::services::state::AppState;
|
||||||
|
|
||||||
pub struct ScriptService {
|
pub struct ScriptService {
|
||||||
engine: Engine,
|
engine: Engine,
|
||||||
module_resolver: StaticModuleResolver,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn json_value_to_dynamic(value: &Value) -> Dynamic {
|
fn json_value_to_dynamic(value: &Value) -> Dynamic {
|
||||||
|
@ -58,8 +55,7 @@ fn to_array(value: Dynamic) -> Array {
|
||||||
impl ScriptService {
|
impl ScriptService {
|
||||||
pub fn new(state: &AppState) -> Self {
|
pub fn new(state: &AppState) -> Self {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
let module_resolver = StaticModuleResolver::new();
|
|
||||||
|
|
||||||
// Configure engine for BASIC-like syntax
|
// Configure engine for BASIC-like syntax
|
||||||
engine.set_allow_anonymous_fn(true);
|
engine.set_allow_anonymous_fn(true);
|
||||||
engine.set_allow_looping(true);
|
engine.set_allow_looping(true);
|
||||||
|
@ -110,7 +106,7 @@ impl ScriptService {
|
||||||
|
|
||||||
for item in array {
|
for item in array {
|
||||||
// Push the loop variable into the scope
|
// Push the loop variable into the scope
|
||||||
context.scope_mut().push(loop_var.clone(), item);
|
context.scope_mut().push(loop_var, item);
|
||||||
|
|
||||||
// Evaluate the block with the current scope
|
// Evaluate the block with the current scope
|
||||||
match context.eval_expression_tree(block) {
|
match context.eval_expression_tree(block) {
|
||||||
|
@ -299,7 +295,6 @@ impl ScriptService {
|
||||||
|
|
||||||
ScriptService {
|
ScriptService {
|
||||||
engine,
|
engine,
|
||||||
module_resolver,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,19 +398,4 @@ impl ScriptService {
|
||||||
pub fn run(&self, ast: &rhai::AST) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn run(&self, ast: &rhai::AST) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
self.engine.eval_ast(ast)
|
self.engine.eval_ast(ast)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_web_service(
|
|
||||||
&self,
|
|
||||||
endpoint: &str,
|
|
||||||
data: HashMap<String, String>,
|
|
||||||
) -> Result<String, Box<EvalAltResult>> {
|
|
||||||
Ok(format!("Called {} with {:?}", endpoint, data))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a BASIC-style script without semicolons
|
|
||||||
pub fn execute_basic_script(&self, script: &str) -> Result<Dynamic, Box<EvalAltResult>> {
|
|
||||||
let processed = self.preprocess_basic_script(script);
|
|
||||||
let ast = self.engine.compile(&processed)?;
|
|
||||||
self.run(&ast)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue