use async_trait::async_trait;
use paladin::application::services::battalion::flow_visualizer::{
FlowVisualizer, VisualizationFormat,
};
use paladin::application::services::battalion::maneuver_service::ManeuverExecutionService;
use paladin::application::services::paladin::error::PaladinError;
use paladin::core::base::entity::node::Node;
use paladin::core::platform::container::battalion::maneuver::{
ErrorStrategy, Maneuver, ManeuverConfig, OutputFormat,
};
use paladin::core::platform::container::battalion::parser::FlowParser;
use paladin::core::platform::container::paladin::{MaxLoops, Paladin, PaladinData, PaladinStatus};
use paladin_ports::output::paladin_port::{PaladinPort, PaladinResult, StopReason};
use std::collections::HashMap;
use std::sync::Arc;
struct ExamplePaladinPort;
#[async_trait]
impl PaladinPort for ExamplePaladinPort {
async fn execute(&self, paladin: &Paladin, input: &str) -> Result<PaladinResult, PaladinError> {
println!("\n🤖 {} executing...", paladin.node.name);
println!(" Input: {}", input);
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
let output = match paladin.node.name.as_str() {
"intake" => format!(
"[Intake] Validated and normalized input: \"{}\"",
input.trim()
),
"analyzer" => format!(
"[Analyzer] Technical analysis:\n - Key themes identified\n - Complexity: Medium\n - Input: {}",
input
),
"summarizer" => format!(
"[Summarizer] Concise summary:\n - Main point extracted\n - Length: {} chars\n - Input: {}",
input.len(),
input
),
"reviewer" => format!(
"[Reviewer] Final synthesis:\n - Analysis and summary combined\n - Quality: Approved\n - Input processed: {}",
input
),
_ => format!("{} processed: {}", paladin.node.name, input),
};
println!(" Output: {}", output);
Ok(PaladinResult {
output,
token_count: 75,
execution_time_ms: 100,
loop_count: 1,
stop_reason: StopReason::Completed,
..Default::default()
})
}
async fn execute_stream(
&self,
_paladin: &Paladin,
_input: &str,
) -> Result<
tokio::sync::mpsc::Receiver<
Result<paladin_ports::output::paladin_port::PaladinStreamChunk, PaladinError>,
>,
PaladinError,
> {
let (_tx, rx) = tokio::sync::mpsc::channel(1);
Ok(rx)
}
fn validate(&self, _paladin: &Paladin) -> Result<(), PaladinError> {
Ok(())
}
}
fn create_paladin(name: &str, system_prompt: &str) -> Paladin {
let data = PaladinData {
system_prompt: system_prompt.to_string(),
name: name.to_string(),
user_name: "User".to_string(),
model: "gpt-4".to_string(),
temperature: 0.7,
max_loops: MaxLoops::Fixed(3),
stop_words: vec![],
status: PaladinStatus::Idle,
vision_enabled: false,
..Default::default()
};
Node::new(data, Some(name.to_string()))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🎯 Maneuver Basic Flow DSL Example");
println!("{}", "=".repeat(60));
println!("\n📝 Step 1: Define Flow Expression");
let flow_expression = "intake -> (analyzer, summarizer) -> reviewer";
println!("Flow DSL: {}", flow_expression);
let flow = FlowParser::parse(flow_expression)?;
println!("✅ Flow parsed successfully");
println!("\n📊 Step 2: Visualize Flow Structure");
let ascii_viz = FlowVisualizer::visualize(&flow, VisualizationFormat::Ascii);
println!("{}", ascii_viz);
println!("\n🏗️ Step 3: Create Paladins");
let mut agents = HashMap::new();
agents.insert(
"intake".to_string(),
create_paladin(
"intake",
"You are the intake processor. Validate and normalize input data.",
),
);
println!(" ✓ Created 'intake' paladin");
agents.insert(
"analyzer".to_string(),
create_paladin(
"analyzer",
"You are the analyzer. Perform technical analysis and identify key themes.",
),
);
println!(" ✓ Created 'analyzer' paladin");
agents.insert(
"summarizer".to_string(),
create_paladin(
"summarizer",
"You are the summarizer. Create concise summaries of input.",
),
);
println!(" ✓ Created 'summarizer' paladin");
agents.insert(
"reviewer".to_string(),
create_paladin(
"reviewer",
"You are the reviewer. Synthesize analysis and summary into final output.",
),
);
println!(" ✓ Created 'reviewer' paladin");
println!("\n⚙️ Step 4: Configure Maneuver");
let config = ManeuverConfig::new()
.with_error_strategy(ErrorStrategy::FailFast)
.with_output_format(OutputFormat::Concatenate)
.with_timing_metrics(true);
println!(" ✓ Error strategy: FailFast");
println!(" ✓ Output format: Concatenate");
println!(" ✓ Timing metrics: Enabled");
println!("\n🎖️ Step 5: Create Maneuver");
let maneuver = Maneuver::new("document-workflow", agents, flow, config)?;
println!(" ✓ Maneuver '{}' created", maneuver.name);
println!("\n🚀 Step 6: Execute Maneuver");
println!("{}", "=".repeat(60));
let paladin_port = Arc::new(ExamplePaladinPort);
let service = ManeuverExecutionService::new(paladin_port);
let input = "Analyze the potential impact of quantum computing on cryptography";
println!("\n📥 Input: {}", input);
let result = service.execute(&maneuver, input).await?;
println!("\n{}", "=".repeat(60));
println!("✅ Execution Complete");
println!("{}", "=".repeat(60));
println!("\n📋 Execution Order:");
for (idx, agent_name) in result.execution_order.iter().enumerate() {
println!(" {}. {}", idx + 1, agent_name);
}
println!("\n⏱️ Timing Metrics:");
if let Some(metrics) = result.timing_metrics {
for (agent, duration) in metrics {
println!(" {} - {}ms", agent, duration.as_millis());
}
}
println!("\n📤 Final Output:");
println!("{}", "-".repeat(60));
println!("{}", result.final_output);
println!("{}", "-".repeat(60));
println!("\n💡 Key Takeaways:");
println!(" • Flow DSL enables declarative workflow definition");
println!(" • Sequential (->) and parallel (,) can be mixed");
println!(" • Visual feedback helps understand execution flow");
println!(" • Timing metrics provide performance insights");
Ok(())
}