use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::error::{Error, Result};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AudioConfig {
pub voice: String,
pub speed: f32,
pub response_format: String,
pub language: Option<String>,
pub temperature: f32,
pub timeout: u32,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for AudioConfig {
fn default() -> Self {
Self {
voice: "alloy".to_string(),
speed: 1.0,
response_format: "mp3".to_string(),
language: None,
temperature: 0.0,
timeout: 600,
api_base: None,
api_key: None,
}
}
}
impl AudioConfig {
pub fn new() -> Self {
Self::default()
}
pub fn voice(mut self, voice: impl Into<String>) -> Self {
self.voice = voice.into();
self
}
pub fn speed(mut self, speed: f32) -> Self {
self.speed = speed;
self
}
pub fn response_format(mut self, format: impl Into<String>) -> Self {
self.response_format = format.into();
self
}
pub fn language(mut self, language: impl Into<String>) -> Self {
self.language = Some(language.into());
self
}
pub fn timeout(mut self, timeout: u32) -> Self {
self.timeout = timeout;
self
}
}
#[derive(Debug, Clone)]
pub struct AudioAgent {
pub name: String,
pub model: String,
pub config: AudioConfig,
pub verbose: bool,
}
impl Default for AudioAgent {
fn default() -> Self {
Self {
name: "AudioAgent".to_string(),
model: "openai/tts-1".to_string(),
config: AudioConfig::default(),
verbose: true,
}
}
}
impl AudioAgent {
pub fn new() -> AudioAgentBuilder {
AudioAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn model(&self) -> &str {
&self.model
}
pub fn speech(&self, text: &str, output_path: &str) -> Result<String> {
Ok(format!(
"Generated speech for '{}' to '{}' using model '{}'",
text, output_path, self.model
))
}
pub fn transcribe(&self, audio_path: &str) -> Result<String> {
Ok(format!(
"Transcribed audio from '{}' using model '{}'",
audio_path, self.model
))
}
}
#[derive(Debug, Default)]
pub struct AudioAgentBuilder {
name: Option<String>,
model: Option<String>,
config: AudioConfig,
verbose: bool,
}
impl AudioAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn voice(mut self, voice: impl Into<String>) -> Self {
self.config.voice = voice.into();
self
}
pub fn speed(mut self, speed: f32) -> Self {
self.config.speed = speed;
self
}
pub fn verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
pub fn config(mut self, config: AudioConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<AudioAgent> {
Ok(AudioAgent {
name: self.name.unwrap_or_else(|| "AudioAgent".to_string()),
model: self.model.unwrap_or_else(|| "openai/tts-1".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageConfig {
pub style: String,
pub response_format: String,
pub timeout: u32,
pub size: Option<String>,
pub quality: Option<String>,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for ImageConfig {
fn default() -> Self {
Self {
style: "natural".to_string(),
response_format: "url".to_string(),
timeout: 600,
size: Some("1024x1024".to_string()),
quality: Some("standard".to_string()),
api_base: None,
api_key: None,
}
}
}
impl ImageConfig {
pub fn new() -> Self {
Self::default()
}
pub fn style(mut self, style: impl Into<String>) -> Self {
self.style = style.into();
self
}
pub fn size(mut self, size: impl Into<String>) -> Self {
self.size = Some(size.into());
self
}
pub fn quality(mut self, quality: impl Into<String>) -> Self {
self.quality = Some(quality.into());
self
}
}
#[derive(Debug, Clone)]
pub struct ImageAgent {
pub name: String,
pub model: String,
pub config: ImageConfig,
pub verbose: bool,
}
impl Default for ImageAgent {
fn default() -> Self {
Self {
name: "ImageAgent".to_string(),
model: "dall-e-3".to_string(),
config: ImageConfig::default(),
verbose: true,
}
}
}
impl ImageAgent {
pub fn new() -> ImageAgentBuilder {
ImageAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn generate(&self, prompt: &str) -> Result<ImageResult> {
Ok(ImageResult {
url: Some(format!("https://example.com/generated-image-{}.png", uuid::Uuid::new_v4())),
b64_json: None,
revised_prompt: Some(prompt.to_string()),
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageResult {
pub url: Option<String>,
pub b64_json: Option<String>,
pub revised_prompt: Option<String>,
}
#[derive(Debug, Default)]
pub struct ImageAgentBuilder {
name: Option<String>,
model: Option<String>,
config: ImageConfig,
verbose: bool,
}
impl ImageAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn config(mut self, config: ImageConfig) -> Self {
self.config = config;
self
}
pub fn verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
pub fn build(self) -> Result<ImageAgent> {
Ok(ImageAgent {
name: self.name.unwrap_or_else(|| "ImageAgent".to_string()),
model: self.model.unwrap_or_else(|| "dall-e-3".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoConfig {
pub seconds: String,
pub size: Option<String>,
pub timeout: u32,
pub poll_interval: u32,
pub max_wait_time: u32,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for VideoConfig {
fn default() -> Self {
Self {
seconds: "8".to_string(),
size: None,
timeout: 600,
poll_interval: 10,
max_wait_time: 600,
api_base: None,
api_key: None,
}
}
}
impl VideoConfig {
pub fn new() -> Self {
Self::default()
}
pub fn seconds(mut self, seconds: impl Into<String>) -> Self {
self.seconds = seconds.into();
self
}
pub fn size(mut self, size: impl Into<String>) -> Self {
self.size = Some(size.into());
self
}
}
#[derive(Debug, Clone)]
pub struct VideoAgent {
pub name: String,
pub model: String,
pub config: VideoConfig,
pub verbose: bool,
}
impl Default for VideoAgent {
fn default() -> Self {
Self {
name: "VideoAgent".to_string(),
model: "openai/sora-2".to_string(),
config: VideoConfig::default(),
verbose: true,
}
}
}
impl VideoAgent {
pub fn new() -> VideoAgentBuilder {
VideoAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn generate(&self, _prompt: &str) -> Result<VideoResult> {
Ok(VideoResult {
id: uuid::Uuid::new_v4().to_string(),
status: VideoStatus::Pending,
url: None,
error: None,
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum VideoStatus {
Pending,
Processing,
Completed,
Failed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoResult {
pub id: String,
pub status: VideoStatus,
pub url: Option<String>,
pub error: Option<String>,
}
#[derive(Debug, Default)]
pub struct VideoAgentBuilder {
name: Option<String>,
model: Option<String>,
config: VideoConfig,
verbose: bool,
}
impl VideoAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn config(mut self, config: VideoConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<VideoAgent> {
Ok(VideoAgent {
name: self.name.unwrap_or_else(|| "VideoAgent".to_string()),
model: self.model.unwrap_or_else(|| "openai/sora-2".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OCRConfig {
pub include_image_base64: bool,
pub pages: Option<Vec<u32>>,
pub image_limit: Option<u32>,
pub timeout: u32,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for OCRConfig {
fn default() -> Self {
Self {
include_image_base64: false,
pages: None,
image_limit: None,
timeout: 600,
api_base: None,
api_key: None,
}
}
}
impl OCRConfig {
pub fn new() -> Self {
Self::default()
}
pub fn pages(mut self, pages: Vec<u32>) -> Self {
self.pages = Some(pages);
self
}
pub fn image_limit(mut self, limit: u32) -> Self {
self.image_limit = Some(limit);
self
}
}
#[derive(Debug, Clone)]
pub struct OCRAgent {
pub name: String,
pub model: String,
pub config: OCRConfig,
pub verbose: bool,
}
impl Default for OCRAgent {
fn default() -> Self {
Self {
name: "OCRAgent".to_string(),
model: "mistral/mistral-ocr-latest".to_string(),
config: OCRConfig::default(),
verbose: true,
}
}
}
impl OCRAgent {
pub fn new() -> OCRAgentBuilder {
OCRAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn extract(&self, source: &str) -> Result<OCRResult> {
Ok(OCRResult {
text: format!("Extracted text from {}", source),
pages: vec![OCRPage {
page_number: 1,
markdown: "# Extracted Content\n\nSample extracted text.".to_string(),
images: vec![],
}],
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OCRResult {
pub text: String,
pub pages: Vec<OCRPage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OCRPage {
pub page_number: u32,
pub markdown: String,
pub images: Vec<String>,
}
#[derive(Debug, Default)]
pub struct OCRAgentBuilder {
name: Option<String>,
model: Option<String>,
config: OCRConfig,
verbose: bool,
}
impl OCRAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn config(mut self, config: OCRConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<OCRAgent> {
Ok(OCRAgent {
name: self.name.unwrap_or_else(|| "OCRAgent".to_string()),
model: self.model.unwrap_or_else(|| "mistral/mistral-ocr-latest".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CodeConfig {
pub sandbox: bool,
pub timeout: u32,
pub allowed_languages: Vec<String>,
pub max_output_length: usize,
pub working_directory: Option<String>,
pub environment: HashMap<String, String>,
}
impl Default for CodeConfig {
fn default() -> Self {
Self {
sandbox: true,
timeout: 30,
allowed_languages: vec!["python".to_string()],
max_output_length: 10000,
working_directory: None,
environment: HashMap::new(),
}
}
}
impl CodeConfig {
pub fn new() -> Self {
Self::default()
}
pub fn sandbox(mut self, sandbox: bool) -> Self {
self.sandbox = sandbox;
self
}
pub fn timeout(mut self, timeout: u32) -> Self {
self.timeout = timeout;
self
}
pub fn allowed_languages(mut self, languages: Vec<String>) -> Self {
self.allowed_languages = languages;
self
}
}
#[derive(Debug, Clone)]
pub struct CodeAgent {
pub name: String,
pub model: String,
pub config: CodeConfig,
pub instructions: Option<String>,
pub verbose: bool,
}
impl Default for CodeAgent {
fn default() -> Self {
Self {
name: "CodeAgent".to_string(),
model: "gpt-4o-mini".to_string(),
config: CodeConfig::default(),
instructions: None,
verbose: true,
}
}
}
impl CodeAgent {
pub fn new() -> CodeAgentBuilder {
CodeAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn generate(&self, description: &str) -> Result<String> {
Ok(format!("# Generated code for: {}\ndef main():\n pass", description))
}
pub fn execute(&self, _code: &str) -> Result<CodeExecutionResult> {
if !self.config.sandbox {
return Err(Error::config("Code execution requires sandbox mode"));
}
Ok(CodeExecutionResult {
output: "Execution output".to_string(),
exit_code: 0,
error: None,
})
}
pub fn review(&self, code: &str) -> Result<String> {
Ok(format!("Code review for:\n{}\n\nNo issues found.", code))
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CodeExecutionResult {
pub output: String,
pub exit_code: i32,
pub error: Option<String>,
}
#[derive(Debug, Default)]
pub struct CodeAgentBuilder {
name: Option<String>,
model: Option<String>,
config: CodeConfig,
instructions: Option<String>,
verbose: bool,
}
impl CodeAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn config(mut self, config: CodeConfig) -> Self {
self.config = config;
self
}
pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
self.instructions = Some(instructions.into());
self
}
pub fn build(self) -> Result<CodeAgent> {
Ok(CodeAgent {
name: self.name.unwrap_or_else(|| "CodeAgent".to_string()),
model: self.model.unwrap_or_else(|| "gpt-4o-mini".to_string()),
config: self.config,
instructions: self.instructions,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisionConfig {
pub detail: String,
pub max_tokens: u32,
pub timeout: u32,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for VisionConfig {
fn default() -> Self {
Self {
detail: "auto".to_string(),
max_tokens: 4096,
timeout: 60,
api_base: None,
api_key: None,
}
}
}
impl VisionConfig {
pub fn new() -> Self {
Self::default()
}
pub fn detail(mut self, detail: impl Into<String>) -> Self {
self.detail = detail.into();
self
}
pub fn max_tokens(mut self, max_tokens: u32) -> Self {
self.max_tokens = max_tokens;
self
}
}
#[derive(Debug, Clone)]
pub struct VisionAgent {
pub name: String,
pub model: String,
pub config: VisionConfig,
pub verbose: bool,
}
impl Default for VisionAgent {
fn default() -> Self {
Self {
name: "VisionAgent".to_string(),
model: "gpt-4o".to_string(),
config: VisionConfig::default(),
verbose: true,
}
}
}
impl VisionAgent {
pub fn new() -> VisionAgentBuilder {
VisionAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn describe(&self, image_source: &str) -> Result<String> {
Ok(format!("Description of image at: {}", image_source))
}
pub fn analyze(&self, image_source: &str, prompt: &str) -> Result<String> {
Ok(format!("Analysis of {} with prompt: {}", image_source, prompt))
}
pub fn compare(&self, images: &[&str]) -> Result<String> {
Ok(format!("Comparison of {} images", images.len()))
}
}
#[derive(Debug, Default)]
pub struct VisionAgentBuilder {
name: Option<String>,
model: Option<String>,
config: VisionConfig,
verbose: bool,
}
impl VisionAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn config(mut self, config: VisionConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<VisionAgent> {
Ok(VisionAgent {
name: self.name.unwrap_or_else(|| "VisionAgent".to_string()),
model: self.model.unwrap_or_else(|| "gpt-4o".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeepResearchConfig {
pub max_sources: usize,
pub include_citations: bool,
pub max_depth: usize,
pub timeout: u32,
pub api_base: Option<String>,
pub api_key: Option<String>,
}
impl Default for DeepResearchConfig {
fn default() -> Self {
Self {
max_sources: 10,
include_citations: true,
max_depth: 3,
timeout: 600,
api_base: None,
api_key: None,
}
}
}
impl DeepResearchConfig {
pub fn new() -> Self {
Self::default()
}
pub fn max_sources(mut self, max: usize) -> Self {
self.max_sources = max;
self
}
pub fn include_citations(mut self, include: bool) -> Self {
self.include_citations = include;
self
}
pub fn max_depth(mut self, depth: usize) -> Self {
self.max_depth = depth;
self
}
pub fn timeout(mut self, timeout: u32) -> Self {
self.timeout = timeout;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResearchCitation {
pub title: String,
pub url: String,
pub start_index: usize,
pub end_index: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeepResearchResult {
pub report: String,
pub citations: Vec<ResearchCitation>,
pub sources_count: usize,
pub time_ms: u64,
}
#[derive(Debug)]
pub struct DeepResearchAgent {
name: String,
pub model: String,
pub instructions: Option<String>,
pub config: DeepResearchConfig,
verbose: bool,
}
impl DeepResearchAgent {
pub fn new() -> DeepResearchAgentBuilder {
DeepResearchAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn research(&self, query: &str) -> Result<DeepResearchResult> {
Ok(DeepResearchResult {
report: format!("Research report for: {}", query),
citations: vec![],
sources_count: 0,
time_ms: 0,
})
}
}
impl Default for DeepResearchAgent {
fn default() -> Self {
Self {
name: "DeepResearchAgent".to_string(),
model: "o3-deep-research".to_string(),
instructions: None,
config: DeepResearchConfig::default(),
verbose: false,
}
}
}
#[derive(Debug, Default)]
pub struct DeepResearchAgentBuilder {
name: Option<String>,
model: Option<String>,
instructions: Option<String>,
config: DeepResearchConfig,
verbose: bool,
}
impl DeepResearchAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
self.instructions = Some(instructions.into());
self
}
pub fn config(mut self, config: DeepResearchConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<DeepResearchAgent> {
Ok(DeepResearchAgent {
name: self.name.unwrap_or_else(|| "DeepResearchAgent".to_string()),
model: self.model.unwrap_or_else(|| "o3-deep-research".to_string()),
instructions: self.instructions,
config: self.config,
verbose: self.verbose,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RealtimeConfig {
pub voice: String,
pub modalities: Vec<String>,
pub turn_detection: String,
pub input_audio_format: String,
pub output_audio_format: String,
pub temperature: f32,
pub max_response_output_tokens: Option<usize>,
pub instructions: Option<String>,
}
impl Default for RealtimeConfig {
fn default() -> Self {
Self {
voice: "alloy".to_string(),
modalities: vec!["text".to_string(), "audio".to_string()],
turn_detection: "server_vad".to_string(),
input_audio_format: "pcm16".to_string(),
output_audio_format: "pcm16".to_string(),
temperature: 0.8,
max_response_output_tokens: None,
instructions: None,
}
}
}
impl RealtimeConfig {
pub fn new() -> Self {
Self::default()
}
pub fn voice(mut self, voice: impl Into<String>) -> Self {
self.voice = voice.into();
self
}
pub fn modalities(mut self, modalities: Vec<String>) -> Self {
self.modalities = modalities;
self
}
pub fn turn_detection(mut self, mode: impl Into<String>) -> Self {
self.turn_detection = mode.into();
self
}
pub fn temperature(mut self, temp: f32) -> Self {
self.temperature = temp;
self
}
pub fn max_response_output_tokens(mut self, tokens: usize) -> Self {
self.max_response_output_tokens = Some(tokens);
self
}
pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
self.instructions = Some(instructions.into());
self
}
}
#[derive(Debug)]
pub struct RealtimeAgent {
name: String,
pub model: String,
pub config: RealtimeConfig,
verbose: bool,
}
impl RealtimeAgent {
pub fn new() -> RealtimeAgentBuilder {
RealtimeAgentBuilder::default()
}
pub fn name(&self) -> &str {
&self.name
}
pub fn send_text(&self, text: &str) -> Result<String> {
Ok(format!("Sent: {}", text))
}
}
impl Default for RealtimeAgent {
fn default() -> Self {
Self {
name: "RealtimeAgent".to_string(),
model: "gpt-4o-realtime-preview".to_string(),
config: RealtimeConfig::default(),
verbose: false,
}
}
}
#[derive(Debug, Default)]
pub struct RealtimeAgentBuilder {
name: Option<String>,
model: Option<String>,
config: RealtimeConfig,
verbose: bool,
}
impl RealtimeAgentBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn model(mut self, model: impl Into<String>) -> Self {
self.model = Some(model.into());
self
}
pub fn voice(mut self, voice: impl Into<String>) -> Self {
self.config.voice = voice.into();
self
}
pub fn config(mut self, config: RealtimeConfig) -> Self {
self.config = config;
self
}
pub fn build(self) -> Result<RealtimeAgent> {
Ok(RealtimeAgent {
name: self.name.unwrap_or_else(|| "RealtimeAgent".to_string()),
model: self.model.unwrap_or_else(|| "gpt-4o-realtime-preview".to_string()),
config: self.config,
verbose: self.verbose,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_audio_agent_builder() {
let agent = AudioAgent::new()
.name("TestAudio")
.model("openai/tts-1-hd")
.voice("nova")
.speed(1.5)
.build()
.unwrap();
assert_eq!(agent.name(), "TestAudio");
assert_eq!(agent.model(), "openai/tts-1-hd");
assert_eq!(agent.config.voice, "nova");
assert_eq!(agent.config.speed, 1.5);
}
#[test]
fn test_audio_config_defaults() {
let config = AudioConfig::default();
assert_eq!(config.voice, "alloy");
assert_eq!(config.speed, 1.0);
assert_eq!(config.response_format, "mp3");
}
#[test]
fn test_image_agent_builder() {
let agent = ImageAgent::new()
.name("TestImage")
.model("dall-e-3")
.build()
.unwrap();
assert_eq!(agent.name(), "TestImage");
assert_eq!(agent.model, "dall-e-3");
}
#[test]
fn test_image_config_builder() {
let config = ImageConfig::new()
.style("vivid")
.size("1792x1024")
.quality("hd");
assert_eq!(config.style, "vivid");
assert_eq!(config.size, Some("1792x1024".to_string()));
assert_eq!(config.quality, Some("hd".to_string()));
}
#[test]
fn test_video_agent_builder() {
let agent = VideoAgent::new()
.name("TestVideo")
.model("openai/sora-2-pro")
.build()
.unwrap();
assert_eq!(agent.name(), "TestVideo");
assert_eq!(agent.model, "openai/sora-2-pro");
}
#[test]
fn test_video_config_defaults() {
let config = VideoConfig::default();
assert_eq!(config.seconds, "8");
assert_eq!(config.timeout, 600);
assert_eq!(config.poll_interval, 10);
}
#[test]
fn test_ocr_agent_builder() {
let agent = OCRAgent::new()
.name("TestOCR")
.model("mistral/mistral-ocr-latest")
.build()
.unwrap();
assert_eq!(agent.name(), "TestOCR");
assert_eq!(agent.model, "mistral/mistral-ocr-latest");
}
#[test]
fn test_ocr_config_builder() {
let config = OCRConfig::new()
.pages(vec![1, 2, 3])
.image_limit(10);
assert_eq!(config.pages, Some(vec![1, 2, 3]));
assert_eq!(config.image_limit, Some(10));
}
#[test]
fn test_code_agent_builder() {
let agent = CodeAgent::new()
.name("TestCode")
.model("gpt-4o")
.instructions("Write clean code")
.build()
.unwrap();
assert_eq!(agent.name(), "TestCode");
assert_eq!(agent.model, "gpt-4o");
assert_eq!(agent.instructions, Some("Write clean code".to_string()));
}
#[test]
fn test_code_config_defaults() {
let config = CodeConfig::default();
assert!(config.sandbox);
assert_eq!(config.timeout, 30);
assert_eq!(config.allowed_languages, vec!["python".to_string()]);
}
#[test]
fn test_vision_agent_builder() {
let agent = VisionAgent::new()
.name("TestVision")
.model("gpt-4o")
.build()
.unwrap();
assert_eq!(agent.name(), "TestVision");
assert_eq!(agent.model, "gpt-4o");
}
#[test]
fn test_vision_config_builder() {
let config = VisionConfig::new()
.detail("high")
.max_tokens(8192);
assert_eq!(config.detail, "high");
assert_eq!(config.max_tokens, 8192);
}
#[test]
fn test_image_generate() {
let agent = ImageAgent::new().build().unwrap();
let result = agent.generate("A sunset over mountains").unwrap();
assert!(result.url.is_some());
}
#[test]
fn test_video_generate() {
let agent = VideoAgent::new().build().unwrap();
let result = agent.generate("A cat playing").unwrap();
assert_eq!(result.status, VideoStatus::Pending);
}
#[test]
fn test_ocr_extract() {
let agent = OCRAgent::new().build().unwrap();
let result = agent.extract("document.pdf").unwrap();
assert!(!result.text.is_empty());
assert!(!result.pages.is_empty());
}
#[test]
fn test_code_generate() {
let agent = CodeAgent::new().build().unwrap();
let code = agent.generate("Calculate fibonacci").unwrap();
assert!(code.contains("def main"));
}
#[test]
fn test_vision_describe() {
let agent = VisionAgent::new().build().unwrap();
let description = agent.describe("image.jpg").unwrap();
assert!(description.contains("image.jpg"));
}
#[test]
fn test_deep_research_agent_builder() {
let agent = DeepResearchAgent::new()
.name("Researcher")
.model("o3-deep-research")
.instructions("Research thoroughly")
.build()
.unwrap();
assert_eq!(agent.name(), "Researcher");
assert_eq!(agent.model, "o3-deep-research");
}
#[test]
fn test_deep_research_config() {
let config = DeepResearchConfig::new()
.max_sources(20)
.include_citations(true);
assert_eq!(config.max_sources, 20);
assert!(config.include_citations);
}
#[test]
fn test_realtime_agent_builder() {
let agent = RealtimeAgent::new()
.name("VoiceAssistant")
.voice("nova")
.build()
.unwrap();
assert_eq!(agent.name(), "VoiceAssistant");
assert_eq!(agent.config.voice, "nova");
}
#[test]
fn test_realtime_config() {
let config = RealtimeConfig::new()
.voice("shimmer")
.temperature(0.7);
assert_eq!(config.voice, "shimmer");
assert_eq!(config.temperature, 0.7);
}
}