Skip to main content

walrus_model/remote/openai/
mod.rs

1//! OpenAI-compatible LLM provider.
2//!
3//! Covers any service exposing the OpenAI chat completions API.
4
5use compact_str::CompactString;
6use reqwest::{Client, header::HeaderMap};
7
8mod provider;
9mod request;
10
11/// OpenAI-compatible endpoint URLs.
12pub mod endpoint {
13    /// OpenAI chat completions (default for OpenAI standard).
14    pub const OPENAI: &str = "https://api.openai.com/v1/chat/completions";
15    /// Ollama local chat completions.
16    pub const OLLAMA: &str = "http://localhost:11434/v1/chat/completions";
17}
18
19/// An OpenAI-compatible LLM provider.
20#[derive(Clone)]
21pub struct OpenAI {
22    /// The HTTP client.
23    pub client: Client,
24    /// Request headers (authorization, content-type).
25    headers: HeaderMap,
26    /// Chat completions endpoint URL.
27    endpoint: String,
28    /// The configured model name (used by `active_model()`).
29    model: CompactString,
30}
31
32impl OpenAI {
33    /// Create a provider targeting a custom OpenAI-compatible endpoint with Bearer auth.
34    pub fn custom(client: Client, key: &str, endpoint: &str, model: &str) -> anyhow::Result<Self> {
35        use reqwest::header;
36        let mut headers = HeaderMap::new();
37        headers.insert(header::CONTENT_TYPE, "application/json".parse()?);
38        headers.insert(header::ACCEPT, "application/json".parse()?);
39        headers.insert(header::AUTHORIZATION, format!("Bearer {key}").parse()?);
40        Ok(Self {
41            client,
42            headers,
43            endpoint: endpoint.to_owned(),
44            model: CompactString::from(model),
45        })
46    }
47
48    /// Create a provider targeting a custom endpoint without authentication (e.g. Ollama).
49    pub fn no_auth(client: Client, endpoint: &str, model: &str) -> Self {
50        use reqwest::header::{self, HeaderValue};
51        let mut headers = HeaderMap::new();
52        headers.insert(
53            header::CONTENT_TYPE,
54            HeaderValue::from_static("application/json"),
55        );
56        headers.insert(header::ACCEPT, HeaderValue::from_static("application/json"));
57        Self {
58            client,
59            headers,
60            endpoint: endpoint.to_owned(),
61            model: CompactString::from(model),
62        }
63    }
64}