Skip to content

fix(chat): route through LiteLLM gateway, default to protolabs/smart#3619

Merged
mabry1985 merged 2 commits into
mainfrom
fix/chat-default-to-gateway-protolabs-smart
May 22, 2026
Merged

fix(chat): route through LiteLLM gateway, default to protolabs/smart#3619
mabry1985 merged 2 commits into
mainfrom
fix/chat-default-to-gateway-protolabs-smart

Conversation

@mabry1985
Copy link
Copy Markdown
Contributor

Why

Ava chat was unusable — Anthropic returned rate_limit_error with a useless "message":"Error" on every call. The chat path was going direct to api.anthropic.com via @ai-sdk/anthropic. The team direction is gateway-first: no Anthropic keys, no direct calls, everything routed through https://api.proto-labs.ai/v1.

This PR yanks the direct-Anthropic path out of chat.

Changes

  • apps/server/src/lib/ai-provider.ts — rewritten to use @ai-sdk/openai-compatible pointed at the gateway. Auth chain:

    1. GATEWAY_API_KEY env
    2. OPENAI_API_KEY env (alias — gateway accepts both)
    3. apiKeys.protolabsGateway from settings credentials

    Legacy Claude aliases (sonnet, opus, haiku, anything starting with claude-) are silently remapped to protolabs/smart so the UI's stored "sonnet" defaults don't blow up mid-migration.

  • apps/server/src/routes/chat/index.ts — default model alias goes from 'sonnet''protolabs/smart'. Existing fall-back chain (header > body > avaConfig.model > default) is preserved.

  • apps/server/package.json — adds @ai-sdk/openai-compatible.

Validation

( cd apps/server && npm run build )
GATEWAY_API_KEY=... GATEWAY_BASE_URL=https://api.proto-labs.ai/v1 \
  node apps/server/dist/apps/server/src/index.js

# server.log:
[AIProvider] Gateway provider initialized: baseURL=https://api.proto-labs.ai/v1 keySource=env.GATEWAY_API_KEY

# POST /api/chat:
data: {"type":"reasoning-start","id":"reasoning-0"}
data: {"type":"reasoning-delta","delta":"The"}
data: {"type":"reasoning-delta","delta":" user"}
... (full stream from protolabs/smart)

Before this change, that same payload returned rate_limit_error and NoOutputGeneratedError. The previous Anthropic-direct path is no longer reachable from /api/chat.

Kept intentionally (for follow-ups)

  • Export name getAnthropicModel is unchanged. Renaming touches ~10 call sites with no behavior change. Rename in a follow-up.
  • providerOptions.anthropic block in chat/index.ts (extended thinking, contextManagement) stays as-is. The AI SDK ignores provider-specific options when the active provider doesn't match, so these are inert under openai-compatible. Cleanup later.
  • Settings UI "Claude" provider tile + Anthropic credential field can be removed in a separate UI-side PR. They're inert now because no code path consumes the Anthropic API key.

Operational note

The server process needs GATEWAY_API_KEY and (optionally) GATEWAY_BASE_URL in its environment. For host-process systemd (the automaker-host.service from PR #3617), drop them into /etc/systemd/system/automaker-host.service.d/override.conf:

[Service]
Environment=GATEWAY_API_KEY=...
Environment=GATEWAY_BASE_URL=https://api.proto-labs.ai/v1

…or pipe from Infisical at deploy time.

## Why

Ava chat was unusable: Anthropic returned `rate_limit_error` with no
useful message on every call. The chat path was going direct to
api.anthropic.com via @ai-sdk/anthropic. The team direction is
gateway-first: no Anthropic keys, no direct calls, everything routed
through https://api.proto-labs.ai/v1.

## Changes

- `apps/server/src/lib/ai-provider.ts` — rewrite to use
  `@ai-sdk/openai-compatible` pointed at the gateway. Auth chain:
  GATEWAY_API_KEY env > OPENAI_API_KEY env > settings credentials.
  Legacy Claude aliases (`sonnet`, `opus`, `haiku`, anything starting
  with `claude-`) get silently remapped to `protolabs/smart` so the
  UI's stored "sonnet" defaults don't blow up mid-migration.
- `apps/server/src/routes/chat/index.ts` — default model alias goes
  from `'sonnet'` to `'protolabs/smart'`. Existing fall-back chain
  (header > body > avaConfig.model > default) is preserved.
- `apps/server/package.json` — adds `@ai-sdk/openai-compatible`.

## Kept intentionally

- Export name `getAnthropicModel` is unchanged. Renaming touches ~10
  call sites and adds churn without behavior change. Follow-up.
- `providerOptions.anthropic` block in chat/index.ts (extended
  thinking, contextManagement) stays as-is. The AI SDK ignores
  provider-specific options when the active provider doesn't match,
  so these are inert under openai-compatible. Cleanup in a follow-up.
- The settings UI "Claude" provider tile and Anthropic credential
  field can be removed in a separate UI-side PR. They're currently
  inert because no code path consumes the Anthropic API key anymore.

## Validation

- `tsc --noEmit` clean
- Local smoke test against this branch's build:
  - server.log: `Gateway provider initialized: baseURL=https://api.proto-labs.ai/v1`
  - POST /api/chat with the broken-before payload now streams
    `reasoning-delta` and text tokens from `protolabs/smart`
- The previous Anthropic rate_limit_error path is no longer
  reachable from /api/chat.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Warning

Rate limit exceeded

@mabry1985 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 4 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9bb0177-f23b-4c00-b318-8d297203dd0f

📥 Commits

Reviewing files that changed from the base of the PR and between ebc038e and 37f5c83.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • apps/server/package.json
  • apps/server/src/lib/ai-provider.ts
  • apps/server/src/routes/chat/index.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/chat-default-to-gateway-protolabs-smart

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

Code Review — ? finding(s)

Async review running parallel to CodeRabbit. Findings are advisory; not all are merge blockers.

protoLabs Code Review Report

  • Generated: 2026-05-22T06:41:07Z
  • Git head: 35bfc6a6edd9dadd75d06819f6fae0ce999a77df
  • Features mapped: 3
  • Findings: 0

No findings recorded.

`n/no-extraneous-import` ESLint rule (enforced in CI's lint step)
flagged the `LanguageModelV3` type import from @ai-sdk/provider as
extraneous because we used a transitive dep without declaring it.
Adds it to apps/server's dependencies. No runtime change.
@github-actions
Copy link
Copy Markdown
Contributor

Code Review — ? finding(s)

Async review running parallel to CodeRabbit. Findings are advisory; not all are merge blockers.

protoLabs Code Review Report

  • Generated: 2026-05-22T06:46:36Z
  • Git head: e1162fd2cf5e83f71ed9402e5d366d541e596cd8
  • Features mapped: 3
  • Findings: 0

No findings recorded.

@mabry1985 mabry1985 merged commit 18e082b into main May 22, 2026
6 checks passed
@mabry1985 mabry1985 deleted the fix/chat-default-to-gateway-protolabs-smart branch May 22, 2026 06:51
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.

1 participant