use perdix::{Buffer, AgentType};
use perdix::pty::portable::PortablePtyWriter;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Perdix PTY Integration Example ===\n");
basic_pty_streaming()?;
ansi_formatted_streaming()?;
#[cfg(not(windows))]
interactive_shell()?;
Ok(())
}
fn basic_pty_streaming() -> Result<(), Box<dyn std::error::Error>> {
println!("Example 1: Basic PTY Streaming");
println!("------------------------------");
let buffer = Buffer::new(512)?;
let (mut producer, consumer) = buffer.split();
println!("Creating PTY with shell...");
let pty = PortablePtyWriter::new()?;
let (stop_flag, writer_handle) = pty.start_writer_thread(consumer);
let messages = vec![
"Welcome to Perdix PTY Integration!",
"This demonstrates GPU-accelerated terminal output.",
"Messages flow from GPU → Ring Buffer → PTY → Terminal",
"",
"Let's see some output:",
];
for msg in messages {
producer.try_produce(msg.as_bytes(), AgentType::System);
producer.try_produce(b"\n", AgentType::System);
thread::sleep(Duration::from_millis(100));
}
for i in 1..=5 {
let msg = format!(" Processing item {}...", i);
producer.try_produce(msg.as_bytes(), AgentType::Info);
producer.try_produce(b"\n", AgentType::Info);
thread::sleep(Duration::from_millis(200));
}
producer.try_produce(b"\nPTY streaming complete!\n", AgentType::System);
thread::sleep(Duration::from_secs(1));
stop_flag.store(true, Ordering::Relaxed);
let bytes_written = writer_handle.join().unwrap();
println!("PTY writer stopped. Total bytes written: {}\n", bytes_written);
Ok(())
}
fn ansi_formatted_streaming() -> Result<(), Box<dyn std::error::Error>> {
println!("Example 2: ANSI Formatted Streaming");
println!("-----------------------------------");
let buffer = Buffer::new(512)?;
let (mut producer, consumer) = buffer.split();
let pty = PortablePtyWriter::new()?;
let (stop_flag, writer_handle) = pty.start_writer_thread(consumer);
let formatted_messages = vec![
("\x1b[2J\x1b[H", AgentType::System),
("\x1b[1;36m=== Perdix ANSI Output Demo ===\x1b[0m\n\n", AgentType::System),
("\x1b[32m[System]\x1b[0m Initializing...\n", AgentType::System),
("\x1b[33m[User]\x1b[0m Running query...\n", AgentType::User),
("\x1b[34m[Assistant]\x1b[0m Processing request...\n", AgentType::Assistant),
("\x1b[31m[Error]\x1b[0m Sample error message\n", AgentType::Error),
("\x1b[35m[Info]\x1b[0m Information update\n", AgentType::Info),
("\n\x1b[1mProgress:\x1b[0m\n", AgentType::System),
];
for (msg, agent_type) in formatted_messages {
producer.try_produce(msg.as_bytes(), agent_type);
thread::sleep(Duration::from_millis(150));
}
for i in 0..=20 {
let progress = "█".repeat(i);
let remaining = "░".repeat(20 - i);
let bar = format!("\r[{}{}] {}%", progress, remaining, i * 5);
producer.try_produce(bar.as_bytes(), AgentType::Info);
thread::sleep(Duration::from_millis(50));
}
producer.try_produce(b"\n\n\x1b[1;32mComplete!\x1b[0m\n", AgentType::System);
thread::sleep(Duration::from_secs(2));
stop_flag.store(true, Ordering::Relaxed);
writer_handle.join().unwrap();
println!("ANSI formatted output complete\n");
Ok(())
}
#[cfg(not(windows))]
fn interactive_shell() -> Result<(), Box<dyn std::error::Error>> {
println!("Example 3: Interactive Shell Integration");
println!("----------------------------------------");
let buffer = Buffer::new(1024)?;
let (mut producer, consumer) = buffer.split();
let pty = PortablePtyWriter::new()?;
let (stop_flag, writer_handle) = pty.start_writer_thread(consumer);
println!("Sending commands to shell via GPU ring buffer...\n");
let commands = vec![
"echo 'Hello from Perdix GPU-accelerated PTY!'",
"date",
"echo 'GPU -> Ring Buffer -> PTY -> Shell'",
"echo 'Zero-copy, lock-free, ultra-fast!'",
];
for cmd in commands {
producer.try_produce(cmd.as_bytes(), AgentType::User);
producer.try_produce(b"\n", AgentType::User);
thread::sleep(Duration::from_millis(500));
}
producer.try_produce(b"exit\n", AgentType::System);
thread::sleep(Duration::from_secs(1));
stop_flag.store(true, Ordering::Relaxed);
let bytes = writer_handle.join().unwrap();
println!("\nShell integration complete. Bytes processed: {}", bytes);
Ok(())
}
fn create_stop_flag() -> Arc<AtomicBool> {
Arc::new(AtomicBool::new(false))
}