use super::DemoScenario;
use crate::demo::runner::DemoRunner;
use crate::tui::animation::agent_avatar::{ActivityLevel, AgentRole};
use crate::tui::animation::message_flow::MessageType;
pub struct BugHuntSafariScenario {
phase: HuntPhase,
bugs_found: usize,
bugs_fixed: usize,
security_issues: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum HuntPhase {
Preparation,
Reproduction,
Investigation,
SecurityScan,
Fix,
Verification,
Complete,
}
impl BugHuntSafariScenario {
pub fn new() -> Self {
Self {
phase: HuntPhase::Preparation,
bugs_found: 0,
bugs_fixed: 0,
security_issues: 0,
}
}
}
impl Default for BugHuntSafariScenario {
fn default() -> Self {
Self::new()
}
}
impl DemoScenario for BugHuntSafariScenario {
fn name(&self) -> &str {
"Bug Hunt Safari"
}
fn description(&self) -> &str {
"Join the hunt as agents track down elusive bugs, identify security vulnerabilities, and implement fixes."
}
fn total_stages(&self) -> usize {
7
}
fn initialize(&mut self, runner: &mut DemoRunner) {
runner.add_agent("tester", AgentRole::Tester);
runner.add_agent("coder", AgentRole::Coder);
runner.add_agent("security", AgentRole::Security);
runner.add_agent("reviewer", AgentRole::Reviewer);
runner.set_token_rate(1000.0);
runner.set_total_tokens(0);
self.phase = HuntPhase::Preparation;
}
fn execute_stage(&mut self, stage: usize, runner: &mut DemoRunner) -> bool {
match stage {
0 => {
self.phase = HuntPhase::Preparation;
runner.set_agent_activity("tester", ActivityLevel::High);
runner.add_agent_tokens("tester", 4000);
runner.sparkle(15.0, 5.0, 10);
true
}
1 => {
self.phase = HuntPhase::Reproduction;
self.bugs_found = 1;
runner.set_agent_activity("tester", ActivityLevel::Max);
runner.set_token_rate(3000.0);
runner.add_agent_tokens("tester", 8000);
runner.send_message(
"tester",
"coder",
MessageType::Error,
(15.0, 5.0),
(30.0, 5.0),
);
runner.explode(15.0, 8.0, 12);
true
}
2 => {
self.phase = HuntPhase::Investigation;
runner.set_agent_activity("tester", ActivityLevel::Medium);
runner.set_agent_activity("coder", ActivityLevel::Max);
runner.set_token_rate(6000.0);
runner.add_agent_tokens("coder", 20000);
runner.send_message(
"coder",
"tester",
MessageType::Response,
(30.0, 5.0),
(15.0, 5.0),
);
runner.sparkle(30.0, 8.0, 8);
true
}
3 => {
self.phase = HuntPhase::SecurityScan;
self.security_issues = 2;
runner.set_agent_activity("coder", ActivityLevel::High);
runner.set_agent_activity("security", ActivityLevel::Max);
runner.set_token_rate(4000.0);
runner.add_agent_tokens("security", 12000);
runner.send_message(
"coder",
"security",
MessageType::Request,
(30.0, 5.0),
(45.0, 5.0),
);
runner.send_message(
"security",
"coder",
MessageType::Error,
(45.0, 5.0),
(30.0, 5.0),
);
runner.explode(45.0, 8.0, 8);
true
}
4 => {
self.phase = HuntPhase::Fix;
self.bugs_fixed = 1;
runner.set_agent_activity("security", ActivityLevel::Medium);
runner.set_agent_activity("coder", ActivityLevel::Max);
runner.set_token_rate(7000.0);
runner.add_agent_tokens("coder", 25000);
runner.sparkle(30.0, 5.0, 15);
true
}
5 => {
self.phase = HuntPhase::Verification;
runner.set_agent_activity("coder", ActivityLevel::Low);
runner.set_agent_activity("reviewer", ActivityLevel::High);
runner.set_agent_activity("tester", ActivityLevel::High);
runner.set_token_rate(3000.0);
runner.add_agent_tokens("reviewer", 8000);
runner.add_agent_tokens("tester", 5000);
runner.send_message(
"coder",
"reviewer",
MessageType::Request,
(30.0, 5.0),
(60.0, 5.0),
);
runner.send_message(
"reviewer",
"coder",
MessageType::Consensus,
(60.0, 5.0),
(30.0, 5.0),
);
runner.sparkle(60.0, 5.0, 10);
true
}
6 => {
self.phase = HuntPhase::Complete;
runner.set_agent_activity("tester", ActivityLevel::Complete);
runner.set_agent_activity("coder", ActivityLevel::Complete);
runner.set_agent_activity("security", ActivityLevel::Complete);
runner.set_agent_activity("reviewer", ActivityLevel::Complete);
runner.set_token_rate(0.0);
runner.celebrate(35.0, 10.0);
runner.sparkle(15.0, 8.0, 15);
runner.sparkle(30.0, 8.0, 15);
runner.sparkle(45.0, 8.0, 15);
runner.sparkle(60.0, 8.0, 15);
true
}
_ => false,
}
}
fn cleanup(&mut self, runner: &mut DemoRunner) {
runner.set_total_tokens(82000);
runner.set_token_rate(0.0);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::demo::DemoConfig;
#[test]
fn test_bug_hunt_scenario_new() {
let scenario = BugHuntSafariScenario::new();
assert_eq!(scenario.name(), "Bug Hunt Safari");
assert_eq!(scenario.total_stages(), 7);
}
#[test]
fn test_bug_hunt_full_execution() {
let mut scenario = BugHuntSafariScenario::new();
let mut runner = DemoRunner::new(DemoConfig::default());
scenario.initialize(&mut runner);
assert_eq!(runner.agents().len(), 4);
for stage in 0..scenario.total_stages() {
assert!(scenario.execute_stage(stage, &mut runner));
}
assert_eq!(scenario.phase, HuntPhase::Complete);
assert_eq!(scenario.bugs_found, 1);
assert_eq!(scenario.bugs_fixed, 1);
assert_eq!(scenario.security_issues, 2);
}
}