feat: add fake LLM provider for testing
Set LLM_PROVIDER=fake to use mock responses without calling real LLM. Useful for API flow tests, action engine tests, UI event tests.
This commit is contained in:
parent
1a2781a85f
commit
e947e248e2
3 changed files with 87 additions and 15 deletions
14
src/main.rs
14
src/main.rs
|
|
@ -16,8 +16,9 @@ use std::sync::Arc;
|
|||
|
||||
use config::AppConfig;
|
||||
use providers::help_center::nxtgauge_help_center_provider::NxtgaugeHelpCenterProvider;
|
||||
use providers::llm::ollama_provider::OllamaAiProvider;
|
||||
use providers::llm::fake_provider::FakeAiProvider;
|
||||
use providers::llm::litellm_provider::LiteLLMProvider;
|
||||
use providers::llm::ollama_provider::OllamaAiProvider;
|
||||
use providers::tickets::nxtgauge_ticket_provider::NxtgaugeTicketProvider;
|
||||
use providers::llm::ai_provider::AiProvider;
|
||||
use retrieval::embeddings::ollama_embedding_provider::OllamaEmbeddingProvider;
|
||||
|
|
@ -38,19 +39,26 @@ async fn main() {
|
|||
}
|
||||
};
|
||||
|
||||
let ai_provider: Arc<dyn AiProvider> = if cfg.llm_provider == "litellm" {
|
||||
let ai_provider: Arc<dyn AiProvider> = match cfg.llm_provider.as_str() {
|
||||
"fake" => {
|
||||
info!("Using Fake AI provider for testing");
|
||||
Arc::new(FakeAiProvider::new()) as Arc<dyn AiProvider>
|
||||
}
|
||||
"litellm" => {
|
||||
info!("Using LiteLLM provider with model {}", cfg.litellm_model);
|
||||
Arc::new(LiteLLMProvider::new(
|
||||
cfg.litellm_base_url.clone(),
|
||||
cfg.litellm_api_key.clone(),
|
||||
cfg.litellm_model.clone(),
|
||||
)) as Arc<dyn AiProvider>
|
||||
} else {
|
||||
}
|
||||
_ => {
|
||||
info!("Using Ollama provider with model {}", cfg.ollama_chat_model);
|
||||
Arc::new(OllamaAiProvider::new(
|
||||
cfg.ollama_base_url.clone(),
|
||||
cfg.ollama_chat_model.clone(),
|
||||
)) as Arc<dyn AiProvider>
|
||||
}
|
||||
};
|
||||
|
||||
let _embedding_provider = Arc::new(OllamaEmbeddingProvider::new(
|
||||
|
|
|
|||
63
src/providers/llm/fake_provider.rs
Normal file
63
src/providers/llm/fake_provider.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use async_trait::async_trait;
|
||||
|
||||
use crate::{error::AppError, providers::llm::ai_provider::AiProvider};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FakeAiProvider {
|
||||
responses: std::collections::HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl FakeAiProvider {
|
||||
pub fn new() -> Self {
|
||||
let mut responses = std::collections::HashMap::new();
|
||||
responses.insert(
|
||||
"job description".to_string(),
|
||||
"## React Developer\n\n**Summary**: We are looking for a skilled React Developer to join our team.\n\n**Responsibilities**:\n- Develop new user-facing features\n- Build reusable components\n- Collaborate with cross-functional teams\n\n**Requirements**:\n- 2+ years of React experience\n- TypeScript proficiency\n- Strong problem-solving skills".to_string(),
|
||||
);
|
||||
responses.insert(
|
||||
"cover letter".to_string(),
|
||||
"Dear Hiring Manager,\n\nI am excited to apply for this position. With my experience in React development and passion for creating user-friendly applications, I believe I would be a great fit for your team.\n\nPlease consider my application.\n\nBest regards".to_string(),
|
||||
);
|
||||
responses.insert(
|
||||
"ticket".to_string(),
|
||||
"Support ticket created successfully. Our team will respond within 24 hours.".to_string(),
|
||||
);
|
||||
responses.insert(
|
||||
"help".to_string(),
|
||||
"I found some helpful articles that might answer your question. You can also contact our support team for further assistance.".to_string(),
|
||||
);
|
||||
responses.insert(
|
||||
"default".to_string(),
|
||||
"I'm here to help! Could you please provide more details about what you need?".to_string(),
|
||||
);
|
||||
Self { responses }
|
||||
}
|
||||
|
||||
pub fn with_response(mut self, trigger: &str, response: &str) -> Self {
|
||||
self.responses.insert(trigger.to_string(), response.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
fn get_response(&self, prompt: &str) -> String {
|
||||
let prompt_lower = prompt.to_lowercase();
|
||||
for (key, value) in &self.responses {
|
||||
if prompt_lower.contains(&key.to_lowercase()) {
|
||||
return value.clone();
|
||||
}
|
||||
}
|
||||
self.responses.get("default").cloned().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FakeAiProvider {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AiProvider for FakeAiProvider {
|
||||
async fn complete(&self, _system_prompt: &str, user_prompt: &str) -> Result<String, AppError> {
|
||||
Ok(self.get_response(user_prompt))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod ai_provider;
|
||||
pub mod ollama_provider;
|
||||
pub mod fake_provider;
|
||||
pub mod litellm_provider;
|
||||
pub mod ollama_provider;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue