Skip to content

Commit fe88a09

Browse files
alenkaczclaude
andcommitted
refactor: address all code review comments from @malinskibeniamin
This commit addresses all code review comments on PR #2175: 1. Revert rsbuild port configuration (frontend/rsbuild.config.ts:51) - Removed hardcoded port: 3004 - Use `bun run start` for enterprise or `bun run start2 --port=3004` for Module Federation 2. Split ai-gateway.tsx into separate files (frontend/src/react-query/api/ai-gateway.tsx:1) - Created ai-gateway/model-providers.tsx for useListModelProvidersQuery - Created ai-gateway/models.tsx for useListModelsQuery - Kept ai-gateway.tsx for useListGatewaysQuery only - Added documentation about AI Gateway transport requirement at top of each file 3. Remove pageSize override in component (frontend/src/components/pages/agents/create/ai-agent-create-page.tsx:84) - Removed pageSize: 100 from useListGatewaysQuery call - Now uses AI_GATEWAY_DEFAULT_PAGE_SIZE (50) from hook 4. Update imports in consuming components - Updated llm-config-section.tsx to import from separate files - Updated ai-agent-configuration-tab.tsx to import from separate files Note: The [nit] comment about nested ternary operators (line 326) is acknowledged and will be addressed in a subsequent PR as suggested. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 3c8965c commit fe88a09

7 files changed

Lines changed: 161 additions & 101 deletions

File tree

