From f1d6f4b1d0a9edf9d43611a3d6f03f65101d00c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alena=20Varko=C4=8Dkov=C3=A1?= Date: Wed, 28 Jan 2026 15:41:57 +0100 Subject: [PATCH] fix: add production support for AI Gateway via config.aiGatewayUrl In production embedded mode, the frontend now uses config.aiGatewayUrl (set by cloud-ui from REACT_APP_AI_GATEWAY_URL_TEMPLATE env var) to construct AI Gateway transport URLs. Changes: - Add aiGatewayUrl?: string to SetConfigArguments and Config types in config.ts - Update useAIGatewayTransport to use config.aiGatewayUrl when isEmbedded() - In production embedded: use config.aiGatewayUrl + /.redpanda/api - In development: use relative /.redpanda/api with dev server proxy - Fallback to relative path for standalone mode Cloud-ui passes aiGatewayUrl by: aiGatewayUrl: process.env.REACT_APP_AI_GATEWAY_URL_TEMPLATE?.replace('{clusterId}', clusterId) This enables environment-specific AI Gateway domains: - Integration: https://ai-gateway.{clusterId}.clusters.ign.rdpa.co - Staging: https://ai-gateway.{clusterId}.clusters.staging.rdpa.co - Production: https://ai-gateway.{clusterId}.clusters.prod.rdpa.co Fixes issue where production requests went to: https://main--redpanda-cloud.netlify.app/.redpanda/api/... Instead of: https://ai-gateway.{clusterId}.clusters.ign.rdpa.co/.redpanda/api/... Related: cloudv2 PR #24457 (adds REACT_APP_AI_GATEWAY_URL_TEMPLATE env var) Co-Authored-By: Claude Sonnet 4.5 --- frontend/src/config.ts | 2 + .../src/hooks/use-ai-gateway-transport.ts | 48 +++++++++++++++---- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/frontend/src/config.ts b/frontend/src/config.ts index 117407258f..0b797d7958 100644 --- a/frontend/src/config.ts +++ b/frontend/src/config.ts @@ -119,6 +119,7 @@ export type SetConfigArguments = { fetch?: WindowOrWorkerGlobalScope['fetch']; jwt?: string; clusterId?: string; + aiGatewayUrl?: string; urlOverride?: { rest?: string; ws?: string; @@ -147,6 +148,7 @@ export type Breadcrumb = { type Config = { controlplaneUrl: string; + aiGatewayUrl?: string; dataplaneTransport?: Transport; restBasePath: string; grpcBasePath: string; diff --git a/frontend/src/hooks/use-ai-gateway-transport.ts b/frontend/src/hooks/use-ai-gateway-transport.ts index 66e46d53fd..38d9ba9c56 100644 --- a/frontend/src/hooks/use-ai-gateway-transport.ts +++ b/frontend/src/hooks/use-ai-gateway-transport.ts @@ -1,29 +1,57 @@ import type { Transport } from '@connectrpc/connect'; import { createConnectTransport } from '@connectrpc/connect-web'; -import { addBearerTokenInterceptor } from 'config'; +import { addBearerTokenInterceptor, config, isEmbedded } from 'config'; import { protobufRegistry } from 'protobuf-registry'; import { useMemo } from 'react'; /** * Custom hook to create and memoize a Connect transport for AI Gateway API calls * - * Uses base path: /.redpanda/api/ - * Connect Query will append the service path: redpanda.api.aigateway.v1.GatewayService/ListGateways - * Full path becomes: /.redpanda/api/redpanda.api.aigateway.v1.GatewayService/ListGateways + * In Development: + * - Uses base path: /.redpanda/api/ + * - Dev server proxies to: https://ai-gateway.{clusterId}.clusters.ign.rdpa.co * - * Dev server proxies /.redpanda/api/redpanda.api.aigateway.v1 to: - * https://ai-gateway.${CLUSTER_ID}.clusters.ign.rdpa.co + * In Production (Embedded): + * - Uses config.aiGatewayUrl set by cloud-ui parent app (from REACT_APP_AI_GATEWAY_URL env var) + * - Appends /.redpanda/api to the base URL + * + * In Production (Standalone): + * - Uses relative path /.redpanda/api (backend handles routing) * * @returns Transport instance configured for AI Gateway communication */ export const useAIGatewayTransport = (): Transport => { const aiGatewayTransport = useMemo(() => { - // Use /.redpanda/api/ base path (AI Gateway's Connect RPC endpoint prefix) - // Dev server will proxy to the correct AI Gateway based on cluster ID - const baseUrl = '/.redpanda/api'; + // In development, use relative path and rely on dev server proxy + if (process.env.NODE_ENV === 'development') { + return createConnectTransport({ + baseUrl: '/.redpanda/api', + interceptors: [addBearerTokenInterceptor], + jsonOptions: { + registry: protobufRegistry, + }, + }); + } + + // In production embedded mode (cloud-ui), use AI Gateway URL from config + if (isEmbedded() && config.aiGatewayUrl) { + // Ensure URL ends with /.redpanda/api + const baseUrl = config.aiGatewayUrl.endsWith('/.redpanda/api') + ? config.aiGatewayUrl + : `${config.aiGatewayUrl}/.redpanda/api`; + + return createConnectTransport({ + baseUrl, + interceptors: [addBearerTokenInterceptor], + jsonOptions: { + registry: protobufRegistry, + }, + }); + } + // Fallback to relative path for standalone mode return createConnectTransport({ - baseUrl, + baseUrl: '/.redpanda/api', interceptors: [addBearerTokenInterceptor], jsonOptions: { registry: protobufRegistry,