Repository navigation
feat(llm): add Opper provider - #1139
Conversation
Adds `opper` as a built-in remote LLM provider. Opper is an EU-hosted, OpenAI-compatible gateway (`https://api.opper.ai/v3/compat`) that fronts many vendors behind one key, with bare pool model ids such as `gpt-5.4-mini` or `claude-sonnet-4-6`. The wiring mirrors the existing `requesty` provider (RemoteConfig block, defaults, env overrides, factory case), and the provider reuses `openaicompat.Client` with strict `json_schema` structured output, same as `openai`. - `internal/llm/provider/opper/opper.go` (new): `New(cfg llm.RemoteConfig)` builds an `openaicompat.Client` for `<base>/chat/completions`. Key from `api_key_env` (default `OPPER_API_KEY`); the base URL already carries `/v3/compat`, so nothing is inserted before `/chat/completions`. Forwards `effort` as `reasoning_effort`. - `internal/llm/config.go`: `Opper RemoteConfig`, `builtinProviders`, `ActiveModel`, `WithModel`, `IsEnabled`, `MergeEnv` (model and effort), `ApplyDefaults` (`gpt-5.4-mini`, the base URL above, `OPPER_API_KEY`) and `MergedWith`. - `internal/llm/provider/provider.go`: `case "opper"` and the error message. `prompts.go`: `opper` maps to `ProfileFrontier`. - Guide, `tools_core.go` assist description, `docs/llm.md`, `README.md`, `SECURITY.md` and `CLAUDE.md` list the provider. - Tests: `opper_test.go` (missing key and model, json_schema request, base URL path, freeform, API error, reasoning_effort), config, provider, prompts and guide marker tests. The embedding API key fallback from the Requesty change is left out: `embedOpenAI` appends `/v1/embeddings` to a base that does not end in `/v1`, which would not match Opper's `/v3/compat/embeddings`. Not run locally: `go test -race ./...` and `make lint` (no Go toolchain on this machine). Pool ids checked against Opper's public catalogue (`GET https://api.opper.ai/v3/models`). Disclosure: Opper is my startup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Thanks for the PR, and for covering the Please rework this as a gateway preset. We made that architectural change in #929, following the same discussion on #928. Requesty is now a preset, and Cheaper Inference and API Route use that path too. The Requesty built-in that this branch follows is no longer the pattern for adding gateways. The new Users can configure Opper on current gortex provider add opper \
--base-url https://api.opper.ai/v3/compat \
--model gpt-5.4-mini \
--api-key-env OPPER_API_KEY \
--prompt-profile frontierThen set llm:
provider: opper
custom:
opper:
base_url: https://api.opper.ai/v3/compat
model: gpt-5.4-mini
api_key_env: OPPER_API_KEY
schema_mode: json_schema
prompt_profile: frontier
To ship Opper as a preset, the core change is three files:
That gives users Please drop the new There are also merge conflicts. I checked head Starting from current The policy is documented in Adding a provider: new wire protocols or authentication schemes need a built-in provider; OpenAI-compatible gateways use custom providers or presets. |
Rework per review: start from main and add Opper to gatewayPresets instead of a built-in provider package. The preset uses the shared custom-provider client at https://api.opper.ai/v3/compat with OPPER_API_KEY, json_schema and the frontier prompt tier. Adds the preset resolution check, a Gateway presets table row, and a regression test that a base URL path other than /v1 is kept when /chat/completions is appended. The earlier opper package and its config, factory and prompt wiring are dropped. Disclosure: Opper is my startup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A live check of both structured-output modes through the preset passed with gpt-6.1-terra. With gpt-5.4-mini the non-strict tool-call schema is rejected by Opper's route for that model today. Disclosure: Opper is my startup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Thanks for the detailed review. Reworked as a gateway preset from current
The provider package and its config, factory, prompt and docs wiring are gone, so the diff against Live check. I ran the preset through the shared client against Opper with That check changed the default model. With At the PR head ( I did not run the repository's lint and build locally; CI on this PR covers them. |
Summary
Adds
opperas a built-in remote LLM provider. Opper is an EU-hosted, OpenAI-compatible gateway (https://api.opper.ai/v3/compat) with bare pool model ids such asgpt-5.4-miniorclaude-sonnet-4-6. The wiring mirrors the existingrequestyprovider, and the provider reusesopenaicompat.Clientwith strictjson_schemastructured output. Closes #.Disclosure: Opper is my startup.
Changes
internal/llm/provider/opper/opper.go(new): builds anopenaicompat.Clientfor<base>/chat/completions. Key fromapi_key_env(defaultOPPER_API_KEY). The base URL already carries/v3/compat, so nothing is inserted before/chat/completions. Forwardseffortasreasoning_effort.internal/llm/config.go:Opper RemoteConfig,builtinProviders,ActiveModel,WithModel,IsEnabled,MergeEnv(model and effort),ApplyDefaults(gpt-5.4-mini, the base URL above,OPPER_API_KEY),MergedWith.internal/llm/provider/provider.go:case "opper"and the error message.prompts.go:oppermaps toProfileFrontier.docs/llm.md,README.md,SECURITY.md,CLAUDE.md.opper_test.go(missing key and model, json_schema request, base URL path, freeform, API error, reasoning_effort), plus config, provider, prompts and guide marker tests.The embedding key fallback from the Requesty change is left out:
embedOpenAIappends/v1/embeddingsunless the base ends in/v1, which would not match Opper's/v3/compat/embeddings.Testing
go test -race ./...) (not run locally, no Go toolchain here; CI will run it)Checklist
Meta["methods"]for interfaces (not applicable)EdgeMemberOfedges to their containing type (not applicable)