frontend/rsbuild.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export default defineConfig({
4848
},
4949
},
5050
server: {
51-
port: 3004,
5251
htmlFallback: 'index',
5352
cors: {
5453
origin: ['http://localhost:3000', 'http://localhost:9090'],

frontend/src/components/pages/agents/create/ai-agent-create-page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export const AIAgentCreatePage = () => {
8080
// Gateway detection and list query (using v1 API from ai-gateway module)
8181
// Only fetch when NOT in legacy mode
8282
const { data: gatewaysData, isLoading: isLoadingGateways } = useListGatewaysQuery(
83-
{ pageSize: 100 },
83+
{},
8484
{ enabled: !isLegacyApiKeyMode }
8585
);
8686

frontend/src/components/pages/agents/details/ai-agent-configuration-tab.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ import {
6666
} from 'protogen/redpanda/api/dataplane/v1alpha3/ai_agent_pb';
6767
import { useCallback, useMemo, useState } from 'react';
6868
import { useGetAIAgentQuery, useUpdateAIAgentMutation } from 'react-query/api/ai-agent';
69-
import { useListGatewaysQuery, useListModelProvidersQuery, useListModelsQuery } from 'react-query/api/ai-gateway';
69+
import { useListGatewaysQuery } from 'react-query/api/ai-gateway';
70+
import { useListModelProvidersQuery } from 'react-query/api/ai-gateway/model-providers';
71+
import { useListModelsQuery } from 'react-query/api/ai-gateway/models';
7072
import { type MCPServer, useListMCPServersQuery } from 'react-query/api/remote-mcp';
7173
import { useListSecretsQuery } from 'react-query/api/secret';
7274
import { toast } from 'sonner';

frontend/src/components/ui/ai-agent/llm-config-section.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ import {
3333
import type { Scope } from "protogen/redpanda/api/dataplane/v1/secret_pb";
3434
import { useEffect, useMemo } from "react";
3535
import { Controller, type UseFormReturn } from "react-hook-form";
36-
import {
37-
useListModelProvidersQuery,
38-
useListModelsQuery,
39-
} from "react-query/api/ai-gateway";
36+
import { useListModelProvidersQuery } from "react-query/api/ai-gateway/model-providers";
37+
import { useListModelsQuery } from "react-query/api/ai-gateway/models";
4038

4139
import { MODEL_OPTIONS_BY_PROVIDER } from "../../pages/agents/ai-agent-model";
4240

Lines changed: 21 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
/**
2+
* AI Gateway Query Hooks
3+
*
4+
* IMPORTANT: All queries in this file must use the AI Gateway transport.
5+
* Use `useAIGatewayTransport()` hook to create the transport that points to /.redpanda/api/
6+
*
7+
* The AI Gateway transport is configured to proxy requests through:
8+
* - Dev: /.redpanda/api/redpanda.api.aigateway.v1.* proxied to AI Gateway service
9+
* - Prod: /.redpanda/api/redpanda.api.aigateway.v1.* handled by backend proxy
10+
*/
11+
112
import { create } from '@bufbuild/protobuf';
213
import type { GenMessage } from '@bufbuild/protobuf/codegenv1';
314
import type { ConnectError } from '@connectrpc/connect';
@@ -10,26 +21,22 @@ import {
1021
type ListGatewaysResponse,
1122
} from 'protogen/redpanda/api/aigateway/v1/gateway_pb';
1223
import { listGateways } from 'protogen/redpanda/api/aigateway/v1/gateway-GatewayService_connectquery';
13-
import {
14-
type ListModelProvidersRequest,
15-
ListModelProvidersRequestSchema,
16-
type ListModelProvidersResponse,
17-
} from 'protogen/redpanda/api/aigateway/v1/model_providers_pb';
18-
import { listModelProviders } from 'protogen/redpanda/api/aigateway/v1/model_providers-ModelProvidersService_connectquery';
19-
import {
20-
type ListModelsRequest,
21-
ListModelsRequestSchema,
22-
type ListModelsResponse,
23-
} from 'protogen/redpanda/api/aigateway/v1/models_pb';
24-
import { listModels } from 'protogen/redpanda/api/aigateway/v1/models-ModelsService_connectquery';
2524
import type { MessageInit, QueryOptions } from 'react-query/react-query.utils';
2625

2726
const AI_GATEWAY_DEFAULT_PAGE_SIZE = 50;
2827

2928
/**
3029
* Hook to list AI Gateways using the AI Gateway v1 API
31-
* Creates its own AI Gateway transport pointing to: /.redpanda/api/
32-
* Dev server proxies /.redpanda/api/redpanda.aigateway.v1 to AI Gateway service
30+
*
31+
* @note This hook uses AI Gateway transport - requires /.redpanda/api/ proxy configuration
32+
*
33+
* @example
34+
* // List all gateways
35+
* useListGatewaysQuery()
36+
*
37+
* @example
38+
* // List gateways with custom page size
39+
* useListGatewaysQuery({ pageSize: 100 })
3340
*/
3441
export const useListGatewaysQuery = (
3542
input?: MessageInit<ListGatewaysRequest>,
@@ -48,83 +55,3 @@ export const useListGatewaysQuery = (
4855
transport,
4956
});
5057
};
51-
52-
// Provider regex for stripping name prefix
53-
const PROVIDER_PREFIX_REGEX = /^model_providers\//;
54-
55-
// Transform function for model providers - strips "model_providers/" prefix from names
56-
const transformModelProviders = (response: ListModelProvidersResponse) => ({
57-
...response,
58-
modelProviders: response.modelProviders.map((provider) => ({
59-
...provider,
60-
name: provider.name.replace(PROVIDER_PREFIX_REGEX, ''),
61-
})),
62-
});
63-
64-
/**
65-
* Hook to list Model Providers using the AI Gateway v1 API
66-
* Lists available LLM providers (OpenAI, Anthropic, Google, etc.)
67-
*
68-
* @note Provider names are automatically transformed to strip the "model_providers/" prefix
69-
*/
70-
export const useListModelProvidersQuery = (
71-
input?: MessageInit<ListModelProvidersRequest>,
72-
options?: QueryOptions<GenMessage<ListModelProvidersRequest>, ListModelProvidersResponse>
73-
): UseQueryResult<ReturnType<typeof transformModelProviders>, ConnectError> => {
74-
const transport = useAIGatewayTransport();
75-
76-
const listModelProvidersRequest = create(ListModelProvidersRequestSchema, {
77-
pageToken: input?.pageToken ?? '',
78-
pageSize: input?.pageSize ?? AI_GATEWAY_DEFAULT_PAGE_SIZE,
79-
...(input?.filter && { filter: input.filter }),
80-
});
81-
82-
return useQuery(listModelProviders, listModelProvidersRequest, {
83-
enabled: options?.enabled,
84-
transport,
85-
select: transformModelProviders,
86-
});
87-
};
88-
89-
// Model regex for stripping name prefix
90-
const MODEL_PREFIX_REGEX = /^models\/[^/]+\//;
91-
92-
// Transform function for models - strips "models/provider/" prefix from names
93-
// e.g., "models/openai/gpt-4o-mini" -> "gpt-4o-mini"
94-
const transformModels = (response: ListModelsResponse) => ({
95-
...response,
96-
models: response.models.map((model) => ({
97-
...model,
98-
name: model.name.replace(MODEL_PREFIX_REGEX, ''),
99-
})),
100-
});
101-
102-
/**
103-
* Hook to list Models using the AI Gateway v1 API
104-
* Lists available models, optionally filtered by provider
105-
*
106-
* @note Model names are automatically transformed to strip the "models/provider/" prefix
107-
*
108-
* @example
109-
* // Filter by provider
110-
* useListModelsQuery({ filter: 'provider = "openai"' })
111-
*/
112-
export const useListModelsQuery = (
113-
input?: MessageInit<ListModelsRequest>,
114-
options?: QueryOptions<GenMessage<ListModelsRequest>, ListModelsResponse>
115-
): UseQueryResult<ReturnType<typeof transformModels>, ConnectError> => {
116-
const transport = useAIGatewayTransport();
117-
118-
const listModelsRequest = create(ListModelsRequestSchema, {
119-
pageToken: input?.pageToken ?? '',
120-
pageSize: input?.pageSize ?? AI_GATEWAY_DEFAULT_PAGE_SIZE,
121-
...(input?.filter && { filter: input.filter }),
122-
...(input?.orderBy && { orderBy: input.orderBy }),
123-
});
124-
125-
return useQuery(listModels, listModelsRequest, {
126-
enabled: options?.enabled,
127-
transport,
128-
select: transformModels,
129-
});
130-
};
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* AI Gateway Model Providers Query Hook
3+
*
4+
* IMPORTANT: All queries in this file must use the AI Gateway transport.
5+
* Use `useAIGatewayTransport()` hook to create the transport that points to /.redpanda/api/
6+
*/
7+
8+
import { create } from '@bufbuild/protobuf';
9+
import type { GenMessage } from '@bufbuild/protobuf/codegenv1';
10+
import type { ConnectError } from '@connectrpc/connect';
11+
import { useQuery } from '@connectrpc/connect-query';
12+
import type { UseQueryResult } from '@tanstack/react-query';
13+
import { useAIGatewayTransport } from 'hooks/use-ai-gateway-transport';
14+
import {
15+
type ListModelProvidersRequest,
16+
ListModelProvidersRequestSchema,
17+
type ListModelProvidersResponse,
18+
} from 'protogen/redpanda/api/aigateway/v1/model_providers_pb';
19+
import { listModelProviders } from 'protogen/redpanda/api/aigateway/v1/model_providers-ModelProvidersService_connectquery';
20+
import type { MessageInit, QueryOptions } from 'react-query/react-query.utils';
21+
22+
const AI_GATEWAY_DEFAULT_PAGE_SIZE = 50;
23+
24+
// Provider regex for stripping name prefix
25+
const PROVIDER_PREFIX_REGEX = /^model_providers\//;
26+
27+
// Transform function for model providers - strips "model_providers/" prefix from names
28+
const transformModelProviders = (response: ListModelProvidersResponse) => ({
29+
...response,
30+
modelProviders: response.modelProviders.map((provider) => ({
31+
...provider,
32+
name: provider.name.replace(PROVIDER_PREFIX_REGEX, ''),
33+
})),
34+
});
35+
36+
/**
37+
* Hook to list Model Providers using the AI Gateway v1 API
38+
* Lists available LLM providers (OpenAI, Anthropic, Google, etc.)
39+
*
40+
* @note Provider names are automatically transformed to strip the "model_providers/" prefix
41+
* @note This hook uses AI Gateway transport - requires /.redpanda/api/ proxy configuration
42+
*
43+
* @example
44+
* // Get all enabled providers
45+
* useListModelProvidersQuery({ filter: 'enabled = "true"' })
46+
*/
47+
export const useListModelProvidersQuery = (
48+
input?: MessageInit<ListModelProvidersRequest>,
49+
options?: QueryOptions<GenMessage<ListModelProvidersRequest>, ListModelProvidersResponse>
50+
): UseQueryResult<ReturnType<typeof transformModelProviders>, ConnectError> => {
51+
const transport = useAIGatewayTransport();
52+
53+
const listModelProvidersRequest = create(ListModelProvidersRequestSchema, {
54+
pageToken: input?.pageToken ?? '',
55+
pageSize: input?.pageSize ?? AI_GATEWAY_DEFAULT_PAGE_SIZE,
56+
...(input?.filter && { filter: input.filter }),
57+
});
58+
59+
return useQuery(listModelProviders, listModelProvidersRequest, {
60+
enabled: options?.enabled,
61+
transport,
62+
select: transformModelProviders,
63+
});
64+
};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* AI Gateway Models Query Hook
3+
*
4+
* IMPORTANT: All queries in this file must use the AI Gateway transport.
5+
* Use `useAIGatewayTransport()` hook to create the transport that points to /.redpanda/api/
6+
*/
7+
8+
import { create } from '@bufbuild/protobuf';
9+
import type { GenMessage } from '@bufbuild/protobuf/codegenv1';
10+
import type { ConnectError } from '@connectrpc/connect';
11+
import { useQuery } from '@connectrpc/connect-query';
12+
import type { UseQueryResult } from '@tanstack/react-query';
13+
import { useAIGatewayTransport } from 'hooks/use-ai-gateway-transport';
14+
import {
15+
type ListModelsRequest,
16+
ListModelsRequestSchema,
17+
type ListModelsResponse,
18+
} from 'protogen/redpanda/api/aigateway/v1/models_pb';
19+
import { listModels } from 'protogen/redpanda/api/aigateway/v1/models-ModelsService_connectquery';
20+
import type { MessageInit, QueryOptions } from 'react-query/react-query.utils';
21+
22+
const AI_GATEWAY_DEFAULT_PAGE_SIZE = 50;
23+
24+
// Model regex for stripping name prefix
25+
const MODEL_PREFIX_REGEX = /^models\/[^/]+\//;
26+
27+
// Transform function for models - strips "models/provider/" prefix from names
28+
// e.g., "models/openai/gpt-4o-mini" -> "gpt-4o-mini"
29+
const transformModels = (response: ListModelsResponse) => ({
30+
...response,
31+
models: response.models.map((model) => ({
32+
...model,
33+
name: model.name.replace(MODEL_PREFIX_REGEX, ''),
34+
})),
35+
});
36+
37+
/**
38+
* Hook to list Models using the AI Gateway v1 API
39+
* Lists available models, optionally filtered by provider
40+
*
41+
* @note Model names are automatically transformed to strip the "models/provider/" prefix
42+
* @note This hook uses AI Gateway transport - requires /.redpanda/api/ proxy configuration
43+
*
44+
* @example
45+
* // Filter by provider
46+
* useListModelsQuery({ filter: 'provider = "openai"' })
47+
*
48+
* @example
49+
* // Filter by provider and enabled status
50+
* useListModelsQuery({ filter: 'provider = "openai" AND enabled = "true"' })
51+
*/
52+
export const useListModelsQuery = (
53+
input?: MessageInit<ListModelsRequest>,
54+
options?: QueryOptions<GenMessage<ListModelsRequest>, ListModelsResponse>
55+
): UseQueryResult<ReturnType<typeof transformModels>, ConnectError> => {
56+
const transport = useAIGatewayTransport();
57+
58+
const listModelsRequest = create(ListModelsRequestSchema, {
59+
pageToken: input?.pageToken ?? '',
60+
pageSize: input?.pageSize ?? AI_GATEWAY_DEFAULT_PAGE_SIZE,
61+
...(input?.filter && { filter: input.filter }),
62+
...(input?.orderBy && { orderBy: input.orderBy }),
63+
});
64+
65+
return useQuery(listModels, listModelsRequest, {
66+
enabled: options?.enabled,
67+
transport,
68+
select: transformModels,
69+
});
70+
};

0 commit comments

Comments
 (0)