Skip to content

Python: [Bug]: FoundryAgent inherits unrelated OPENAI_CHAT_MODEL for agent-reference requests #7272

Description

Description

FoundryAgent incorrectly inherits OPENAI_CHAT_MODEL from the process environment even though the target Prompt Agent or Hosted Agent already owns its model through agent_reference.

This can cause an unrelated OpenAI deployment name to be copied into FoundryAgent.default_options and sent alongside the Foundry agent reference. Foundry then rejects the request when that value differs from the persisted agent definition's model.

Observed with a Prompt Agent configured for gpt-5.4 and a development .env containing OPENAI_CHAT_MODEL=gpt-4.1:

FOUNDRY_MODEL='gpt-5.4'
RawFoundryAgentChatClient.model='gpt-4.1'
FoundryAgent.client.model='gpt-4.1'
FoundryAgent.default_options.model='gpt-4.1'

The value flows through these steps:

  1. RawFoundryAgentChatClient obtains an OpenAI-compatible client from AIProjectClient.
  2. Its RawOpenAIChatClient base resolves OPENAI_CHAT_MODEL even though no model is required for an agent-reference request.
  3. Agent.__init__ copies client.model into default_options.
  4. RawFoundryAgentChatClient._prepare_options sees options["model"] as populated and therefore does not strip it.
  5. Foundry compares the unrelated model with the persisted agent model and rejects the request.

Expected behavior: generic OPENAI_* and AZURE_OPENAI_* model environment variables must not implicitly configure RawFoundryAgentChatClient/FoundryAgent. The persisted Foundry agent definition should resolve the model. If explicitly supplying a matching model remains supported, it should be distinguishable from an environment-derived value.

This was discovered while independently validating the stateless reasoning replay work from #7233; it prevents the request from reaching that workflow logic and is a separate defect.

Code Sample

import asyncio
import os

from agent_framework.foundry import FoundryAgent
from azure.identity.aio import AzureCliCredential


async def main() -> None:
    # The existing Prompt Agent named below is configured with gpt-5.4.
    os.environ["OPENAI_CHAT_MODEL"] = "gpt-4.1"

    async with (
        AzureCliCredential() as credential,
        FoundryAgent(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            agent_name="existing-gpt-5.4-prompt-agent",
            agent_version="1",
            credential=credential,
        ) as agent,
    ):
        print(f"client model: {agent.client.model!r}")
        print(f"request model: {agent.default_options.get('model')!r}")
        await agent.run("Respond with exactly: ok")


asyncio.run(main())

The local contamination can also be demonstrated without a service call by supplying a mocked project client's OpenAI client and inspecting RawFoundryAgentChatClient.model and FoundryAgent.default_options.

Error Messages / Stack Traces

Error code: 400
{
  "error": {
    "code": "invalid_payload",
    "message": "Invalid payload",
    "type": "invalid_request_error",
    "details": [
      {
        "code": "ValidationError",
        "message": "Model must match the agent's model 'gpt-5.4' when agent is specified.",
        "param": "model",
        "type": "error"
      }
    ]
  }
}

Package Versions

Latest main source at 2d34deeb8269ebaa2c27332e1bbf80726fa48b32 with local environment metadata: agent-framework-core==1.11.0, agent-framework-foundry==1.10.1, azure-ai-projects==2.2.0, openai==2.45.0.

Python Version

Python 3.13.5

Additional Context

Suggested regression coverage:

  • Set OPENAI_CHAT_MODEL to a value different from the persisted Foundry agent model.
  • Assert RawFoundryAgentChatClient.model does not inherit it.
  • Assert FoundryAgent.default_options does not contain the inherited model.
  • Assert an agent-reference request omits an environment-derived model.
  • Preserve intentional behavior for an explicitly supplied matching model, if that override is supported.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

pythonUsage: [Issues, PRs], Target: Python

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions