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
+3 -3
View File
@@ -191,7 +191,7 @@ func (f AIBridgeListSessionsFilter) asRequestOption() RequestOption {
// AIBridgeListSessions returns AI Bridge sessions with the given filter.
func (c *Client) AIBridgeListSessions(ctx context.Context, filter AIBridgeListSessionsFilter) (AIBridgeListSessionsResponse, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/sessions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption())
res, err := c.Request(ctx, http.MethodGet, "/api/v2/ai-gateway/sessions", nil, filter.asRequestOption(), filter.Pagination.asRequestOption())
if err != nil {
return AIBridgeListSessionsResponse{}, err
}
@@ -206,7 +206,7 @@ func (c *Client) AIBridgeListSessions(ctx context.Context, filter AIBridgeListSe
// AIBridgeGetSessionThreads returns a single session with expanded
// thread details including agentic actions and thinking blocks.
func (c *Client) AIBridgeGetSessionThreads(ctx context.Context, sessionID string, afterID, beforeID uuid.UUID, limit int32) (AIBridgeSessionThreadsResponse, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/aibridge/sessions/%s", sessionID), nil, func(r *http.Request) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/ai-gateway/sessions/%s", sessionID), nil, func(r *http.Request) {
q := r.URL.Query()
if afterID != uuid.Nil {
q.Set("after_id", afterID.String())
@@ -232,7 +232,7 @@ func (c *Client) AIBridgeGetSessionThreads(ctx context.Context, sessionID string
// AIBridgeListClients returns the distinct AI clients visible to the caller.
func (c *Client) AIBridgeListClients(ctx context.Context) ([]string, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/clients", nil)
res, err := c.Request(ctx, http.MethodGet, "/api/v2/ai-gateway/clients", nil)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -38,7 +38,7 @@ type CreateAIGatewayKeyResponse struct {
// CreateAIGatewayKey creates a new AI Gateway key.
func (c *Client) CreateAIGatewayKey(ctx context.Context, req CreateAIGatewayKeyRequest) (CreateAIGatewayKeyResponse, error) {
res, err := c.Request(ctx, http.MethodPost, "/api/v2/aibridge/keys", req)
res, err := c.Request(ctx, http.MethodPost, "/api/v2/ai-gateway/keys", req)
if err != nil {
return CreateAIGatewayKeyResponse{}, xerrors.Errorf("make request: %w", err)
}
@@ -53,7 +53,7 @@ func (c *Client) CreateAIGatewayKey(ctx context.Context, req CreateAIGatewayKeyR
// ListAIGatewayKeys lists all AI Gateway keys.
func (c *Client) ListAIGatewayKeys(ctx context.Context) ([]AIGatewayKey, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/aibridge/keys", nil)
res, err := c.Request(ctx, http.MethodGet, "/api/v2/ai-gateway/keys", nil)
if err != nil {
return nil, xerrors.Errorf("make request: %w", err)
}
@@ -69,7 +69,7 @@ func (c *Client) ListAIGatewayKeys(ctx context.Context) ([]AIGatewayKey, error)
// DeleteAIGatewayKey deletes an AI Gateway key by ID.
func (c *Client) DeleteAIGatewayKey(ctx context.Context, id uuid.UUID) error {
res, err := c.Request(ctx, http.MethodDelete,
fmt.Sprintf("/api/v2/aibridge/keys/%s", id.String()), nil)
fmt.Sprintf("/api/v2/ai-gateway/keys/%s", id.String()), nil)
if err != nil {
return xerrors.Errorf("make request: %w", err)
}