llm_wire/provider
Adds a provider that the built-in OpenAI, Anthropic and Google adapters do not cover.
An adapter supplies only what differs between providers: how a request is encoded and how the event stream is reduced. The runtime keeps the rest for every adapter: transport through the caller’s HTTP Gun client, the three timers, byte limits, tool-call admission, telemetry and cleanup.
import llm_wire
import llm_wire/provider
let config =
provider.new(message.Custom("acme"), "https://llm.acme.test/v1", encode, fn() {
provider.reducer(initial_state, step, terminal)
})
|> provider.with_headers(fn() { [#("authorization", "Bearer " <> key())] })
|> provider.config
encode receives the admitted Request (read its fields by label:
model, messages, max_tokens, temperature, top_p,
stop_sequences, prompt_cache), the tools after schema projection
(name, description, schema) and the structured-output format
(name, schema), and returns encoded(path, body), where path is
appended to the endpoint. A reducer turns each server-sent Event
(event, data, id, retry) into message.Progress values, and
ends with a Terminal built by text, tool_calls, output_limited,
refused or failed.
Credentials belong in the with_headers closure, so they never print
with the adapter or a configuration. step and terminal drive a
reducer directly, for testing it without a server.
Types
An encoded request: a path below the endpoint and a JSON body.
pub type Encoded =
@internal Encoded
The structured-output format after projection.
pub type OutputFormat =
@internal OutputFormat
A tool after this adapter’s schema projection.
pub type ProjectedTool =
@internal ProjectedTool
A provider prompt cache reference, read from Request.prompt_cache.
pub type PromptCache =
@internal PromptCache
A reducer over the provider’s event stream; its state stays inside it.
pub type Reducer =
@internal Reducer
Values
pub fn blueprint_schema(
schema: codec.Schema,
) -> Result(json.Json, String)
Blueprint’s canonical JSON Schema for schema. Adapters may apply
stricter provider rules after it.
pub fn config(provider_adapter: Adapter) -> llm_wire.Config
The configuration of a call through this adapter, with the default limits, timeouts and tool-call checks.
pub fn event(name: option.Option(String), data: String) -> Event
A server-sent event with this event name and data, for tests.
pub fn failed(
error: error.Error,
usage: option.Option(message.Usage),
) -> Terminal
The provider ended its response with an error.
pub fn new(
provider: message.Provider,
endpoint: String,
encode: fn(
Request,
List(ProjectedTool),
option.Option(OutputFormat),
) -> Result(Encoded, error.PrepareError),
reducer: fn() -> Reducer,
) -> Adapter
An adapter for provider at endpoint. Tool and output schemas are
projected with blueprint_schema until with_tool_schema or
with_output_schema replace it; no headers are sent until
with_headers.
pub fn output_limited(
partial_text: String,
partial_calls: List(message.ToolCall),
usage: option.Option(message.Usage),
) -> Terminal
Output cut off by the provider’s token limit.
pub fn reducer(
state: state,
step: fn(state, Event) -> Result(
#(state, List(message.Progress)),
error.Error,
),
terminal: fn(state) -> option.Option(Terminal),
) -> Reducer
A reducer from an initial state, a step function and a terminal check.
pub fn refused(
reason: String,
usage: option.Option(message.Usage),
) -> Terminal
pub fn step(
reducer: Reducer,
event: Event,
) -> Result(#(Reducer, List(message.Progress)), error.Error)
Step a reducer with one event.
pub fn terminal(reducer: Reducer) -> option.Option(Terminal)
The reducer’s terminal, once its response ended.
pub fn text(
text: String,
usage: option.Option(message.Usage),
) -> Terminal
A final text answer.
pub fn tool_calls(
text: String,
calls: List(message.ToolCall),
response_id: option.Option(String),
provider_data: option.Option(String),
usage: option.Option(message.Usage),
) -> Terminal
Tool calls awaiting results. provider_data is opaque replay data the
adapter’s encode receives back in the assistant turn.
pub fn with_headers(
provider_adapter: Adapter,
headers: fn() -> List(#(String, String)),
) -> Adapter
Send these headers with every request. The closure runs when a request is prepared, so a credential read inside it never prints.
pub fn with_output_schema(
provider_adapter: Adapter,
project: fn(codec.Schema) -> Result(json.Json, String),
) -> Adapter
Project structured-output schemas with project.
pub fn with_tool_schema(
provider_adapter: Adapter,
project: fn(codec.Schema) -> Result(json.Json, String),
) -> Adapter
Project tool input schemas with project; an Error reason makes
prepare fail with error.UnsupportedSchema.