fix: AI Proxy fixes#3571
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Greptile SummaryThis PR fixes the AI Proxy (Nexus) by bumping Bifrost and refactoring the OpenAI routing layer to support CHAT/RESPONSES/AUTO method selection with cross-format fallbacks, and extends the deployment-operator harness with proxy model prefixing, OpenAI-compatible custom endpoints, and Docker-in-Docker bash permission improvements.
Confidence Score: 4/5Generally safe to merge; one stream-cancellation gap in the cross-format fallback path could leave upstream Bifrost streams open longer than needed when a client disconnects mid-stream on the responsesViaChat path. The responsesViaChat streaming branch in handleStreaming logs write errors from writeChatStreamAsResponses but does not call cancel() or return, unlike every other write-error site in that function. If a client disconnects during a long multi-chunk response on this path, the upstream stream stays running and each subsequent chunk re-enters the branch, fails, and is logged until the channel drains. All other routing paths are well-tested and the change is otherwise well-structured. go/nexus/internal/router/router.go — the responsesViaChat streaming branch around line 409
|
| Filename | Overview |
|---|---|
| go/nexus/internal/router/router.go | Added responsesViaChat cross-format handling and releaseChatToResponsesStreamState defer; the responsesViaChat streaming path doesn't call cancel() on write errors, unlike all other write-error paths in this function. |
| go/nexus/internal/router/openai_method.go | New file implementing HTTP policy for OpenAI method routing (CHAT/RESPONSES/AUTO) with cross-format fallback via BifrostContext keys; logic and tests look correct. |
| go/nexus/internal/router/openai_routing_stream.go | New file wrapping chat→responses stream conversion with pool state management; writeStreamSSE duplicates SSE-writing logic from router.go but is otherwise correct. |
| go/nexus/internal/router/openai_raw_response.go | New helper that gates raw-response passthrough when cross-format fallbacks are active; correctly skips passthrough for chatViaResponses and responsesViaChat paths. |
| go/nexus/internal/router/openai_allowed_requests.go | Configures Bifrost AllowedRequests gating to match the configured OpenAI method; clean and well-tested. |
| go/nexus/internal/router/account_keys.go | Migrated Bedrock and Azure deployments from KeyConfig.Deployments to Key.Aliases, matching updated bifrost API. |
| go/nexus/internal/router/provider_base_url.go | Strips trailing /v1 from Console-style base URLs for Bifrost compatibility; well-tested including edge cases. |
| lib/console/ai/provider/nexus.ex | Extracted openai_base_url/1 helper to avoid double-appending /v1; tests verify no-double-append and trailing-slash cases. |
| lib/console/grpc/server.ex | Added openai_method_to_pb/1 to serialize the new method field; nil maps to :AUTO which falls through the same default case as UNSPECIFIED in Go. |
| go/deployment-operator/api/v1alpha1/agentruntime_types.go | Added OpenAICompatible config block for custom endpoints, aiProxy helpers, secretKeySelectorSet guard, and omitempty on raw API-key fields; changes are backwards-compatible. |
| go/deployment-operator/pkg/agentrun-harness/model/proxy.go | New package providing ProxyProvider and ProxyModel helpers; replaces ad-hoc openai/ prefix logic scattered across tool packages. |
| go/deployment-operator/pkg/agentrun-harness/tool/opencode/opencode_types.go | Refactored EnsureProvider to pass through arbitrary provider slugs, added ProviderOpenAICompatible constant, and extracted resolveOpenCodeSettings for cleaner provider/model wiring. |
| go/deployment-operator/pkg/agentrun-harness/tool/opencode/templates/opencode.json.gotmpl | Added DindEnabled bash permission toggle, optional baseURL for non-plural providers, and openai-compatible npm block; template conditionals produce valid JSON in all branches. |
Reviews (2): Last reviewed commit: "better ai proxy documentation" | Re-trigger Greptile
* bumps bifrost + some api refactors as a result
3e4a7c6 to
fd909f8
Compare
|
plural deploy this, and use modify the tag for the ai proxy too alongside it |
d31afff to
eeb159c
Compare
eeb159c to
6646546
Compare
6646546 to
9564c6e
Compare
7908f0f to
8094d4b
Compare
|
plural deploy this, and also modify the ai proxy tag alongside it |
|
plural deploy this, alonside the ai proxy as well |
| case chunk.BifrostChatResponse != nil: | ||
| if responsesViaChat(ctx) { | ||
| if err := in.writeChatStreamAsResponses(w, ctx, config, chunk.BifrostChatResponse); err != nil { | ||
| in.logger.Error("failed to convert chat stream chunk to responses format", zap.Error(err)) | ||
| } | ||
| flusher.Flush() | ||
| continue | ||
| } |
There was a problem hiding this comment.
Stream not cancelled on write error in responsesViaChat path
When writeChatStreamAsResponses returns an error — typically because the client disconnected and a write to w failed — cancel() is not called, so the upstream Bifrost stream keeps running. Every subsequent chunk in the channel will re-enter this branch, fail again, and be logged, burning server resources until Bifrost drains the whole response. The parallel non-fallback write paths both call cancel() and return on write failures (lines 451, 466). This path should do the same.
There was a problem hiding this comment.
there's a defer cancel at the top of the function
29fa5be to
2838679
Compare
5ba2056 to
fc1ec15
Compare
|
plural deploy this, and the nexus proxy image too |
93b6bd7 to
5ed503f
Compare
1606507 to
3c71a03
Compare
|
plural deploy this, and the ai proxy tag too |
|
plural deploy this, plus the ai proxy tag |
8392fb5 to
52c85e7
Compare
52c85e7 to
c89bfc8
Compare
|
plural deploy this |
|
plural deploy this |
|
yea I'm not positive as well, we should probably merge it and work on opencode separately in another pr so this doesn't back up any further. |

Fixes PROD-4851
Test Plan
Test environment: https://console.plrldemo.onplural.sh/cd/clusters/a1748282-ce8b-48ab-ae7e-326e74fce04e/services/f3f89a54-d1a7-4bc8-9152-daa07ede918d/settings/secrets
Checklist
Plural Flow: console