#![allow(dead_code, unused_variables)]
use llm_trait::{
Capabilities, ChatMessage, ChatRequest, LlmConfig, LlmError, LlmProvider, Protocol, RawAdapter,
StreamChunk, UsageInfo,
};
use llm_unified::model_registry::{ModelProfile, ModelRegistry};
use llm_unified::{
AnthropicProtocol, GenericProvider, OpenAiProtocol, create, create_provider, from_env,
};
use std::sync::Arc;
async fn readme_quickstart() -> Result<(), Box<dyn std::error::Error>> {
let config = LlmConfig {
protocol: None,
api_key: std::env::var("LLM_API_KEY")?,
model: "gpt-4o-mini".to_string(),
base_url: "https://api.openai.com/v1".to_string(),
options: Default::default(),
};
let provider = create_provider(&config)?;
let request = ChatRequest::new(vec![
ChatMessage::system("You are a concise assistant."),
ChatMessage::user("Reply with one word."),
]);
let response = provider.chat(request.clone()).await?;
println!("{}", response.content);
println!(
"finish: {:?}, usage: {:?}",
response.finish_reason, response.usage
);
let mut stream = provider.stream(request).await?;
while let Some(chunk) = stream.next().await {
match chunk? {
StreamChunk::Text(t) => print!("{t}"),
StreamChunk::Thought(t) => eprintln!("[thinking] {t}"),
StreamChunk::ToolCall(call) => eprintln!("[tool] {call}"),
StreamChunk::Usage(usage) => eprintln!("[usage] {usage:?}"),
StreamChunk::Stop { finish_reason } => {
eprintln!("\n[stop] {finish_reason:?}");
break;
}
StreamChunk::Error(e) => eprintln!("[error] {e}"),
StreamChunk::ThinkingSignature(_) => {}
}
}
Ok(())
}
async fn readme_collect(
provider: Arc<dyn LlmProvider>,
request: ChatRequest,
) -> Result<(), LlmError> {
let text = provider
.stream(request.clone())
.await?
.collect_text()
.await?;
let full = provider.stream(request).await?.collect_response().await?;
Ok(())
}
fn readme_factories() -> Result<(), LlmError> {
let from_env_provider = from_env()?;
let created = create("sk-test", "gpt-4o", "https://api.openai.com/v1")?;
Ok(())
}
fn docs_level1(key: &str) -> Result<(), LlmError> {
let config = LlmConfig {
protocol: Some(Protocol::OpenAi),
api_key: key.into(),
model: "qwen2.5-coder:32b".into(),
base_url: "http://localhost:11434/v1".into(),
options: Default::default(),
};
let provider = create_provider(&config)?;
Ok(())
}
fn docs_level2_fields() {
let profile = ModelProfile {
protocol: Protocol::OpenAi,
provider_name: "mybrand",
capabilities: Capabilities {
supports_streaming: true,
supports_tools: true,
supports_vision: false,
supports_thinking: false,
max_context_tokens: Some(128_000),
max_output_tokens: Some(8_192),
},
reasoning_mode: llm_trait::ReasoningMode::None,
supported_extra_params: &[],
};
let registry = ModelRegistry::builtin();
let resolved: ModelProfile =
registry.lookup("my-Flagship-1", Some("https://api.mybrand.com/v1"), None);
}
fn docs_level3(
adapter: Box<dyn RawAdapter>,
client: Arc<dyn llm_trait::HttpClient>,
config: &LlmConfig,
) {
let wrapped = GenericProvider::new(Box::new(OpenAiProtocol::from_config(config)));
let injected = GenericProvider::with_http_client(adapter, client, Default::default());
let _: &dyn RawAdapter = injected.adapter();
}
fn docs_errors() {
let err = LlmError::api(429, "slow down");
assert_eq!(err.status(), Some(429));
assert!(LlmError::config("missing key").status().is_none());
let by_inherent = llm_trait::FinishReason::from_str("max_tokens");
let by_from_str: llm_trait::FinishReason = "length".parse().unwrap();
assert_eq!(by_inherent, by_from_str);
let mut usage = UsageInfo::default();
usage.merge(&UsageInfo {
prompt_tokens: Some(10),
..Default::default()
});
let _ = AnthropicProtocol::new("k", "m", Some("http://localhost"));
}
#[test]
fn doc_examples_stay_compiled() {
}