use omniference::{
OmniferenceEngine,
types::{ChatRequestIR, Message, ModelRef, ProviderConfig, ProviderEndpoint, ProviderKind},
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let _ = dotenvy::dotenv();
tracing_subscriber::fmt().with_env_filter(tracing_subscriber::EnvFilter::from_default_env()).init();
println!("🚀 Omniference Library Example");
println!("=============================");
let mut engine = OmniferenceEngine::new();
let ollama_base = std::env::var("OLLAMA_BASE_URL").unwrap_or_else(|_| "http://localhost:11434".to_string());
engine
.register_provider(ProviderConfig {
name: "ollama".to_string(),
endpoint: ProviderEndpoint {
kind: ProviderKind::OpenAICompat,
base_url: ollama_base.clone(),
api_key: None,
extra_headers: std::collections::BTreeMap::new(),
timeout: Some(30000),
},
enabled: true,
catalog_provider_slug: None,
})
.await
.map_err(|e| anyhow::anyhow!(e))?;
println!("✅ Registered Ollama provider");
match engine.discover_models().await {
Ok(models) => {
println!("📋 Available models:");
for model in &models {
println!(" - {} (via {})", model.id, model.provider_name);
}
if models.is_empty() {
println!("❌ No models found. Make sure Ollama is running and has models.");
return Ok(());
}
let model = &models[0];
println!("\n🤖 Using model: {}", model.id);
let request = ChatRequestIR {
model: ModelRef {
alias: model.id.clone(),
provider: engine.get_provider(&model.provider_name).await.unwrap(),
model_id: model.id.clone(),
input_modalities: model.input_modalities.clone(),
output_modalities: model.output_modalities.clone(),
},
messages: vec![Message {
role: omniference::types::Role::User,
parts: vec![omniference::types::ContentPart::Text(
"Hello! Can you introduce yourself and explain what you can do?".to_string(),
)],
name: None,
}],
reasoning: None,
tools: vec![],
tool_choice: omniference::types::ToolChoice::Auto,
sampling: omniference::types::Sampling::default(),
stream: false,
response_format: None,
audio_output: None,
web_search_options: None,
prediction: None,
metadata: std::collections::BTreeMap::new(),
request_timeout: None,
cache_key: None,
safety_identifier: None,
provider_routing: None,
};
println!("\n💬 Sending request...");
match engine.chat_complete(request).await {
Ok(response) => {
println!("\n📝 Response:");
println!("{}", response);
}
Err(e) => {
println!("❌ Error: {}", e);
}
}
println!("\n🔄 Streaming example:");
let streaming_request = ChatRequestIR {
model: ModelRef {
alias: model.id.clone(),
provider: engine.get_provider(&model.provider_name).await.unwrap(),
model_id: model.id.clone(),
input_modalities: model.input_modalities.clone(),
output_modalities: model.output_modalities.clone(),
},
messages: vec![Message {
role: omniference::types::Role::User,
parts: vec![omniference::types::ContentPart::Text("Count from 1 to 5 slowly.".to_string())],
name: None,
}],
reasoning: None,
tools: vec![],
tool_choice: omniference::types::ToolChoice::Auto,
sampling: omniference::types::Sampling::default(),
stream: true,
response_format: None,
audio_output: None,
web_search_options: None,
prediction: None,
metadata: std::collections::BTreeMap::new(),
request_timeout: None,
cache_key: None,
safety_identifier: None,
provider_routing: None,
};
match engine.chat(streaming_request).await {
Ok(stream) => {
use futures_util::StreamExt;
tokio::pin!(stream);
print!("📡 Streaming response: ");
while let Some(event) = stream.next().await {
match event {
omniference::stream::StreamEvent::TextDelta { content } => {
print!("{}", content);
tokio::io::AsyncWriteExt::flush(&mut tokio::io::stdout()).await.unwrap();
}
omniference::stream::StreamEvent::FinalMessage { .. } => {
println!("\n✅ Streaming complete!");
break;
}
omniference::stream::StreamEvent::Error { code, message } => {
println!("\n❌ Streaming error: {}: {}", code, message);
break;
}
_ => {}
}
}
}
Err(e) => {
println!("❌ Streaming error: {}", e);
}
}
}
Err(e) => {
println!("❌ Failed to discover models: {}", e);
println!(" Make sure Ollama is running at http://localhost:11434");
}
}
Ok(())
}