feat(byok): per-user provider config — proxy URL + pinned model - #75
Open
harshithmullapudi wants to merge 1 commit into
Open
feat(byok): per-user provider config — proxy URL + pinned model#75harshithmullapudi wants to merge 1 commit into
harshithmullapudi wants to merge 1 commit into
Conversation
Extends the BYOK settings surface so users can configure their own
proxy endpoint + model per provider, not just an API key. Chats that
run against any of these keys still skip the aura debit — the debit
gate is `usedBYOK`, which stays true across all four slots.
Four provider rows on the settings card:
| slot | key | base URL | model |
| -------------- | --- | ------------ | --------- |
| Anthropic | req | — | optional |
| OpenAI | req | — | optional |
| OpenAI Proxy | req | required | optional |
| Ollama Cloud | req | optional | optional |
- Prisma: two nullable columns on ModelKey (baseUrl, model). Migration
20260728084341_modelkey_proxy_fields (safe: only adds columns).
- Store: adds "openai_proxy" to BYOK_PROVIDERS. Enforces baseUrl on
openai_proxy, drops baseUrl silently for providers that don't accept
it, always accepts a pinned model. resolveByokForUser walks all four
slots with LLM_PROVIDER as an explicit override and a natural priority
chain (anthropic → openai_proxy → openai → ollama).
- Chat model: four BYOK branches. anthropic/openai stay direct; openai_proxy
uses createOpenAI({ baseURL, apiKey }); ollama uses createOpenAICompatible
so a user can point at a self-hosted daemon or Ollama Cloud with their
own key.
- UI: four rows. baseUrl input renders for openai_proxy (required) and
ollama (optional). Model input renders for every provider. Saved rows
show "url · <baseUrl>" and/or "model · <id>" beneath the status pill.
- API: existing /api/byok POST already accepts optional baseUrl / model.
Store enforces per-provider rules; client-side validation surfaces
http(s):// checks and the openai_proxy baseUrl requirement.
Fallback behaviour unchanged: if a user has no BYOK row, resolveByokForUser
returns null and the platform env path (OPENAI_BASE_URL / *_CHAT_MODEL /
etc.) is used with normal aura debit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the BYOK settings surface so users can configure their own proxy endpoint and pinned model per provider — not just an API key. Chats that run against any of these keys still skip the aura debit; the gate is `usedBYOK`, which stays true across all four slots.
Four provider rows on the settings card:
Changes
Fallback behaviour
Unchanged: if a user has no BYOK row, `resolveByokForUser` returns `null` and `getChatModel` falls through to the platform env path (`OPENAI_BASE_URL`, `OPENAI_CHAT_MODEL`, `OPENAI_STRUCTURED_MODEL`, `ANTHROPIC_API_KEY`, etc.). Aura debits normally on that path.
Migration required
```bash
pnpm db:migrate
```
Applies `20260728084341_modelkey_proxy_fields` — two `ALTER TABLE` statements adding nullable columns. No data loss risk; existing rows keep working with `baseUrl = null, model = null` (falls back to defaults).
Test plan
🤖 Generated with Claude Code