use async_trait::async_trait;
use super::llm_port::{LlmError, LlmPort, LlmRequest, LlmResponse};
use paladin_core::platform::container::vision::VisionRequest;
#[async_trait]
pub trait VisionCapableLlm: LlmPort + Send + Sync {
async fn generate_with_vision(
&self,
request: LlmRequest,
vision: VisionRequest,
) -> Result<LlmResponse, LlmError>;
fn supports_vision(&self) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn test_vision_capable_llm_is_send_sync() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<Arc<dyn VisionCapableLlm>>();
assert_sync::<Arc<dyn VisionCapableLlm>>();
}
#[test]
fn test_vision_capable_llm_is_object_safe() {
#[allow(dead_code)]
fn assert_object_safe(_: &dyn VisionCapableLlm) {}
}
struct MockVisionLlm;
#[async_trait]
impl LlmPort for MockVisionLlm {
async fn generate(&self, _request: LlmRequest) -> Result<LlmResponse, LlmError> {
unimplemented!()
}
async fn generate_stream(
&self,
_request: LlmRequest,
) -> Result<
Box<
dyn futures::Stream<
Item = Result<super::super::llm_port::StreamingResponse, LlmError>,
> + Send,
>,
LlmError,
> {
unimplemented!()
}
async fn validate_model(&self, _model: &str) -> Result<bool, LlmError> {
Ok(true)
}
async fn get_available_models(&self) -> Result<Vec<String>, LlmError> {
Ok(vec!["gpt-4o".to_string()])
}
fn get_provider_name(&self) -> &'static str {
"mock"
}
fn get_capabilities(&self) -> super::super::llm_port::ProviderCapabilities {
super::super::llm_port::ProviderCapabilities {
supports_vision: true,
..Default::default()
}
}
}
#[async_trait]
impl VisionCapableLlm for MockVisionLlm {
async fn generate_with_vision(
&self,
_request: LlmRequest,
_vision: VisionRequest,
) -> Result<LlmResponse, LlmError> {
unimplemented!()
}
fn supports_vision(&self) -> bool {
true
}
}
#[test]
fn test_mock_vision_llm_implements_trait() {
let _llm = MockVisionLlm;
}
#[test]
fn test_mock_supports_vision() {
let llm = MockVisionLlm;
assert!(llm.supports_vision());
}
#[test]
fn test_trait_can_be_boxed() {
let llm: Box<dyn VisionCapableLlm> = Box::new(MockVisionLlm);
assert!(llm.supports_vision());
}
#[test]
fn test_trait_can_be_arc() {
let llm: Arc<dyn VisionCapableLlm> = Arc::new(MockVisionLlm);
assert!(llm.supports_vision());
}
}