Skip to content

Conversation

@Steinblock
Copy link
Contributor

@Steinblock Steinblock commented Aug 18, 2025

with keyed OpenAIClients

builder.AddKeyedOpenAIClient("openai");
builder.AddKeyedOpenAIClient("ionos");

assuming that at least one keyed OpenAIClient has a differnt endpoint,

{
  "ConnectionStrings": {
    "openai": "Key={account_key};"
    "ionos": "Endpoint=https://{openai_rest_api_url};Key={account_key};"
  }
}

getting the client with

var client = serviceProvider.GetRequiredKeyedService<OpenAIClient>("ionos")

the client uses the key from the connectionstring but it still has the default enpoint https://api.openai.com/v1

The issue is that ConfigureOpenAI ignores the serviceKey and always get's the default OpenAIClientOptions instead of the one created with optionsName = servicekey.

This makes using keyed OpenAIClients virtually impossible because the main reason having multiple OpenAIClients is having different endpoints.

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

with keyed OpenAIClients

```
builder.AddKeyedOpenAIClient("openai");
builder.AddKeyedOpenAIClient("ionos");
```

assuming that at least one keyed OpenAIClient has a differnt endpoint,

```
{
  "ConnectionStrings": {
    "openai": "Key={account_key};"
    "ionos": "Endpoint=https://{openai_rest_api_url};Key={account_key};"
  }
}
```

 getting the client with

```
var client = serviceProvider.GetRequiredKeyedService<OpenAIClient>("ionos")
```

the client uses the key from the connectionstring but it still has the default enpoint https://api.openai.com/v1

The issue is that ConfigureOpenAI ignores the serviceKey and always get's the default OpenAIClientOptions instead of the one created with optionsName = servicekey.

This makes using keyed OpenAIClients virtually impossible because the main reason having multiple OpenAIClients is having different endpoints.
@github-actions github-actions bot added the area-integrations Issues pertaining to Aspire Integrations packages label Aug 18, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Aug 18, 2025
@Steinblock
Copy link
Contributor Author

@dotnet-policy-service agree

@eerhardt
Copy link
Member

Can you add tests for this?

@Kumima
Copy link
Contributor

Kumima commented Aug 19, 2025

Fixing #9543
Is this better? And did you take a look at the azure related stuff?

options = serviceProvider.GetRequiredService<IOptionsMonitor<OpenAIClientOptions>>()
                        .Get(serviceKey ?? Options.DefaultName);

According to: openai/openai-dotnet#215
Tests can be tricky using reflection.

@Steinblock
Copy link
Contributor Author

@eerhardt I added a test case that is failing without my changes and passing afterwards.

As @Kumima mentioned, testing this is tricky because OpenAIClient doesn't expose the endpoint.

I don't really like the test because I usually only test the public interface of a class but I could not figure out how to workaround this so I opted for using reflection to get the endpoint.

@Kumima

This would work as well.

var options = serviceProvider
                        .GetRequiredService<IOptionsMonitor<OpenAIClientOptions>>()
                        .Get(serviceKey ?? Options.Options.DefaultName);

Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for the fix!

@eerhardt eerhardt enabled auto-merge (squash) August 19, 2025 22:32
@eerhardt eerhardt disabled auto-merge August 19, 2025 22:33
@eerhardt eerhardt enabled auto-merge (squash) August 19, 2025 22:33
@eerhardt eerhardt merged commit 79d4eed into dotnet:main Aug 19, 2025
292 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 9.5 milestone Aug 19, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Sep 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-integrations Issues pertaining to Aspire Integrations packages community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants