3.5 KiB
LLM Internals
Purpose
internal/llm defines the provider-neutral Client interface and the
OpenAI-compatible client implementation. The OpenAI-compatible integration
contract owns the outbound HTTP wire
format and protocol behavior.
Construction
NewOpenAICompatibleClient validates a non-empty configured base URL, records
an optional default model, and resolves one base timeout. A supplied client with
a non-zero timeout supplies that base; otherwise a positive configured timeout
is used, then the internal default.
When callers supply an http.Client, construction clones it rather than
mutating the caller's instance. A supplied client with no timeout receives the
resolved base timeout in the clone. The client stores the trimmed base URL,
default model, and cloned client.
Generate Flow
Generate receives a domain.GenerateRequest from the runner:
- validate the effective timeout and choose the request endpoint;
- map the domain request to the internal wire-request representation;
- validate and flatten extra parameters, encode JSON, and create the HTTP request;
- prefer a direct API key, otherwise resolve the configured key environment variable;
- derive a request HTTP client only when an explicit timeout changes the base client;
- execute the request, reject non-success status responses without returning provider response bodies; and
- decode the response subset into
domain.GenerateResponse.
openAIChatRequestFromGenerateRequest is the conversion boundary for effective
model defaults, explicit numeric-presence state, rendered messages, structured
output, and session-ID validation. openAIChatRequestPayload protects reserved
fields and JSON encoding before an HTTP call. The external payload shape is
defined only in the integration contract.
Error Categories
The package uses these internal sentinels:
ErrInvalidConfigfor invalid client construction;ErrInvalidRequestfor invalid effective generation input;ErrRequestFailedfor request construction or transport failures;ErrUnexpectedStatusfor non-success HTTP responses; andErrMalformedResponsefor invalid or incomplete successful-response data.
The runner maps an invalid LLM request to its invalid-request category and other LLM failures to its generation category. Adapters then apply their public error contracts.
Package-Local Guarantees
- The default-model fallback happens before wire encoding.
- Per-request timeout handling clones a configured HTTP client when needed; it does not mutate shared client state.
- Direct API keys take precedence over environment lookup within this client.
- Provider response bodies are discarded for non-success status responses.
- The client does not implement retries, tool calls, or a stateful session store.
Verification And Change Recipe
Inspect:
internal/llm/openai_compatible_client_test.gointernal/usecase/runner_test.gointernal/adapter/http/handler_test.go
When changing the client:
- keep domain-to-wire mapping inside
internal/llmand preserve theClientinterface; - test construction, timeout selection, mapping, and error categorization;
- update the OpenAI-compatible integration contract for any observable wire or protocol change; and
- update runner internals if the client boundary or structured output handoff changes.
The testing policy owns global test sufficiency.