1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//! OpenAI, by every reach this crate has — and, through `api`, most of the rest.
//!
//! | Module | Reach | What it is |
//! |---|---|---|
//! | `api` | you say | Anything speaking `/v1/chat/completions` |
//! | `cli` | [`crate::Reach::LocalCli`] | The Codex tool on this machine |
//! | `embed` | you say | Anything speaking `/v1/embeddings` |
//!
//! # `api` is a shape, not a vendor
//!
//! This is the one module in the tree whose name is wider than what it holds. OpenAI,
//! Groq, Together, Fireworks, vLLM, Ollama, LM Studio, OpenRouter and LiteLLM all answer at
//! `/v1/chat/completions` with the same envelope, so the base URL is a constructor argument
//! and one protocol covers every one of them. It sits here because the shape is OpenAI's and
//! that is what the ecosystem calls it, not because a caller reaching Ollama is reaching
//! OpenAI.
//!
//! Which is why `api` is the only provider in this crate whose reach you supply. Everywhere
//! else the module name settles it; here a model on your laptop and a hosted API are the same
//! JSON over the same path, and nothing in a request can tell them apart. Guessing would mean
//! guessing where a prompt is allowed to go, so it is asked for instead — see
//! [`crate::Reach`] for what the answer changes.
// Both features, because this is the embeddings trait spoken in the OpenAI shape and needs
// each half. It is a sibling of `api` rather than something inside it: embeddings are a
// different request, a different reply and a different trait, and the only thing the two
// share is a base URL and a key.