[ Gateway 6/10 ]Add Create endpoint page and enhance provider select#19475
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds the foundation for the Endpoint Create page in the AI Gateway UI, focusing on provider selection functionality. It introduces a sophisticated provider grouping system that coalesces related providers (OpenAI/Azure OpenAI and Google Vertex AI variants) and includes backend changes to support dictionary-based masked values for multi-field credentials.
Key Changes:
- Enhanced provider selection with grouping and variant selection for special providers (OpenAI/Azure, Vertex AI)
- Backend changes to support dict-based masked values instead of strings, with increased VARCHAR size (100→500)
- New utility modules for provider formatting, error handling, date conversion, and secret management
- Create endpoint page with provider selection (model selection deferred to future PRs)
Reviewed changes
Copilot reviewed 94 out of 99 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
mlflow/utils/crypto.py |
Refactored masking to return dict format, separated string masking logic |
mlflow/store/tracking/gateway/sqlalchemy_mixin.py |
Updated to JSON-serialize masked value dicts |
mlflow/store/tracking/dbmodels/models.py |
Increased masked_value column size, added JSON deserialization |
tests/utils/test_crypto.py |
Updated tests to expect dict-based masked values |
tests/tracking/test_rest_tracking.py |
Updated integration tests for dict masked values |
tests/store/tracking/test_gateway_sql_store.py |
Updated store tests for dict format |
tests/entities/test_gateway_secrets.py |
Added tests for multi-key masked values |
tests/db/schemas/*.sql |
Increased masked_value VARCHAR from 100 to 500 |
mlflow/server/js/src/gateway/utils/providerUtils.ts |
Provider grouping, formatting, and display name utilities |
mlflow/server/js/src/gateway/utils/errorUtils.ts |
Error message parsing and user-friendly error generation |
mlflow/server/js/src/gateway/utils/dateUtils.ts |
Timestamp conversion handling seconds vs milliseconds |
mlflow/server/js/src/gateway/hooks/useCreateEndpointForm.ts |
Form state management for endpoint creation |
mlflow/server/js/src/gateway/components/create-endpoint/ProviderSelect.tsx |
Complex provider selection with grouping and variants |
mlflow/server/js/src/gateway/components/endpoint-form/EndpointFormRenderer.tsx |
Reusable form renderer for create/edit modes |
mlflow/server/js/src/gateway/pages/CreateEndpointPage.tsx |
Create endpoint page container |
mlflow/server/js/src/lang/default/en.json |
Added i18n strings for new features |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Documentation preview for f5d0cd1 is available at: More info
|
f4f1445 to
71d1e19
Compare
2d979c2 to
e9479bb
Compare
| const openaiAzureProviders: string[] = []; | ||
| const vertexProviders: string[] = []; | ||
| const ungroupedProviders: string[] = []; |
There was a problem hiding this comment.
nit: Is is easier to have Map<key of PROVIDER_GROUPS, string>?
| if (b === 'openai') return 1; | ||
| if (a === 'azure') return -1; | ||
| if (b === 'azure') return 1; | ||
| return a.localeCompare(b); |
There was a problem hiding this comment.
I think it's fine to hardcode openaiAzureProviders = ['openai', 'azure'] as it's simpler
| ); | ||
| }; | ||
|
|
||
| export const isSecretNameConflict = (error: unknown): boolean => { |
There was a problem hiding this comment.
is this used anywhere?
There was a problem hiding this comment.
@BenWilson2 do we plan to use this function in the future pr?
| return lowerMessage.includes('endpoints.name') || lowerMessage.includes('endpoint_name'); | ||
| }; | ||
|
|
||
| export const isSecretNameError = (message: string): boolean => { |
There was a problem hiding this comment.
Do we need to export this function?
There was a problem hiding this comment.
no, this should be module private. Thanks for the catch :) Updated the private ones to not export and left 2 as exported that need to be used externally.
| ); | ||
| }; | ||
|
|
||
| export const isEndpointNameError = (message: string): boolean => { |
| @@ -0,0 +1,66 @@ | |||
| export const isUniqueConstraintError = (message: string): boolean => { | |||
| return isUniqueConstraintError(errorMessage) && isSecretNameError(errorMessage); | ||
| }; | ||
|
|
||
| export interface GetReadableErrorMessageOptions { |
| action?: 'creating' | 'updating' | 'deleting'; | ||
| } | ||
|
|
||
| export const getReadableErrorMessage = ( |
There was a problem hiding this comment.
can we have tests for this function?
| 'vertex_ai-vision-models': 'Vertex AI (Vision)', | ||
| }; | ||
|
|
||
| export function isVertexAiVariant(provider: string): boolean { |
| return provider.startsWith('vertex_ai-'); | ||
| } | ||
|
|
||
| export function formatProviderName(provider: string): string { |
There was a problem hiding this comment.
Can we have a test for this method?
| return null; | ||
| } | ||
|
|
||
| export function isGroupedProvider(provider: string): boolean { |
There was a problem hiding this comment.
Not anymore :) And it's largely overwritten in favor of the new design in the last PR in the stack as well
741f9b1 to
b261ce4
Compare
b261ce4 to
ef2d5fe
Compare
| } | ||
| }; | ||
|
|
||
| const isFormComplete = Boolean(provider) && Boolean(name); |
There was a problem hiding this comment.
q: do we need Boolean()?
There was a problem hiding this comment.
ohhhhh I guess there's a !! operator that can do the same thing. Interesting! Thanks for the tip :)
| import { getReadableErrorMessage } from '../utils/errorUtils'; | ||
| import GatewayRoutes from '../routes'; | ||
|
|
||
| export { getReadableErrorMessage }; |
There was a problem hiding this comment.
why do we need to re-export from this file?
There was a problem hiding this comment.
I think I was just being lazy to group imports from the hooks within the page that is consuming them. I should just have the page renderer import from utils directly.
TomeHirata
left a comment
There was a problem hiding this comment.
Left some minor comments, otherwise LGTM!
Signed-off-by: Ben Wilson <benjamin.wilson@databricks.com>
ef2d5fe to
f5d0cd1
Compare
🥞 Stacked PR
Use this link to review incremental changes.
Related Issues/PRs
#xxxWhat changes are proposed in this pull request?
Adds in the start of the Endpoint Create page (in this PR, only provider selection is supported to reduce the overall size of this PR).
Addresses feedback regarding coalescing providers by their base configuration and introduces a new sub-selector for the two special case providers (OpenAI / Azure OpenAI and Google Vertex).
How is this PR tested?
Does this PR require documentation update?
Release Notes
Is this a user-facing change?
What component(s), interfaces, languages, and integrations does this PR affect?
Components
area/tracking: Tracking Service, tracking client APIs, autologgingarea/models: MLmodel format, model serialization/deserialization, flavorsarea/model-registry: Model Registry service, APIs, and the fluent client calls for Model Registryarea/scoring: MLflow Model server, model deployment tools, Spark UDFsarea/evaluation: MLflow model evaluation features, evaluation metrics, and evaluation workflowsarea/gateway: MLflow AI Gateway client APIs, server, and third-party integrationsarea/prompts: MLflow prompt engineering features, prompt templates, and prompt managementarea/tracing: MLflow Tracing features, tracing APIs, and LLM tracing functionalityarea/projects: MLproject format, project running backendsarea/uiux: Front-end, user experience, plotting, JavaScript, JavaScript dev serverarea/build: Build and test infrastructure for MLflowarea/docs: MLflow documentation pagesHow should the PR be classified in the release notes? Choose one:
rn/none- No description will be included. The PR will be mentioned only by the PR number in the "Small Bugfixes and Documentation Updates" sectionrn/breaking-change- The PR will be mentioned in the "Breaking Changes" sectionrn/feature- A new user-facing feature worth mentioning in the release notesrn/bug-fix- A user-facing bug fix worth mentioning in the release notesrn/documentation- A user-facing documentation change worth mentioning in the release notesShould this PR be included in the next patch release?
Yesshould be selected for bug fixes, documentation updates, and other small changes.Noshould be selected for new features and larger changes. If you're unsure about the release classification of this PR, leave this unchecked to let the maintainers decide.What is a minor/patch release?
Bug fixes, doc updates and new features usually go into minor releases.
Bug fixes and doc updates usually go into patch releases.