Skip to content

feat(models): add Opper as a model vendor - #3986

Closed
Felixkw12 wants to merge 1 commit into
Tencent:mainfrom
Felixkw12:feat/opper-provider
Closed

Felixkw12 wants to merge 1 commit into
Tencent:mainfrom
Felixkw12:feat/opper-provider

Conversation

@Felixkw12

@Felixkw12 Felixkw12 commented Oct 6, 2026 •

Copy link
Copy Markdown

Description

Adds Opper (https://opper.ai) as a built-in model vendor on the provider layout from #3470 and #3589. Opper is an EU-hosted AI gateway with an OpenAI-compatible API, so the vendor is set up like OpenRouter and Requesty: base URL https://api.opper.ai/v3/compat, bearer auth, chat, VLM and embedding.

  • internal/models/providers/opper.go: vendor definition. It sends max_tokens and a top-level reasoning_effort (the docs list low, medium and high, so minimal is sent as low), round-trips extra_content on tool calls, and reads cached tokens from usage. The file comment lists each fact with its source in the Opper docs or the published OpenAPI schema, and what is not verified.
  • internal/models/providers/assets/opper.svg: the Opper mark, one colour (currentColor).
  • internal/models/providers/builtin.go: registration.
  • internal/models/catalog/data/seed.json, models.generated.json: an empty opper list, as for litellm. Model ids are bare pool names such as claude-sonnet-4-6 or gpt-5.5, or provider/model to pin one route. With no catalog entries, catalog-baseline.json does not change.
  • internal/models/providers/providers_test.go: the vendor list and count, and a resolve check for max_tokens, reasoning_effort and the minimal rung.
  • README*.md, website-docs/: vendor count 27 to 28, and an Opper row in the vendor table.

If you would rather the vendor ship with catalog entries, I can add a few pools with the regenerated baseline, here or in a follow-up.

Disclosure: Opper is my startup. Happy to adjust this, or close it if it is not a fit.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 📚 Documentation update
  • 🎨 Refactor
  • ⚡ Performance improvement
  • 🧪 Test
  • 🔧 Configuration / Build / CI

Related Issue

None.

Testing

go test, go vet, gofmt and golangci-lint were not run locally (no Go toolchain here), so CI is the first run. Formatting was matched by hand to the neighbouring vendor files.

models.generated.json was edited by hand. I checked it against json.dumps(..., ensure_ascii=False, indent=2) of the merged seed.json and overrides.json, which is what generate.py --check compares, and the same check reproduces the current main file byte for byte.

Checklist

  • git diff --check origin/main...HEAD passes
  • Changed source files are formatted (matched by hand, gofmt not run)
  • Targeted tests for the changed packages/components pass (not run)
  • Diff-scoped lint passes where applicable (for Go: golangci-lint run --new-from-rev=origin/main ./...) (not run)
  • Full-repository checks were run, or any unrelated/environment-dependent failures are documented above
  • Self-reviewed the code
  • Added/updated tests covering the change
  • Updated related documentation (README, website-docs/, Swagger annotations, etc.)
  • Breaking changes are clearly called out in the description above (none)

Screenshots / Recordings

Not applicable. The vendor list is served by GET /api/v1/models/providers, so the frontend has no change.

Adds Opper (https://opper.ai) as a built-in vendor on the provider layout
from Tencent#3470 and Tencent#3589. Opper is an EU-hosted AI gateway with an
OpenAI-compatible API, so the vendor is set up like OpenRouter and
Requesty.

- internal/models/providers/opper.go: vendor definition. Base URL
  https://api.opper.ai/v3/compat with bearer auth, opening chat, VLM and
  embedding. It sends max_tokens and a top-level reasoning_effort (the
  docs list low, medium and high, so minimal is sent as low), round-trips
  extra_content on tool calls, and reads cached tokens from usage. The
  file comment lists each fact with its source in the Opper docs or the
  published OpenAPI schema, and what is not verified.
- internal/models/providers/assets/opper.svg: the Opper mark, one colour
  (currentColor).
- internal/models/providers/builtin.go: registration.
- internal/models/catalog/data/seed.json and models.generated.json: an
  empty "opper" list, as for litellm. Model ids are bare pool names such
  as claude-sonnet-4-6 or gpt-5.5, or provider/model to pin one route,
  and the operator enters the one they want. With no catalog entries,
  parity/testdata/catalog-baseline.json does not change.
- internal/models/providers/providers_test.go: the vendor list and count,
  and a resolve check for max_tokens, reasoning_effort and the minimal
  rung.
- README*.md and website-docs: vendor count 27 to 28, and an Opper row in
  the vendor table.

Testing: go test, go vet, gofmt and golangci-lint were not run locally
(no Go toolchain here), so CI is the first run. Formatting was matched by
hand to the neighbouring vendor files (tabs, aligned fields, lines under
120 columns), and git diff --check is clean. models.generated.json was
edited by hand: generate.py copies seed.json in order and applies
overrides.json, and there is no Opper override, so the new line sits at
the same place in both files. I checked the edited file against
json.dumps(..., ensure_ascii=False, indent=2) of the merged data, which
is what generate.py --check compares, and the same check reproduces the
current main file byte for byte.

Disclosure: Opper is my startup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@lyingbug

lyingbug commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Thanks @Felixkw12 for the contribution. I'm going to close this one.

This PR uses the existing OpenAI-compatible implementation, and its chat behavior can already be configured without code changes: max_tokens_field: "max_tokens", thinking_format: "openai", supports_reasoning_effort: true, tool_call_extra_fields: ["extra_content"], and prompt_cache_accounting: true. The minimal → low mapping is also expressible through thinking_levels.

A deployment can configure the generic OpenAI-compatible vendor with the required overrides, or declare an opper vendor in the config/models.json overlay. See the lab-vllm example in config/models.json.example and the model configuration documentation. To reproduce the embedding settings as well, set send_encoding_format: true and dimensions_field: "dimensions" in the embedding model entries' compat.

This PR ships no model catalog entries and adds no Opper-specific protocol handling. I'm keeping the built-in list to vendors that ship a catalog or need code-level handling, so I don't think a built-in entry adds enough here. If Opper ever needs behavior the overlay can't express, I'm happy to revisit.

@lyingbug lyingbug closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants