Repository navigation
Conversation
Adds Opper as a built-in AI provider, in the same places as Requesty: API key lookup (keychain, then OPPER_API_KEY), a curated model list in ai_models.yaml, dynamic model discovery from Opper's public catalog, and generation through https://api.opper.ai/v3/compat/chat/completions with an X-Opper-Name: tabularis header. It is not part of the automatic provider detection. Opper is an EU-hosted, OpenAI-compatible AI gateway: 700+ models from 50+ providers behind one API key. Discovery keeps pooled chat models (bare names such as claude-sonnet-4-6, where Opper picks the route). Also lists Opper among the AI providers in the READMEs, the snap description and the gitster summary, and adds tests next to the Requesty ones (default models, provider label, no auto-select). Disclosure: Opper is my startup. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Felix Wunderlich <felix@opper.ai>
Code Review SummaryStatus: No Issues Found | Recommendation: Merge The PR mirrors every Requesty touchpoint for Opper: Rust dispatch, key lookup in both env-var paths, model discovery, YAML defaults, web-ui type/label/settings entry/key-status check, tests, and docs. Opper is correctly excluded from automatic provider detection. The incremental change since the last review ( Assumptions and gaps: the Opper API behaviour ( Files Reviewed (23 files)
Previous Review Summary (commit 28b0573)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 28b0573)Status: No Issues Found | Recommendation: Merge The PR mirrors every Requesty touchpoint for Opper (Rust dispatch, key lookup in both env-var paths, model discovery, YAML defaults, web-ui type/label/settings entry/key-status check, tests, docs). Opper is correctly excluded from automatic provider detection. No bugs, security problems, or missing integration points were found in the changed lines. Assumptions and gaps: the Opper API behaviour ( Files Reviewed (23 files)
Reviewed by claude-sonnet-5.5 · Input: 248 · Output: 1.9K · Cached: 292K Review guidance: REVIEW.md from base branch |
debba
left a comment
There was a problem hiding this comment.
Thanks for adding Opper across the provider settings, key lookup and model catalogue, and for being upfront about your connection to the service. Keeping it out of automatic provider selection is a thoughtful default. The settings and provider-label suites passed, with 97 tests in total.
Welcome with your first PR here! We'd be happy to have you join us on Discord if you'd like: https://discord.com/invite/K2hmhfHRSt
I haven't found a blocking issue in the diff. I'll run the desktop end-to-end checks and the remaining validation before merging. I'll report any part that I can't verify against the live service.
debba
left a comment
There was a problem hiding this comment.
Thanks again for the integration. I hit a build blocker when checking it against the updated main.
To reproduce:
- Check out this PR and merge the current main locally.
- Run
pnpm tauri build --debug --no-bundle -- --features e2e-testing.
The app should build so the Opper settings and requests can be tested. Instead, Rust stops in src-tauri/src/ai.rs, in fetch_opper_models, with E0599: no method named get found for enum Result<reqwest::Client, String>.
Since #1283, ai_client_for returns Result<Client, String>. The new fetcher still assigns that result directly to client and calls .get() on it. Please rebase and handle the result here, as the other model fetchers now do, while preserving the custom-proxy failure behavior.
Lint and typecheck passed. I couldn't reach the desktop or live-provider tests because the build fails, so I'm holding the merge until this is fixed.
Signed-off-by: Felix Wunderlich <felix@opper.ai>
Since TabularisDB#1283 ai_client_for returns Result<Client, String>. Match the other model fetchers and return no dynamic models when the client cannot be built, which keeps the custom proxy failure behavior. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Felix Wunderlich <felix@opper.ai>
|
Thanks for checking it against main. I merged the current main into the branch and fixed fetch_opper_models to handle the Result from ai_client_for, the same way the other fetchers do since #1283. If the client cannot be built it returns no dynamic models, so the custom proxy failure behavior stays the same. I merged instead of rebasing to avoid a force push. Happy to squash if you prefer. I have not run the Tauri build myself, so your e2e run will be the first full build of this change. |
debba
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround on the ai_client_for change. The let Ok(client) = ai_client_for("opper") else { return Vec::new(); } guard is how the other fetchers handle it now, so a broken proxy config just leaves Opper with its static model list, which is what I was after. Merging main instead of force pushing is fine, we squash on merge anyway.
I rebuilt it on my side: cargo check passes with the desktop features and with --no-default-features, the ai tests pass (including the new opper assertion in the default models test), and the settings and label suites are green with 97 tests. The web UI build passes too. I also hit the public /v3/models endpoint without a key to check the response shape against the parser: the model, pooled and type fields line up, and all the ids in ai_models.yaml show up among the pooled chat models.
Nothing blocking anymore, so I'm approving. Two things I'd keep as follow-ups, not for this PR:
generate_oppercould get a case inai_provider_tests.rsso theX-Opper-Nameheader and the endpoint path are covered by the fixture tests.- The model fetch pulls the whole catalog with a fixed
limit=2000. That's fine today, but the list would be cut off silently if the catalog ever grows past it.
The CI workflows still need a maintainer approval to run since this is your first PR here. I'll get those going and do the manual desktop checks against the live service before merging.
Resolves the ai_models.yaml conflict: main's new MiniMax entries stay in the Requesty list, and the Opper list follows it unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Merged the current main to resolve the conflict in ai_models.yaml (main's new MiniMax entries kept in the Requesty list, Opper list unchanged). No other changes. |
NewtTheWolf
left a comment
There was a problem hiding this comment.
Thanks for the ai_client_for error handling update. On 6e70468, the 97 affected frontend tests, typecheck and all 2,279 Rust library tests pass locally.
The branch currently conflicts with main in src-tauri/src/ai.rs, which has gained further provider and inline-completion changes. Please rebase and preserve those paths. I do not have a live Opper account for the promised account/catalog and generation checks, so those remain unverified. I am leaving this open for the integration update and service verification.
Resolves the conflicts with API Route (TabularisDB#1459) and the inline completion and optional-key changes (TabularisDB#1455, TabularisDB#1457). Both providers are kept in every list, with Opper after Requesty and API Route after Opper. In ai.rs the Opper model fetch stays as step 7, followed by main's new custom-openai discovery and the API Route catalog. Inline completion goes through dispatch_provider, so it reaches Opper without further changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Thanks @NewtTheWolf. I merged the current main into the branch in a6f136c, the same way as before since you squash on merge. The conflicts were with API Route (#1459) and the inline completion and optional key changes (#1455, #1457). Both providers are now kept in every list. In For the account, catalog and generation checks: if you sign up at https://platform.opper.ai and send the account email to hello@opper.ai, we will put $10 of credits on it for testing. The catalog check needs no key, since |
|
The external AI assistant runtime from #1337 is now on "min_runtime_version": "0.32.1-4"The current nightly is For a complete published example, see Google Gemini on Tabularium, the Gemini plugin repository, and release 1.0.2. The release includes the standalone The authoring guide describes the declarative HTTP contract. New providers should use an external Please port the Opper integration in this PR to that package format; Gemini demonstrates the repository and release structure to follow. |
NewtTheWolf
left a comment
There was a problem hiding this comment.
Thanks for fixing the earlier ai_client_for integration and updating the branch. The target architecture has now changed: #1337 is merged, and external providers are declarative ai-assistant packages instead of additional Rust dispatch arms and hardcoded settings controls.
Please port Opper onto current main using plugins/ai-assistants/packages/opper/.tabularium and plugins/ai-assistants/README.md as the starting point. That existing example already expresses /v3/compat/chat/completions, X-Opper-Name: tabularis, the unauthenticated model source and its llm/pooled filters. Preserve the public catalog behavior and add fixture coverage for the generation path when validating the package. The Opper package will need an independent release and the real first supporting runtime version before production listing; the eight bundled providers do not need replacement releases.
On the current a6f136cb head, the focused frontend suites, typecheck and production build pass. pnpm lint fails Prettier on packages/web-ui/src/components/settings/AiTab.tsx, and GitHub reports conflicts with main. I also fetched the public models endpoint successfully: its response still has the fields the parser expects. I have not run a paid generation request or backend tests on this current head.
Requesting changes for the port and integration. This supersedes the old hardcoded-provider merge path; it does not require adding provider-specific Rust code to the new generic host.
Summary
Adds Opper, an EU-hosted, OpenAI-compatible AI gateway (700+ models from 50+ providers behind one API key), as an AI provider. It follows the Requesty integration step by step, so it shows up in Settings > AI next to Requesty and works for SQL generation, query explanation, explain plan analysis, cell and tab naming and table name suggestions.
Changes
src-tauri/src/ai.rs:generate_opper(POSThttps://api.opper.ai/v3/compat/chat/completions, same body as Requesty, with anX-Opper-Name: tabularisheader so calls are labelled in Opper's traces), dispatch arm, andfetch_opper_models, which reads Opper's public catalog (GET https://api.opper.ai/v3/models, no key needed) and keeps pooled chat models without duplicates. Merged into the static list like OpenRouter and Requesty.src-tauri/src/ai_models.yaml:opperentry withclaude-sonnet-4-6first as the default, plus a few more pool names. All ids checked against the live catalog.src-tauri/src/application/ai.rs,src-tauri/src/transport/desktop/config.rs:OPPER_API_KEYenv var for key lookup and key status.packages/web-ui: provider type, label, settings entry, key status check and an Opper icon (single colour,currentColor)..gitster/gitster.mdandsnap/snapcraft.yaml: Opper added to the provider lists.Pool names such as
claude-sonnet-4-6let Opper pick the provider per request; aprovider/modelid such asanthropic/claude-sonnet-4-6pins one route.How to test
OPPER_API_KEY.claude-sonnet-4-6(or refresh the model list to see all pooled models).Checks
I did not run the toolchains locally (no pnpm, cargo or vitest run); CI will be the first run. The new Rust code is written to rustfmt defaults and the TypeScript to the repo's Prettier config by hand. Model ids were checked against Opper's public catalog.
Disclosure: Opper is my startup. Happy to adjust anything to match project conventions.