feat: add /api/v2/ai-gateway API route aliases (#26475)

## Description

Registers `/api/v2/ai-gateway/*` as the new API path for AI Gateway, replacing `/api/v2/aibridge/*`. Both prefixes share the same route builder (`aiBridgeRoutes`) backed by a single in-memory handler, so existing `/aibridge` endpoints continue to work. New endpoints must be registered on the enterprise API handler under `/api/v2/ai-gateway` only.

Swagger annotations now point to `/api/v2/ai-gateway` paths with a backward-compatibility note referencing `/aibridge`. The legacy `/aibridge` routes are skipped in the swagger documentation test.

## Changes

- Store one raw handler (`aiGatewayHandler`) instead of two prefix-stripped handlers
- Register `/ai-gateway` and `/ai-gateway/proxy` route aliases alongside legacy `/aibridge` routes
- Move `/aibridge/keys` to `/ai-gateway/keys`
- Update in-process transport to use `/api/v2/ai-gateway` prefix
- Update SDK client URLs and proxy forwarding URL
- Swap `@Router` and `@Tags` annotations from `aibridge`/`AI Bridge` to `ai-gateway`/`AI Gateway`
- Rename user-facing error messages from "AI Bridge" to "AI Gateway"
- Define consts for route prefixes (`AIGatewayRootPath`, `AIBridgeRootPath`)
- Update tests and comments to use new paths

Note: the following will be addressed in follow-up PRs:
- Frontend API URLs
- Frontend routes and redirects
- Dogfood main.tf updates
- Hand-written documentation URL updates
- aibridge internal comments and nits
- Scale tests path updates

Refs https://linear.app/coder/issue/AIGOV-230

> Generated with the assistance of Coder Agents (@ssncferreira)
This commit is contained in:
Susana Ferreira
2026-06-23 12:15:10 +01:00
committed by GitHub
parent 4691ef39cd
commit 970bd73691
28 changed files with 727 additions and 630 deletions
+6 -6
View File
@@ -81,7 +81,7 @@ func TestAIGatewayKeys(t *testing.T) {
require.NoError(t, err)
fullKey := created.Key
resp, err := ownerClient.Request(ctx, http.MethodGet, "/api/v2/aibridge/keys", nil)
resp, err := ownerClient.Request(ctx, http.MethodGet, "/api/v2/ai-gateway/keys", nil)
require.NoError(t, err)
t.Cleanup(func() { _ = resp.Body.Close() })
require.Equal(t, http.StatusOK, resp.StatusCode)
@@ -137,7 +137,7 @@ func TestAIGatewayKeys(t *testing.T) {
// Invalid UUID -> 400 (raw request; SDK method accepts uuid.UUID).
//nolint:gocritic // Managing AI Gateway keys is owner-only.
resp, err := ownerClient.Request(ctx, http.MethodDelete, "/api/v2/aibridge/keys/not-a-uuid", nil)
resp, err := ownerClient.Request(ctx, http.MethodDelete, "/api/v2/ai-gateway/keys/not-a-uuid", nil)
require.NoError(t, err)
t.Cleanup(func() { _ = resp.Body.Close() })
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
@@ -148,7 +148,7 @@ func TestAIGatewayKeys(t *testing.T) {
})
require.NoError(t, err)
// SDK returns no code on success, using raw request to check for 204.
delResp, err := ownerClient.Request(ctx, http.MethodDelete, "/api/v2/aibridge/keys/"+created.ID.String(), nil)
delResp, err := ownerClient.Request(ctx, http.MethodDelete, "/api/v2/ai-gateway/keys/"+created.ID.String(), nil)
require.NoError(t, err)
defer delResp.Body.Close()
require.Equal(t, http.StatusNoContent, delResp.StatusCode)
@@ -333,7 +333,7 @@ func TestAIGatewayKeysDatabaseErrors(t *testing.T) {
name: "CreateDBError",
errStore: aiGatewayKeyErrorStore{insertErr: dbErr},
method: http.MethodPost,
path: "/api/v2/aibridge/keys",
path: "/api/v2/ai-gateway/keys",
body: codersdk.CreateAIGatewayKeyRequest{Name: "db-err-create"},
wantStatus: http.StatusInternalServerError,
wantMsg: "Failed to create key. Please retry.",
@@ -342,7 +342,7 @@ func TestAIGatewayKeysDatabaseErrors(t *testing.T) {
name: "ListDBError",
errStore: aiGatewayKeyErrorStore{listErr: dbErr},
method: http.MethodGet,
path: "/api/v2/aibridge/keys",
path: "/api/v2/ai-gateway/keys",
wantStatus: http.StatusInternalServerError,
wantMsg: "Failed to list keys.",
},
@@ -350,7 +350,7 @@ func TestAIGatewayKeysDatabaseErrors(t *testing.T) {
name: "DeleteDBError",
errStore: aiGatewayKeyErrorStore{deleteErr: dbErr},
method: http.MethodDelete,
path: "/api/v2/aibridge/keys/" + uuid.New().String(),
path: "/api/v2/ai-gateway/keys/" + uuid.New().String(),
wantStatus: http.StatusInternalServerError,
wantMsg: "Failed to delete key.",
},