FIX: GUI target config shows wrong model name due to env var override#1590
FIX: GUI target config shows wrong model name due to env var override#1590romanlutz wants to merge 1 commit intomicrosoft:mainfrom
Conversation
The target configuration view in the GUI displayed incorrect model names because the underlying_model environment variable (e.g., OPENAI_CHAT_UNDERLYING_MODEL) silently overrode user-provided model names. This affected both GUI-created targets and initializer-registered targets (deepseek, mistral, gemini, llama, etc.). Root cause: OpenAITarget.__init__ unconditionally fell back to the underlying_model env var even when a model_name was explicitly passed, causing the identifier to store the wrong value. The frontend then displayed this incorrect identifier value. ## Backend fixes - **openai_target.py**: Only fall back to underlying_model env var when model_name was also resolved from env vars. When model_name is explicitly passed (by the GUI or initializer) but underlying_model is not, the env var no longer overrides it. - **prompt_target.py**: Store deployment_name (the user's model_name input) as a separate identifier param alongside model_name (underlying model), so both are always available. - **target_mappers.py**: Extract deployment_name from identifier params for the API. - **targets.py model**: Add deployment_name field to TargetInstance DTO. ## Frontend fixes - **CreateTargetDialog**: Add toggle for specifying a different underlying model (hidden by default, with explanation about Azure deployment names). - **TargetTable**: Redesigned with collapsible sections grouped alphabetically by target type, Expand All / Collapse All, model tooltip when underlying model differs, line-wrapped parameters, and wider endpoint column. - **ChatWindow**: Show deployment_name (user's input) in the target badge. - **types**: Add deployment_name to TargetInstance interface. ## Tests - Backend: test that explicit model_name is not overridden by env var (service, chat target, response target), test deployment_name preserved in identifier. - Frontend: 18 TargetTable tests covering alphabetical ordering, expand/collapse, active target auto-expand, expand/collapse all, tooltip, and params rendering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes incorrect model name display in the GUI when an OpenAI underlying-model environment variable was unintentionally overriding explicitly provided model/deployment names. This aligns target identifiers and API responses with what users actually configured, while still preserving the underlying model when it’s intentionally provided.
Changes:
- Update OpenAI target initialization to only use the underlying-model env var when the deployment/model name is also coming from env vars.
- Add
deployment_nameto target identifiers and surface it through backend DTOs/API and frontend types/UI. - Redesign the TargetTable UI (grouped/collapsible sections, expand/collapse controls, tooltip when underlying model differs) and adjust related tests/e2e.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/target/test_openai_response_target.py | Adds unit test coverage for env var override behavior (response target). |
| tests/unit/target/test_openai_chat_target.py | Refines env var override tests; asserts deployment_name preservation. |
| tests/unit/backend/test_target_service.py | Adds service-layer test ensuring GUI create path preserves explicit model/deployment name. |
| pyrit/prompt_target/openai/openai_target.py | Adjusts underlying-model env var fallback logic to avoid overriding explicit model_name. |
| pyrit/prompt_target/common/prompt_target.py | Adds deployment_name into target identifiers alongside model_name. |
| pyrit/backend/models/targets.py | Extends TargetInstance DTO with deployment_name and clarifies model_name semantics. |
| pyrit/backend/mappers/target_mappers.py | Maps deployment_name from identifier params into TargetInstance responses. |
| frontend/src/types/index.ts | Adds deployment_name to the frontend TargetInstance type. |
| frontend/src/components/Config/TargetTable.tsx | Implements grouped/collapsible TargetTable UI and tooltip behavior. |
| frontend/src/components/Config/TargetTable.test.tsx | Updates/adds tests for new TargetTable grouping and expand/collapse behaviors. |
| frontend/src/components/Config/TargetTable.styles.ts | Adds styling to support multi-line parameter display. |
| frontend/src/components/Config/CreateTargetDialog.tsx | Adds optional “underlying model differs” toggle and field; sends underlying_model when set. |
| frontend/src/components/Config/CreateTargetDialog.test.tsx | Updates placeholder text in tests to match dialog copy change. |
| frontend/src/components/Chat/ChatWindow.tsx | Displays deployment_name in the active target badge when available. |
| frontend/e2e/config.spec.ts | Updates placeholder text used by e2e test to match dialog copy change. |
| // When active target changes, ensure its section is expanded | ||
| useMemo(() => { | ||
| if (activeGroup && !expandedSections.has(activeGroup)) { | ||
| setExpandedSections(prev => new Set([...prev, activeGroup])) | ||
| } | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [activeGroup]) |
There was a problem hiding this comment.
useMemo is being used to perform a side effect (calling setExpandedSections). This runs during render and can trigger React warnings or render loops. Replace this block with a useEffect that expands the active section using a functional state update (so you don’t need to disable the exhaustive-deps rule).
| with patch.dict(os.environ, {"OPENAI_CHAT_UNDERLYING_MODEL": "gpt-4o"}): | ||
| target = OpenAIResponseTarget( | ||
| model_name="gpt-4.1", | ||
| endpoint="https://mock.azure.com/", | ||
| api_key="mock-api-key", | ||
| ) |
There was a problem hiding this comment.
This test patches OPENAI_CHAT_UNDERLYING_MODEL, but OpenAIResponseTarget reads OPENAI_RESPONSES_UNDERLYING_MODEL (see OpenAIResponseTarget._set_openai_env_configuration_vars). As written, the env var override path isn’t exercised for the response target. Patch the correct env var name so the test actually validates the intended behavior.
| import os | ||
| from unittest.mock import patch | ||
|
|
There was a problem hiding this comment.
Imports were added inside the test method. This repo’s Python style guide requires imports at the top of the file (inline imports are only for documented circular-dependency breaks). Please move import os / from unittest.mock import patch to the module import section.
Problem
Users reported that the GUI's target configuration view showed incorrect model names. When creating a target with a specific model name (e.g.,
claude-sonnet-4-6), the target table would displaygpt-4oinstead — the value from theOPENAI_CHAT_UNDERLYING_MODELenvironment variable.This affected:
gpt-4oas their model nameRoot Cause
OpenAITarget.__init__unconditionally fell back to theunderlying_modelenv var (e.g.,OPENAI_CHAT_UNDERLYING_MODEL) even whenmodel_namewas explicitly passed. The identifier then stored this env var value asmodel_name, which the frontend displayed.Fix
Backend
openai_target.py: Only fall back to theunderlying_modelenv var whenmodel_namewas also resolved from env vars. Whenmodel_nameis explicitly passed butunderlying_modelis not, the env var no longer overrides it.prompt_target.py: Storedeployment_name(the user's actualmodel_nameinput) as a separate identifier param alongsidemodel_name(underlying model), so both are always available.target_mappers.py/targets.py: Surfacedeployment_namein the API response.Frontend
Tests
Backend (new)
test_get_identifier_ignores_underlying_model_env_var_when_model_name_explicit— chat targettest_get_identifier_ignores_underlying_model_env_var_when_model_name_explicit— response targettest_create_target_model_name_not_overridden_by_env_var— service layer (GUI create path)deployment_nameis preserved in identifiersFrontend (18 TargetTable tests)
Screenshot
collapsed view
expanded section with tooltip for target where the underlying model differs from the model name