feat: add Azure OpenAI under feature flag - #2209
feat: add Azure OpenAI under feature flag#2209edwinjosechittilappilly wants to merge 16 commits into
Conversation
- Implemented Azure AI Foundry settings form for user configuration. - Integrated Azure AI Foundry model fetching and validation in the ingest settings section. - Added Azure AI Foundry logo and settings dialog to the model providers component. - Enhanced model helpers to support Azure AI Foundry as a model provider. - Created API endpoints for fetching Azure AI Foundry models and validating credentials. - Updated configuration management to include Azure AI Foundry settings. - Implemented health check and completion tests for Azure AI Foundry. - Added support for Azure AI Foundry in Langflow global variable synchronization. - Updated settings models to accommodate Azure AI Foundry API key and endpoint. - Enhanced provider health checks to include Azure AI Foundry.
…d additional parameters
…AI Foundry settings
…nclude model parameter
- Introduced Azure OpenAI provider configuration and models. - Updated frontend components to include Azure OpenAI logo and provider options. - Implemented backend API endpoints for Azure OpenAI model retrieval and validation. - Enhanced settings management to accommodate Azure OpenAI API key, endpoint, and version. - Updated provider health checks and validation functions for Azure OpenAI. - Added support for Azure OpenAI in Langflow synchronization. - Modified models and settings schemas to include Azure OpenAI fields.
…int handling across multiple files
Introduce OPENRAG_AZURE_AI_ENABLED to gate Azure AI Foundry / Azure OpenAI functionality across the stack. Adds is_azure_ai_enabled() accessor and documents the env var in .env.example. ConfigManager now only ingests Azure provider env vars when the flag is enabled (prevents env-only re-enable). API: settings endpoint redacts Azure provider state when disabled, returns show_azure_ai_providers, and update/onboarding endpoints reject attempts to configure or select Azure providers when disabled. Model listing endpoints return 404 when Azure is disabled. Frontend hides Azure provider tiles/dialogs when the flag is off. This prevents the UI from learning about or configuring Azure providers unless explicitly enabled.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds feature-gated Azure AI Foundry and Azure OpenAI providers. The change covers configuration, validation, model retrieval, settings persistence, Langflow synchronization, model routing, and frontend configuration workflows. ChangesAzure provider integration
Estimated code review effort: 5 (Critical) | ~90+ minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
React Doctor found 4 new issues in 2 files · 4 warnings · score 82 / 100 (Needs work) · 0 fixed · vs 4 warnings
Reviewed by React Doctor for commit |
| errors.append(f"Embedding deployment '{embedding_deployment_name}': {str(e)}") | ||
|
|
||
| if errors: | ||
| return JSONResponse({"error": "; ".join(errors)}, status_code=400) |
| ) | ||
| except Exception as e: | ||
| return JSONResponse( | ||
| {"error": f"Could not connect to Azure AI Foundry endpoint: {str(e)}"}, |
| errors.append(f"Embedding deployment '{embedding_deployment_name}': {str(e)}") | ||
|
|
||
| if errors: | ||
| return JSONResponse({"error": "; ".join(errors)}, status_code=400) |
| try: | ||
| await _test_azure_openai_lightweight_health(api_key, endpoint, api_version) | ||
| except Exception as e: | ||
| return JSONResponse({"error": str(e)}, status_code=400) |
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (2)
frontend/app/settings/_components/azure-openai-settings-dialog.tsx (1)
33-348: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftThe two Azure dialogs duplicate one component. Both files repeat the same state, the same validate and test flow, the same pluralization logic, the same health-cache write, the same error animation blocks, and the same footer wiring. Only the provider key, the payload field names, and the extra
apiVersionfield differ. Every future fix must land twice, and thecanRemoveAzuredivergence already shows that drift. React Doctor also flagged the size of both components.Extract a shared
AzureProviderSettingsDialogthat takes the provider key, the form component, the payload builder, and the removal flag as props.
frontend/app/settings/_components/azure-openai-settings-dialog.tsx#L33-L348: reduce to a thin wrapper over the shared dialog.frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx#L33-L336: reduce to a thin wrapper over the shared dialog.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 33 - 348, Extract the duplicated dialog logic from AzureOpenAISettingsDialog in frontend/app/settings/_components/azure-openai-settings-dialog.tsx (lines 33-348) and AzureAIFoundrySettingsDialog in frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx (lines 33-336) into a shared AzureProviderSettingsDialog. Pass the provider key, provider-specific form component, payload builder, and removal flag as props, preserving each provider’s apiVersion handling, validation/test flows, health-cache update, error rendering, footer wiring, and removal behavior; reduce both existing components to thin provider-specific wrappers.src/api/models.py (1)
430-560: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffExtract the shared Azure model-resolution flow.
get_azure_openai_modelsandget_azure_ai_foundry_modelsrepeat the same steps: feature gate, resolve values from body or config, validate required fields, run the optional inference tests, then fall back to stored deployment names. Only the validator functions and the required-field set differ. Extract a helper that takes the provider name, the resolved values, and the test callables. This keeps the two handlers to their provider-specific parts.The unused
models_service=Depends(get_models_service)parameter can be removed from both handlers at the same time, because neither body uses it.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/api/models.py` around lines 430 - 560, Extract the duplicated Azure model-resolution logic from get_azure_openai_models and get_azure_ai_foundry_models into a shared helper accepting the provider name, resolved credentials/deployment values, and provider-specific validation callables; preserve each handler’s feature gate, required-field differences, inference-test behavior, lightweight validation, and stored-deployment fallback. Remove the unused models_service=Depends(get_models_service) parameter from both handlers and clean up any now-unused import.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx`:
- Around line 81-86: Replace the no-argument reset in the Azure AI Foundry
dialog’s useEffect with explicit values from
settings.providers?.azure_ai_foundry for endpoint, llmDeploymentName, and
embeddingDeploymentName, while resetting apiKey to an empty string. Apply the
same change in
frontend/app/settings/_components/azure-openai-settings-dialog.tsx at lines
83-88 using settings.providers?.azure_openai and including apiVersion; retain
clearing testConnectionResult when open.
In `@frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx`:
- Around line 56-59: The API key validation must allow edits to
already-configured Azure providers without requiring the secret again. In
frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx lines
56-59, add an isConfigured prop and make the apiKey required rule conditional on
it; in frontend/app/settings/_components/azure-openai-settings-form.tsx lines
57-60, apply the same rule and pass isConfigured from
azure-openai-settings-dialog.tsx.
In `@src/api/models.py`:
- Around line 366-402: Update the Azure AI Foundry model-list flow around the
credential-check response and the `language_models`/`embedding_models` parsing
block: append `/models` to the resource endpoint for the model-list request, and
reuse the existing first credential-check response rather than issuing a second
identical GET. Preserve the current response parsing and fallback behavior.
In `@src/api/provider_health.py`:
- Around line 110-116: Update the provider-health cache key construction in the
surrounding provider health flow to include both api_version and
embedding_api_version alongside their respective provider settings. Ensure
changes to either Azure OpenAI API version produce a distinct key so
validate_provider_setup runs instead of returning stale cached health data.
In `@src/api/provider_validation.py`:
- Around line 1474-1499: The Azure completion validation payloads in
_test_azure_openai_completion and _test_azure_ai_foundry_completion currently
test only chat responses; add the same minimal tools payload used by supported
completion providers to both request bodies. Preserve the existing messages and
token settings while ensuring both Azure tests exercise the tool-calling
fallback path.
- Around line 1322-1327: Fix the Ruff B904 violations in the six Azure validator
timeout handlers by adding an explicit exception cause when raising the new
Exception inside each except httpx.TimeoutException block. Update the handlers
around the affected health-check validators, using from e when the caught
exception is bound or from None when it is not, while preserving the existing
messages and re-raise behavior.
In `@src/api/settings/endpoints.py`:
- Around line 1167-1181: Update the Azure credential-update handling near the
feature-gate check to persist Azure AI Foundry and Azure OpenAI API keys,
endpoints, and azure_openai_api_version into current_config, mark the
corresponding providers as configured, and include Azure deployment metadata.
Update the validation calls around the existing validation blocks to propagate
api_version, ensuring Azure onboarding validates the newly persisted complete
configuration before proceeding.
- Around line 848-887: Move the Azure-specific configuration workflow currently
implemented in the route handler—including updates in the Azure provider blocks,
endpoint normalization, credential removal, fallback selection, and embedding
dependency checks—into an injected settings service. Keep the route handler
limited to request validation, authorization, invoking the service, and
constructing HTTP responses; preserve the existing behavior and use the
service’s existing provider/configuration symbols.
- Around line 544-549: Update the settings endpoint’s Azure mutation branches,
including the deployment-name logic around effective_llm_provider and the
referenced credential, endpoint, API-version, removal, and fallback handling, to
modify working_config instead of current_config. Ensure every Azure change is
applied to the same working_config instance that the save operation at line 1094
persists, while preserving the existing provider-selection behavior.
In `@src/config/config_manager.py`:
- Around line 469-503: Move the Azure feature-flag parsing and environment reads
from the configuration-loading block into typed accessors in config/settings.py,
then have the Azure setup in config_manager use those accessors instead of
os.getenv. Update the relevant settings model/accessor symbols for
OPENRAG_AZURE_AI_ENABLED, Azure AI Foundry, and Azure OpenAI values while
preserving the existing enabled gating and provider configuration behavior.
In `@src/config/settings.py`:
- Around line 1185-1210: Gate the Azure credential and endpoint exports in the
settings-loading path around is_azure_ai_enabled(), covering both
azure_ai_foundry and azure_openai assignments. When Azure is disabled or the
provider configuration is removed, clear the relevant Azure environment
variables, including API keys, base URLs, and API version, so stale routing
state is not retained.
In `@src/services/models_service.py`:
- Around line 116-138: Update the Azure registration logic in the model registry
flow to register persisted deployment names from the configured provider
objects, rather than only the currently active embedding_model and llm_model
values. For both azure_ai_foundry and azure_openai, add each configured
llm_deployment_name and embedding_deployment_name to new_registry with the
corresponding provider identifier, while preserving configured-provider guards
and avoiding empty names.
---
Nitpick comments:
In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx`:
- Around line 33-348: Extract the duplicated dialog logic from
AzureOpenAISettingsDialog in
frontend/app/settings/_components/azure-openai-settings-dialog.tsx (lines
33-348) and AzureAIFoundrySettingsDialog in
frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx (lines
33-336) into a shared AzureProviderSettingsDialog. Pass the provider key,
provider-specific form component, payload builder, and removal flag as props,
preserving each provider’s apiVersion handling, validation/test flows,
health-cache update, error rendering, footer wiring, and removal behavior;
reduce both existing components to thin provider-specific wrappers.
In `@src/api/models.py`:
- Around line 430-560: Extract the duplicated Azure model-resolution logic from
get_azure_openai_models and get_azure_ai_foundry_models into a shared helper
accepting the provider name, resolved credentials/deployment values, and
provider-specific validation callables; preserve each handler’s feature gate,
required-field differences, inference-test behavior, lightweight validation, and
stored-deployment fallback. Remove the unused
models_service=Depends(get_models_service) parameter from both handlers and
clean up any now-unused import.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0846b1fb-c21a-4a67-8ec5-4661f159e47e
📒 Files selected for processing (27)
.env.examplefrontend/app/api/mutations/useUpdateSettingsMutation.tsfrontend/app/api/queries/useGetModelsQuery.tsfrontend/app/api/queries/useGetSettingsQuery.tsfrontend/app/settings/_components/agent-settings-section.tsxfrontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsxfrontend/app/settings/_components/azure-ai-foundry-settings-form.tsxfrontend/app/settings/_components/azure-openai-settings-dialog.tsxfrontend/app/settings/_components/azure-openai-settings-form.tsxfrontend/app/settings/_components/ingest-settings-section.tsxfrontend/app/settings/_components/model-providers.tsxfrontend/app/settings/_helpers/model-helpers.tsxfrontend/components/icons/azure-ai-foundry-logo.tsxfrontend/components/icons/azure-openai-logo.tsxfrontend/components/provider-health-banner.tsxsrc/api/models.pysrc/api/provider_health.pysrc/api/provider_validation.pysrc/api/settings/endpoints.pysrc/api/settings/helpers.pysrc/api/settings/langflow_sync.pysrc/api/settings/models.pysrc/app/routes/internal.pysrc/config/config_manager.pysrc/config/settings.pysrc/services/models_service.pysrc/utils/container_utils.py
| useEffect(() => { | ||
| if (open) { | ||
| methods.reset(); | ||
| setTestConnectionResult(null); | ||
| } | ||
| }, [open]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
methods.reset() restores stale empty defaults in both Azure dialogs. useForm captures defaultValues on the first render, and useGetSettingsQuery resolves after that render. The captured defaults are therefore the "" fallbacks. When the dialog opens later, reset() with no argument restores those empty values, so a configured provider shows blank fields and the user must retype the endpoint and deployment names. The shared root cause is that the reset call does not receive the settings-derived values.
frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx#L81-L86: pass an explicit object toresetwithendpoint,llmDeploymentName, andembeddingDeploymentNameread fromsettings.providers?.azure_ai_foundry, andapiKey: "".frontend/app/settings/_components/azure-openai-settings-dialog.tsx#L83-L88: pass the same explicit object fromsettings.providers?.azure_openai, includingapiVersion.
🐛 Proposed fix for the Azure AI Foundry dialog
useEffect(() => {
if (open) {
- methods.reset();
+ methods.reset({
+ endpoint: settings.providers?.azure_ai_foundry?.endpoint ?? "",
+ apiKey: "",
+ llmDeploymentName:
+ settings.providers?.azure_ai_foundry?.llm_deployment_name ?? "",
+ embeddingDeploymentName:
+ settings.providers?.azure_ai_foundry?.embedding_deployment_name ?? "",
+ });
setTestConnectionResult(null);
}
- }, [open]);
+ }, [open, methods, settings.providers?.azure_ai_foundry]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| if (open) { | |
| methods.reset(); | |
| setTestConnectionResult(null); | |
| } | |
| }, [open]); | |
| useEffect(() => { | |
| if (open) { | |
| methods.reset({ | |
| endpoint: settings.providers?.azure_ai_foundry?.endpoint ?? "", | |
| apiKey: "", | |
| llmDeploymentName: | |
| settings.providers?.azure_ai_foundry?.llm_deployment_name ?? "", | |
| embeddingDeploymentName: | |
| settings.providers?.azure_ai_foundry?.embedding_deployment_name ?? "", | |
| }); | |
| setTestConnectionResult(null); | |
| } | |
| }, [open, methods, settings.providers?.azure_ai_foundry]); |
📍 Affects 2 files
frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx#L81-L86(this comment)frontend/app/settings/_components/azure-openai-settings-dialog.tsx#L83-L88
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx`
around lines 81 - 86, Replace the no-argument reset in the Azure AI Foundry
dialog’s useEffect with explicit values from
settings.providers?.azure_ai_foundry for endpoint, llmDeploymentName, and
embeddingDeploymentName, while resetting apiKey to an empty string. Apply the
same change in
frontend/app/settings/_components/azure-openai-settings-dialog.tsx at lines
83-88 using settings.providers?.azure_openai and including apiVersion; retain
clearing testConnectionResult when open.
| <Input | ||
| {...register("apiKey", { | ||
| required: "API key is required", | ||
| })} |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
The API key rule blocks edits to an already-configured Azure provider. Both dialogs omit the API key from the settings payload when the field is empty, which supports keeping the stored key. Both forms mark the field required unconditionally, so that path is unreachable. A configured user who edits only the deployment names cannot submit without retyping the secret. The shared root cause is that the validation rule ignores the provider's configured state.
frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx#L56-L59: accept anisConfiguredprop and setrequiredtoisConfigured ? false : "API key is required".frontend/app/settings/_components/azure-openai-settings-form.tsx#L57-L60: apply the same conditional rule and passisConfiguredfromazure-openai-settings-dialog.tsx.
📍 Affects 2 files
frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx#L56-L59(this comment)frontend/app/settings/_components/azure-openai-settings-form.tsx#L57-L60
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx` around
lines 56 - 59, The API key validation must allow edits to already-configured
Azure providers without requiring the secret again. In
frontend/app/settings/_components/azure-ai-foundry-settings-form.tsx lines
56-59, add an isConfigured prop and make the apiKey required rule conditional on
it; in frontend/app/settings/_components/azure-openai-settings-form.tsx lines
57-60, apply the same rule and pass isConfigured from
azure-openai-settings-dialog.tsx.
| # Try to fetch the deployed model list from the resource endpoint. | ||
| # Azure AI Foundry resource-level endpoints return an OpenAI-compatible | ||
| # GET /models response: {"data": [{"id": "<deployment>", ...}, ...]} | ||
| language_models = [] | ||
| embedding_models = [] | ||
|
|
||
| try: | ||
| async with httpx.AsyncClient() as client: | ||
| list_response = await client.get( | ||
| endpoint.rstrip("/"), | ||
| headers={ | ||
| "Authorization": f"Bearer {api_key}", | ||
| "Content-Type": "application/json", | ||
| }, | ||
| timeout=10.0, | ||
| ) | ||
| logger.info(f"Azure AI Foundry GET /models status: {list_response.status_code}") | ||
| logger.debug(f"Azure AI Foundry GET /models body: {list_response.text[:500]}") | ||
| if list_response.status_code == 200: | ||
| data = list_response.json() | ||
| entries = data.get("data", []) | ||
| for entry in entries: | ||
| model_id = entry.get("id", "") | ||
| if not model_id: | ||
| continue | ||
| item = {"value": model_id, "label": model_id} | ||
| # Heuristic: names containing "embed" go to embedding; rest to language. | ||
| if "embed" in model_id.lower(): | ||
| embedding_models.append(item) | ||
| else: | ||
| language_models.append(item) | ||
| logger.info( | ||
| f"Azure AI Foundry models parsed: {len(language_models)} LLM, {len(embedding_models)} embedding" | ||
| ) | ||
| except Exception as e: | ||
| logger.warning(f"Azure AI Foundry GET /models failed: {e}") | ||
| pass # Fall through to config-based fallback below |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
The model-list call repeats the credential check and never requests /models.
The block at Lines 372-381 issues the same GET to endpoint.rstrip("/") with the same headers and timeout as the credential check at Lines 333-341. Two effects follow. First, every request performs two identical round-trips. Second, the comment at Lines 366-368 states that an OpenAI-compatible GET /models payload is parsed, but no /models path is appended, so data["data"] is normally absent and the dynamic listing always falls through to the stored deployment names.
Append the /models path and reuse the first response instead of repeating the request.
🐛 Proposed fix
try:
async with httpx.AsyncClient() as client:
list_response = await client.get(
- endpoint.rstrip("/"),
+ f"{endpoint.rstrip('/')}/models",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
timeout=10.0,
)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/api/models.py` around lines 366 - 402, Update the Azure AI Foundry
model-list flow around the credential-check response and the
`language_models`/`embedding_models` parsing block: append `/models` to the
resource endpoint for the model-list request, and reuse the existing first
credential-check response rather than issuing a second identical GET. Preserve
the current response parsing and fallback behavior.
| api_version = getattr(llm_provider_config, "api_version", None) | ||
| llm_model = current_config.agent.llm_model | ||
|
|
||
| embedding_api_key = getattr(embedding_provider_config, "api_key", None) | ||
| embedding_endpoint = getattr(embedding_provider_config, "endpoint", None) | ||
| embedding_project_id = getattr(embedding_provider_config, "project_id", None) | ||
| embedding_api_version = getattr(embedding_provider_config, "api_version", None) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Add the API versions to the provider-health cache key.
api_version and embedding_api_version now change the validation outcome, because validate_provider_setup builds the Azure OpenAI request URL from them at Lines 204 and 239. The cache key at Lines 123-135 omits both. If a user corrects only the Azure OpenAI API version, every key component stays the same, so the cached healthy payload is returned and the new version is never validated. The banner then reports a stale status until the entry expires.
Include both values in the key.
🐛 Proposed fix
health_cache_key = provider_health_cache.cache_key(
provider=provider,
embedding_provider=embedding_provider,
test_completion=test_completion,
llm_model=llm_model,
embedding_model=embedding_model,
endpoint=endpoint,
project_id=project_id,
api_key=api_key,
+ api_version=api_version,
embedding_api_key=embedding_api_key,
embedding_endpoint=embedding_endpoint,
embedding_project_id=embedding_project_id,
+ embedding_api_version=embedding_api_version,
)Also applies to: 123-135
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/api/provider_health.py` around lines 110 - 116, Update the
provider-health cache key construction in the surrounding provider health flow
to include both api_version and embedding_api_version alongside their respective
provider settings. Ensure changes to either Azure OpenAI API version produce a
distinct key so validate_provider_setup runs instead of returning stale cached
health data.
| if body.azure_ai_foundry_api_key is not None and body.azure_ai_foundry_api_key.strip(): | ||
| current_config.providers.azure_ai_foundry.api_key = ( | ||
| body.azure_ai_foundry_api_key.strip() | ||
| ) | ||
| current_config.providers.azure_ai_foundry.configured = True | ||
| config_updated = True | ||
| provider_updated = True | ||
|
|
||
| if body.azure_ai_foundry_endpoint is not None: | ||
| current_config.providers.azure_ai_foundry.endpoint = ( | ||
| body.azure_ai_foundry_endpoint.strip() | ||
| ) | ||
| current_config.providers.azure_ai_foundry.configured = True | ||
| config_updated = True | ||
| provider_updated = True | ||
|
|
||
| if body.azure_openai_api_key is not None and body.azure_openai_api_key.strip(): | ||
| current_config.providers.azure_openai.api_key = body.azure_openai_api_key.strip() | ||
| current_config.providers.azure_openai.configured = True | ||
| config_updated = True | ||
| provider_updated = True | ||
|
|
||
| if body.azure_openai_endpoint is not None: | ||
| from utils.container_utils import normalize_azure_openai_base | ||
|
|
||
| current_config.providers.azure_openai.endpoint = normalize_azure_openai_base( | ||
| body.azure_openai_endpoint.strip() | ||
| ) | ||
| current_config.providers.azure_openai.configured = True | ||
| config_updated = True | ||
| provider_updated = True | ||
|
|
||
| if body.azure_openai_api_version is not None: | ||
| current_config.providers.azure_openai.api_version = ( | ||
| body.azure_openai_api_version.strip() | ||
| ) | ||
| current_config.providers.azure_openai.configured = True | ||
| config_updated = True | ||
| provider_updated = True | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
Move Azure provider orchestration out of the route handler.
This route directly updates provider state, normalizes endpoints, removes credentials, selects fallbacks, and checks embedding dependencies. Move this Azure-specific workflow into an injected settings service. Keep the route responsible for request validation, authorization, and HTTP responses.
As per path instructions, src/api/**/*.py requires: “No business logic in route handlers.”
Also applies to: 1009-1084
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/api/settings/endpoints.py` around lines 848 - 887, Move the
Azure-specific configuration workflow currently implemented in the route
handler—including updates in the Azure provider blocks, endpoint normalization,
credential removal, fallback selection, and embedding dependency checks—into an
injected settings service. Keep the route handler limited to request validation,
authorization, invoking the service, and constructing HTTP responses; preserve
the existing behavior and use the service’s existing provider/configuration
symbols.
Source: Path instructions
| azure_touched = ( | ||
| body.llm_provider in ("azure_ai_foundry", "azure_openai") | ||
| or body.embedding_provider in ("azure_ai_foundry", "azure_openai") | ||
| or body.azure_ai_foundry_api_key is not None | ||
| or body.azure_ai_foundry_endpoint is not None | ||
| or body.azure_openai_api_key is not None | ||
| or body.azure_openai_endpoint is not None | ||
| or body.azure_openai_api_version is not None | ||
| ) | ||
| if azure_touched and not is_azure_ai_enabled(): | ||
| return JSONResponse( | ||
| {"error": "Azure AI providers are not enabled on this deployment."}, | ||
| status_code=403, | ||
| ) | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Persist and validate Azure onboarding fields.
The feature gate accepts Azure onboarding requests, but the following credential-update blocks only handle the existing providers. Azure API keys, endpoints, and azure_openai_api_version never reach current_config. The validation calls at Lines 1338 and 1358 also omit api_version. An Azure onboarding request therefore validates an empty or incomplete provider configuration and fails. Add Azure field persistence, configured-state handling, deployment metadata, and API-version propagation before validation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/api/settings/endpoints.py` around lines 1167 - 1181, Update the Azure
credential-update handling near the feature-gate check to persist Azure AI
Foundry and Azure OpenAI API keys, endpoints, and azure_openai_api_version into
current_config, mark the corresponding providers as configured, and include
Azure deployment metadata. Update the validation calls around the existing
validation blocks to propagate api_version, ensuring Azure onboarding validates
the newly persisted complete configuration before proceeding.
| # Azure AI Foundry / Azure OpenAI provider settings — gated behind the | ||
| # feature flag (default off) so setting these env vars alone can't | ||
| # silently re-enable the feature. Read the raw env var here (not | ||
| # config.settings.is_azure_ai_enabled) to avoid a circular import. | ||
| azure_ai_enabled = os.getenv("OPENRAG_AZURE_AI_ENABLED", "false").strip().lower() in ( | ||
| "true", | ||
| "1", | ||
| "yes", | ||
| "on", | ||
| ) | ||
| if azure_ai_enabled: | ||
| if os.getenv("AZURE_AI_API_KEY"): | ||
| config_data["providers"]["azure_ai_foundry"]["api_key"] = os.getenv( | ||
| "AZURE_AI_API_KEY" | ||
| ) | ||
| config_data["providers"]["azure_ai_foundry"]["configured"] = True | ||
| if os.getenv("AZURE_AI_API_BASE"): | ||
| config_data["providers"]["azure_ai_foundry"]["endpoint"] = os.getenv( | ||
| "AZURE_AI_API_BASE" | ||
| ) | ||
|
|
||
| if os.getenv("AZURE_OPENAI_API_KEY"): | ||
| config_data["providers"]["azure_openai"]["api_key"] = os.getenv( | ||
| "AZURE_OPENAI_API_KEY" | ||
| ) | ||
| config_data["providers"]["azure_openai"]["configured"] = True | ||
| if os.getenv("AZURE_OPENAI_ENDPOINT"): | ||
| config_data["providers"]["azure_openai"]["endpoint"] = os.getenv( | ||
| "AZURE_OPENAI_ENDPOINT" | ||
| ) | ||
| if os.getenv("AZURE_OPENAI_API_VERSION"): | ||
| config_data["providers"]["azure_openai"]["api_version"] = os.getenv( | ||
| "AZURE_OPENAI_API_VERSION" | ||
| ) | ||
|
|
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Route Azure environment access through config/settings.py.
Lines 473-502 read Azure configuration with os.getenv in src/config/config_manager.py. This creates a second configuration source. Move feature-flag parsing and Azure environment access into typed accessors in config/settings.py.
As per path instructions, src/**/*.py requires: “Config values must come from config/settings.py (the only place os.environ is read); never access os.environ elsewhere in the codebase.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/config/config_manager.py` around lines 469 - 503, Move the Azure
feature-flag parsing and environment reads from the configuration-loading block
into typed accessors in config/settings.py, then have the Azure setup in
config_manager use those accessors instead of os.getenv. Update the relevant
settings model/accessor symbols for OPENRAG_AZURE_AI_ENABLED, Azure AI Foundry,
and Azure OpenAI values while preserving the existing enabled gating and
provider configuration behavior.
Source: Path instructions
| # Set Azure AI Foundry credentials | ||
| if config.providers.azure_ai_foundry.api_key: | ||
| os.environ["AZURE_AI_API_KEY"] = config.providers.azure_ai_foundry.api_key | ||
| logger.debug("Loaded Azure AI Foundry API key from config") | ||
| if config.providers.azure_ai_foundry.endpoint: | ||
| os.environ["AZURE_AI_API_BASE"] = config.providers.azure_ai_foundry.endpoint | ||
| logger.debug("Loaded Azure AI Foundry endpoint from config") | ||
|
|
||
| # Set Azure OpenAI Service credentials (LiteLLM azure/ prefix). | ||
| # AZURE_API_BASE must be the bare resource root — LiteLLM appends | ||
| # /openai/deployments/<name>/... itself, so a pasted /openai/v1 | ||
| # suffix would otherwise produce a doubled path (404 at inference). | ||
| if config.providers.azure_openai.api_key: | ||
| os.environ["AZURE_API_KEY"] = config.providers.azure_openai.api_key | ||
| logger.debug("Loaded Azure OpenAI API key from config") | ||
| if config.providers.azure_openai.endpoint: | ||
| from utils.container_utils import normalize_azure_openai_base | ||
|
|
||
| os.environ["AZURE_API_BASE"] = normalize_azure_openai_base( | ||
| config.providers.azure_openai.endpoint | ||
| ) | ||
| logger.debug("Loaded Azure OpenAI endpoint from config") | ||
| if config.providers.azure_openai.api_version: | ||
| os.environ["AZURE_API_VERSION"] = config.providers.azure_openai.api_version | ||
| logger.debug("Loaded Azure OpenAI API version from config") | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Honor the Azure feature flag before exporting credentials.
When Azure was configured before the flag is disabled, this path still exports its credentials and endpoints to LiteLLM-visible environment variables. The disabled feature can therefore retain Azure routing state in the running process. Gate these assignments with is_azure_ai_enabled() and clear the Azure variables when the feature is disabled or the provider is removed. This is required by the PR objective that disabled Azure environment values are not ingested.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/config/settings.py` around lines 1185 - 1210, Gate the Azure credential
and endpoint exports in the settings-loading path around is_azure_ai_enabled(),
covering both azure_ai_foundry and azure_openai assignments. When Azure is
disabled or the provider configuration is removed, clear the relevant Azure
environment variables, including API keys, base URLs, and API version, so stale
routing state is not retained.
| # Azure AI Foundry — register configured deployment names statically; | ||
| # the user provides deployment names manually (no remote model fetch). | ||
| if config.providers.azure_ai_foundry.configured: | ||
| embedding_model = config.knowledge.embedding_model | ||
| llm_model = config.agent.llm_model | ||
| if ( | ||
| embedding_model | ||
| and config.knowledge.embedding_provider == "azure_ai_foundry" | ||
| ): | ||
| new_registry[embedding_model] = "azure_ai_foundry" | ||
| if llm_model and config.agent.llm_provider == "azure_ai_foundry": | ||
| new_registry[llm_model] = "azure_ai_foundry" | ||
|
|
||
| # Azure OpenAI Service — register configured deployment names statically; | ||
| # the user provides deployment names manually (no remote model fetch). | ||
| if config.providers.azure_openai.configured: | ||
| embedding_model = config.knowledge.embedding_model | ||
| llm_model = config.agent.llm_model | ||
| if embedding_model and config.knowledge.embedding_provider == "azure_openai": | ||
| new_registry[embedding_model] = "azure_openai" | ||
| if llm_model and config.agent.llm_provider == "azure_openai": | ||
| new_registry[llm_model] = "azure_openai" | ||
|
|
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm the persisted deployment-name fields exist on the Azure provider configs.
set -euo pipefail
rg -n --type=py -C6 'class Azure.*Config|llm_deployment_name|embedding_deployment_name' src/config | head -100Repository: langflow-ai/openrag
Length of output: 2385
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
git ls-files | rg '(^src/.*models.py|src/config|src/services/models_service.py)$'
echo "== config manager relevant section =="
sed -n '120,210p' src/config/config_manager.py
echo "== src/services/models_service.py outline =="
ast-grep outline src/services/models_service.py --view expanded
echo "== src/services/models_service.py lines 100-205 =="
sed -n '100,205p' src/services/models_service.py
echo "== api models azure deployment usage =="
rg -n --type=py -C4 'get_azure_ai_foundry_models|azure_ai_foundry|azure_openai|llm_deployment_name|embedding_deployment_name|model_registry' src/api/models.py src/services src/dependencies.py src/main.pyRepository: langflow-ai/openrag
Length of output: 27497
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== all references to model persistence/deployment model fields =="
rg -n --type=py -C4 'embedding_model|llm_model|embedding_provider|llm_provider|embedding_deployment_name|llm_deployment_name|azure_ai_foundry|azure_openai|agent|knowledge' src | head -300
echo "== provider validation azure deployment names =="
rg -n --type=py -C4 'llm_deployment_name|embedding_deployment_name|_test_azure|azure_ai_foundry|azure_openai' src | rg -n --type=py -C4 'validator|provider_validation|models.py'
echo "== behavioral probe for registry behavior =="
python3 - <<'PY'
from pathlib import Path
src = Path("src/services/models_service.py").read_text()
checks = {
"azure_foundry_active_embedding": 'config.knowledge.embedding_provider == "azure_ai_foundry"' in src,
"azure_foundry_stored_llm": 'config.providers.azure_ai_foundry.llm_deployment_name' in src,
"azure_foundry_stored_embed": 'config.providers.azure_ai_foundry.embedding_deployment_name' in src,
"azure_aoai_active_embedding": 'config.knowledge.embedding_provider == "azure_openai"' in src,
"azure_aoai_stored_llm": 'config.providers.azure_openai.llm_deployment_name' in src,
"azure_aoai_stored_embed": 'config.providers.azure_openai.embedding_deployment_name' in src,
"registry_get_returns_raw_in_nonstrict": 'return model_name # OpenAI-compatible models work without a prefix',
"regressed_by_switch_simulation",
}
# Simulate the registry condition: if active provider is OTHER, Azure configured blocks do not add Azure stored deployment names.
provider = "azure_ai_foundry"
configured = True
embedding_model = "azure-embed-deployment"
embedding_provider_active = "other_active_provider"
llm_model = "azure-llm-deployment"
llm_provider_active = "other_active_provider"
new_registry = {}
if configured:
if embedding_model and embedding_provider_active == "azure_ai_foundry":
new_registry[embedding_model] = "azure_ai_foundry"
if llm_model and llm_provider_active == "azure_ai_foundry":
new_registry[llm_model] = "azure_ai_foundry"
checks["switch_drops_stored_embeddings"] = embedding_model not in new_registry and llm_model not in new_registry
print("\n".join(f"{k}: {v}" for k, v in checks.items()))
PYRepository: langflow-ai/openrag
Length of output: 50375
Register the persisted Azure deployment names, not only the active ones.
Azure registry entries are added only when that Azure provider is the active embedding_provider or llm_provider. A corpus embedded with a persisted Azure deployment name stops resolving after an active-provider switch: strict=True raises UnknownEmbeddingProvider, and non-strict lookup returns the bare name so LiteLLM cannot route the request. Register config.providers.azure_ai_foundry and config.providers.azure_openai persisted llm_deployment_name/embedding_deployment_name values instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/services/models_service.py` around lines 116 - 138, Update the Azure
registration logic in the model registry flow to register persisted deployment
names from the configured provider objects, rather than only the currently
active embedding_model and llm_model values. For both azure_ai_foundry and
azure_openai, add each configured llm_deployment_name and
embedding_deployment_name to new_registry with the corresponding provider
identifier, while preserving configured-provider guards and avoiding empty
names.
Introduce LANGFLOW_MODEL_VALUE_PROVIDERS and include azure_ai_foundry, so Langflow flow-sync only runs for providers that are routable through Langflow's unified components. Rename Langflow global variables for Azure Foundry to AZURE_AI_FOUNDRY_API_KEY / AZURE_AI_FOUNDRY_ENDPOINT to match Langflow metadata. Add provider display mapping and API-key mapping for Azure AI Foundry, update validation/error text, and log skipped providers when appropriate. Files changed: src/api/settings/langflow_sync.py, src/services/flows_service.py, src/utils/langflow_headers.py
…/openrag into azure-ai-rebase-main
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/services/flows_service.py`:
- Around line 26-32: Move the component-selection logic in
_update_provider_components_locked so it executes before the early return inside
wrap_node_update, ensuring node_tasks is populated. Preserve the existing
compatibility filtering and enable azure_ai_foundry to route through
change_langflow_model_value, so Azure AI Foundry model changes update the
selected flow components instead of returning “No compatible components found.”
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9a3740c0-c226-41cf-99fe-68528b3a3408
📒 Files selected for processing (3)
src/api/settings/langflow_sync.pysrc/services/flows_service.pysrc/utils/langflow_headers.py
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
src/services/flows_service.py (1)
1417-1417: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winMap Azure AI Foundry endpoint fields on Langflow templates.
_required_generic_global_valuesreturns the api-key-only mapping, while_update_langflow_global_variablespublishesAZURE_AES_AI_FOUNDRY_ENDPOINTthrough provider metadata. Add the corresponding template endpoint field mapping for Azure AI Foundry if component templates expose one under a Langflow-specific field name.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/services/flows_service.py` at line 1417, Update the Azure AI Foundry entry in _required_generic_global_values to include the Langflow template field for its endpoint, using the existing provider metadata key AZURE_AES_AI_FOUNDRY_ENDPOINT and the template’s Langflow-specific field name when available. Keep the existing API-key mapping intact and align the new endpoint mapping with the other provider template mappings.frontend/app/settings/_components/azure-openai-settings-dialog.tsx (5)
165-171: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winRefresh provider health after removal.
The save path writes a healthy
["provider", "health"]entry. The removal path does not clear or invalidate that entry.useUpdateSettingsMutationonly invalidates settings and refetches current-provider models.A provider health banner can therefore continue to show Azure OpenAI as healthy after removal. Invalidate the health query or write the unconfigured state in
removeMutation.onSuccess.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 165 - 171, Update removeMutation.onSuccess in the Azure OpenAI settings dialog to invalidate the ["provider", "health"] query or write its unconfigured state after removal. Preserve the existing toast, confirmation reset, affected-model cleanup, and dialog close behavior.
115-137: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDiscard stale connection-test results.
The form watcher clears
testConnectionResulton any field change. Capture the tested values/request ID at the timerunConnectionTest()starts, and only write the result back if those values still match the current form.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 115 - 137, Update handleTestConnection to snapshot the deployment values or request identity when runConnectionTest starts, then only call setTestConnectionResult if that snapshot still matches the current form values. Discard both success and error results from stale tests while preserving the existing loading-state behavior.
206-213: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winDo not omit
llm_model/embedding_modelwhen clearing Azure deployment names.
SettingsUpdateBodyallowsnull, andupdate_settingsapplies a model only when the field is notnull. Sending a cleared value also clearsazure_openai.llm_deployment_name/embedding_deployment_name; omitting the field preserves those stored values.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 206 - 213, Update the payload construction around the Azure deployment fields so llm_model and embedding_model are sent as null when their corresponding llmDeploymentName or embeddingDeploymentName is cleared, rather than omitting them. Preserve the azure_openai provider fields and existing non-empty deployment values.
70-81: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReset the form from saved Azure settings on each dialog open.
defaultValuesare read only duringuseForminitialization, so an existing Azure configuration can reopen with empty endpoint, API version, and deployment fields aftermethods.reset(). Reset the form with the current settings, keepapiKey**API Version** and deployment fields aftermethods.reset(). Reset each reset the form with the current settings, keepapiKeyempty, and clearvalidationError`.Clear the completed mutation errors from the previous session as well; otherwise
settingsMutation.errororremoveMutation.errorcan show stale text after reopening the dialog.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 70 - 81, Update the Azure settings dialog open/reset flow around useForm and methods.reset so each open repopulates endpoint, apiVersion, llmDeploymentName, and embeddingDeploymentName from current saved Azure settings while keeping apiKey empty. Clear validationError and reset settingsMutation.error and removeMutation.error when reopening, preventing stale state from the previous session.
98-113: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winPrevent Azure credentials from entering React Query state.
useGetAzureOpenAIModelsQuerystores credential-injected request params in itsqueryKey, and the save path passesazure_openai_api_keythroughuseUpdateSettingsMutation. Use non-cached credential validation and mutate without raw keys, or use React Query credentials-protection/persistence settings to prevent raw credentials from remaining in client state.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx` around lines 98 - 113, Update the Azure settings validation and save flow around validateCredentials, runConnectionTest, and useUpdateSettingsMutation so raw endpoint credentials are not stored in React Query query keys, cached state, or mutation variables. Use a non-cached credential-validation mechanism and submit the update through the established protected credentials path, preserving validation and connection-test behavior without retaining azure_openai_api_key in client state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/services/flows_service.py`:
- Line 1143: Validate the boolean result from _enable_model_in_langflow before
reporting activation success: update src/services/flows_service.py lines
1143-1143 to append the embedding-model message only on success, and lines
1245-1245 to apply the same guard to the LLM activation message; preserve the
existing failure handling and avoid reporting success when either request fails.
---
Outside diff comments:
In `@frontend/app/settings/_components/azure-openai-settings-dialog.tsx`:
- Around line 165-171: Update removeMutation.onSuccess in the Azure OpenAI
settings dialog to invalidate the ["provider", "health"] query or write its
unconfigured state after removal. Preserve the existing toast, confirmation
reset, affected-model cleanup, and dialog close behavior.
- Around line 115-137: Update handleTestConnection to snapshot the deployment
values or request identity when runConnectionTest starts, then only call
setTestConnectionResult if that snapshot still matches the current form values.
Discard both success and error results from stale tests while preserving the
existing loading-state behavior.
- Around line 206-213: Update the payload construction around the Azure
deployment fields so llm_model and embedding_model are sent as null when their
corresponding llmDeploymentName or embeddingDeploymentName is cleared, rather
than omitting them. Preserve the azure_openai provider fields and existing
non-empty deployment values.
- Around line 70-81: Update the Azure settings dialog open/reset flow around
useForm and methods.reset so each open repopulates endpoint, apiVersion,
llmDeploymentName, and embeddingDeploymentName from current saved Azure settings
while keeping apiKey empty. Clear validationError and reset
settingsMutation.error and removeMutation.error when reopening, preventing stale
state from the previous session.
- Around line 98-113: Update the Azure settings validation and save flow around
validateCredentials, runConnectionTest, and useUpdateSettingsMutation so raw
endpoint credentials are not stored in React Query query keys, cached state, or
mutation variables. Use a non-cached credential-validation mechanism and submit
the update through the established protected credentials path, preserving
validation and connection-test behavior without retaining azure_openai_api_key
in client state.
In `@src/services/flows_service.py`:
- Line 1417: Update the Azure AI Foundry entry in
_required_generic_global_values to include the Langflow template field for its
endpoint, using the existing provider metadata key AZURE_AES_AI_FOUNDRY_ENDPOINT
and the template’s Langflow-specific field name when available. Keep the
existing API-key mapping intact and align the new endpoint mapping with the
other provider template mappings.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 8a01ef35-a006-4507-8965-86864766c8e9
📒 Files selected for processing (3)
frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsxfrontend/app/settings/_components/azure-openai-settings-dialog.tsxsrc/services/flows_service.py
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/app/settings/_components/azure-ai-foundry-settings-dialog.tsx
|
|
||
| import { useQueryClient } from "@tanstack/react-query"; | ||
| import { CheckCircle2, Loader2, XCircle } from "lucide-react"; | ||
| import { AnimatePresence, motion } from "motion/react"; |
There was a problem hiding this comment.
React Doctor · react-doctor/use-lazy-motion (warning)
Importing "motion" ships about 30 kb of extra code and slows page load. Use "m" with LazyMotion instead.
Fix → Use import { LazyMotion, m } from "framer-motion" with domAnimation features. Saves about 30kb.
| } from "./azure-ai-foundry-settings-form"; | ||
| import ModelProviderDialogFooter from "./model-provider-dialog-footer"; | ||
|
|
||
| const AzureAIFoundrySettingsDialog = ({ |
There was a problem hiding this comment.
React Doctor · react-doctor/no-giant-component (warning)
Component "AzureAIFoundrySettingsDialog" is 304 lines long, which is hard to read & change. Split it into a few smaller components.
Fix → Pull each section into its own component so the parent is easier to read, test, and change.
|
|
||
| import { useQueryClient } from "@tanstack/react-query"; | ||
| import { CheckCircle2, Loader2, XCircle } from "lucide-react"; | ||
| import { AnimatePresence, motion } from "motion/react"; |
There was a problem hiding this comment.
React Doctor · react-doctor/use-lazy-motion (warning)
Importing "motion" ships about 30 kb of extra code and slows page load. Use "m" with LazyMotion instead.
Fix → Use import { LazyMotion, m } from "framer-motion" with domAnimation features. Saves about 30kb.
| } from "./azure-openai-settings-form"; | ||
| import ModelProviderDialogFooter from "./model-provider-dialog-footer"; | ||
|
|
||
| const AzureOpenAISettingsDialog = ({ |
There was a problem hiding this comment.
React Doctor · react-doctor/no-giant-component (warning)
Component "AzureOpenAISettingsDialog" is 310 lines long, which is hard to read & change. Split it into a few smaller components.
Fix → Pull each section into its own component so the parent is easier to read, test, and change.
lucaseduoli
left a comment
There was a problem hiding this comment.
Looks good! But it's missing the providers in the onboarding
This pull request introduces comprehensive support for Azure AI Foundry and Azure OpenAI as new model providers in the frontend application. It includes changes to the environment configuration, settings management, API queries, and the user interface, allowing users to configure, validate, and manage these Azure providers alongside existing model providers.
Azure Provider Integration
OPENRAG_AZURE_AI_ENABLEDto.env.exampleto control the visibility and availability of Azure AI Foundry and Azure OpenAI providers in the application.ProviderSettingsandSettingsinterfaces to include configuration options and state forazure_ai_foundryandazure_openaiproviders, including deployment names and API versions. [1] [2]API and Query Enhancements
useGetAzureAIFoundryModelsQueryanduseGetAzureOpenAIModelsQuery, including parameter interfaces, for fetching and validating model lists from Azure AI Foundry and Azure OpenAI endpoints. [1] [2]useGetCurrentProviderModelsQueryto support Azure AI Foundry and Azure OpenAI, ensuring the correct models are fetched based on the active provider. [1] [2]Settings and Mutation Support
UpdateSettingsRequestinterface to support setting and removing Azure AI Foundry and Azure OpenAI credentials and endpoints, enabling full lifecycle management of these providers.User Interface Updates
AzureAIFoundrySettingsDialogcomponent, providing a dedicated UI for configuring, validating, testing, and removing Azure AI Foundry provider settings, with user feedback and error handling.These changes collectively enable seamless integration and management of Azure-based model providers within the application's frontend.
Summary by CodeRabbit