introduce agent that would respond to the user

This commit is contained in:
Adil Hafeez 2025-09-23 17:35:57 -07:00
parent 6dd99a6c05
commit 1cd5bb4235
No known key found for this signature in database
GPG key ID: 9B18EF7691369645
6 changed files with 21 additions and 39 deletions

View file

@ -122,8 +122,8 @@ async fn handle_agent_chat(
.await?; .await?;
// Get terminal agent and send final response // Get terminal agent and send final response
let terminal_agent_name = selected_agent.filter_chain.last().unwrap(); let terminal_agent_name = selected_agent.agent;
let terminal_agent = agent_map.get(terminal_agent_name).unwrap(); let terminal_agent = agent_map.get(&terminal_agent_name).unwrap();
debug!("Processing terminal agent: {}", terminal_agent_name); debug!("Processing terminal agent: {}", terminal_agent_name);
debug!("Terminal agent details: {:?}", terminal_agent); debug!("Terminal agent details: {:?}", terminal_agent);

View file

@ -165,6 +165,7 @@ mod tests {
fn create_test_agent(name: &str, description: &str, is_default: bool) -> AgentPipeline { fn create_test_agent(name: &str, description: &str, is_default: bool) -> AgentPipeline {
AgentPipeline { AgentPipeline {
name: name.to_string(), name: name.to_string(),
agent: name.to_string(),
description: Some(description.to_string()), description: Some(description.to_string()),
default: Some(is_default), default: Some(is_default),
filter_chain: vec![name.to_string()], filter_chain: vec![name.to_string()],

View file

@ -60,6 +60,7 @@ mod integration_tests {
let agent_pipeline = AgentPipeline { let agent_pipeline = AgentPipeline {
name: "test-pipeline".to_string(), name: "test-pipeline".to_string(),
agent: "terminal-agent".to_string(),
filter_chain: vec!["filter-agent".to_string(), "terminal-agent".to_string()], filter_chain: vec!["filter-agent".to_string(), "terminal-agent".to_string()],
description: Some("Test pipeline".to_string()), description: Some("Test pipeline".to_string()),
default: Some(true), default: Some(true),
@ -97,10 +98,11 @@ mod integration_tests {
..Default::default() ..Default::default()
}; };
// Create a pipeline with only terminal agent to avoid network calls // Create a pipeline with empty filter chain to avoid network calls
let test_pipeline = AgentPipeline { let test_pipeline = AgentPipeline {
name: "test-pipeline".to_string(), name: "test-pipeline".to_string(),
filter_chain: vec!["terminal-agent".to_string()], agent: "terminal-agent".to_string(),
filter_chain: vec![], // Empty filter chain - no network calls needed
description: None, description: None,
default: None, default: None,
}; };
@ -110,9 +112,17 @@ mod integration_tests {
.process_filter_chain(&request, &test_pipeline, &agent_map, &headers) .process_filter_chain(&request, &test_pipeline, &agent_map, &headers)
.await; .await;
println!("Pipeline processing result: {:?}", result);
assert!(result.is_ok()); assert!(result.is_ok());
let processed_messages = result.unwrap(); let processed_messages = result.unwrap();
// With empty filter chain, should return the original messages unchanged
assert_eq!(processed_messages.len(), 1); assert_eq!(processed_messages.len(), 1);
if let MessageContent::Text(content) = &processed_messages[0].content {
assert_eq!(content, "Hello world!");
} else {
panic!("Expected text content");
}
// Test 4: Error Response Creation // Test 4: Error Response Creation
let error_response = ResponseHandler::create_bad_request("Test error"); let error_response = ResponseHandler::create_bad_request("Test error");

View file

@ -54,10 +54,7 @@ impl PipelineProcessor {
) -> Result<Vec<Message>, PipelineError> { ) -> Result<Vec<Message>, PipelineError> {
let mut chat_completions_history = initial_request.messages.clone(); let mut chat_completions_history = initial_request.messages.clone();
let filter_chain_without_terminal = for agent_name in &agent_pipeline.filter_chain {
&agent_pipeline.filter_chain[..agent_pipeline.filter_chain.len().saturating_sub(1)];
for agent_name in filter_chain_without_terminal {
debug!("Processing filter agent: {}", agent_name); debug!("Processing filter agent: {}", agent_name);
let agent = agent_map let agent = agent_map
@ -201,39 +198,13 @@ mod tests {
fn create_test_pipeline(agents: Vec<&str>) -> AgentPipeline { fn create_test_pipeline(agents: Vec<&str>) -> AgentPipeline {
AgentPipeline { AgentPipeline {
name: "test-pipeline".to_string(), name: "test-pipeline".to_string(),
agent: "test-agent".to_string(),
filter_chain: agents.iter().map(|s| s.to_string()).collect(), filter_chain: agents.iter().map(|s| s.to_string()).collect(),
description: None, description: None,
default: None, default: None,
} }
} }
#[tokio::test]
async fn test_process_empty_filter_chain() {
let processor = PipelineProcessor::default();
let agent_map = HashMap::new();
let request_headers = HeaderMap::new();
let initial_request = ChatCompletionsRequest {
messages: vec![create_test_message(Role::User, "Hello")],
model: "test-model".to_string(),
..Default::default()
};
// Pipeline with only terminal agent (no filter chain)
let pipeline = create_test_pipeline(vec!["terminal-agent"]);
let result = processor
.process_filter_chain(&initial_request, &pipeline, &agent_map, &request_headers)
.await;
assert!(result.is_ok());
let messages = result.unwrap();
assert_eq!(messages.len(), 1);
if let MessageContent::Text(text) = &messages[0].content {
assert_eq!(text, "Hello");
}
}
#[tokio::test] #[tokio::test]
async fn test_agent_not_found_error() { async fn test_agent_not_found_error() {
let processor = PipelineProcessor::default(); let processor = PipelineProcessor::default();

View file

@ -28,6 +28,7 @@ pub struct Agent {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentPipeline { pub struct AgentPipeline {
pub name: String, pub name: String,
pub agent: String,
pub default: Option<bool>, pub default: Option<bool>,
pub description: Option<String>, pub description: Option<String>,
pub filter_chain: Vec<String>, pub filter_chain: Vec<String>,

View file

@ -7,23 +7,22 @@ agents:
- name: context_builder - name: context_builder
kind: openai kind: openai
endpoint: http://host.docker.internal:10501 endpoint: http://host.docker.internal:10501
- name: response_generator - name: rag_agent
kind: openai kind: openai
endpoint: http://host.docker.internal:10502 endpoint: http://host.docker.internal:10502
- name: research_agent - name: research_agent
kind: openai kind: openai
endpoint: http://host.docker.internal:10503 endpoint: http://host.docker.internal:10503
listeners: listeners:
- name: rag agent - name: rag agent listener
router: arch_agent_v2 router: arch_agent_v2
agents: agents:
- name: simple_rag_agent - name: simple_rag_agent
default: true agent: rag_agent
description: virtual assistant for device contracts for simple queries description: virtual assistant for device contracts for simple queries
filter_chain: filter_chain:
- query_rewriter - query_rewriter
- context_builder - context_builder
- response_generator
protocol: openai protocol: openai
address: 0.0.0.0 address: 0.0.0.0
port: 8001 port: 8001