pub trait StreamAdapter {
type ProviderEvent;
type GraphEvent;
fn adapt(&self, event: Self::ProviderEvent) -> Option<Self::GraphEvent>;
}
pub struct OpenAIStreamAdapter;
impl StreamAdapter for OpenAIStreamAdapter {
type ProviderEvent = praxis_llm::StreamEvent;
type GraphEvent = crate::types::StreamEvent;
fn adapt(&self, event: Self::ProviderEvent) -> Option<Self::GraphEvent> {
Some(event.into())
}
}
#[allow(dead_code)]
pub struct AzureStreamAdapter;
#[allow(dead_code)]
pub struct AnthropicStreamAdapter;
#[cfg(test)]
mod tests {
use super::*;
use praxis_llm::StreamEvent as LLMEvent;
use crate::types::StreamEvent as GraphEvent;
#[test]
fn test_openai_adapter_message() {
let adapter = OpenAIStreamAdapter;
let llm_event = LLMEvent::Message {
content: "Hello".to_string(),
};
let graph_event = adapter.adapt(llm_event);
assert!(graph_event.is_some());
match graph_event.unwrap() {
GraphEvent::Message { content } => {
assert_eq!(content, "Hello");
}
_ => panic!("Expected Message event"),
}
}
#[test]
fn test_openai_adapter_reasoning() {
let adapter = OpenAIStreamAdapter;
let llm_event = LLMEvent::Reasoning {
content: "Thinking...".to_string(),
};
let graph_event = adapter.adapt(llm_event);
assert!(graph_event.is_some());
match graph_event.unwrap() {
GraphEvent::Reasoning { content } => {
assert_eq!(content, "Thinking...");
}
_ => panic!("Expected Reasoning event"),
}
}
}