You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support bring-your-own LLM (hosted OpenAI-compatible / Azure OpenAI) - #2035
apiKey in languageModel config, with @env:VAR_NAME support so keys stay out of config files. Sent as Authorization: Bearer for OpenAI (any OpenAI-compatible endpoint: OpenAI, GitHub Models, OpenRouter) and Ollama clients, and as the api-key header for AzureOpenAI. The key is never logged.
AzureOpenAI client that reuses the OpenAI client against the Azure OpenAI v1 API (https://<resource>.openai.azure.com/openai/v1/, model = deployment name). It requires an API key.
Non-billable availability check: the startup probe now calls GET {url}/models:
2xx and the configured model is listed (incl. Ollama's :latest tag) → enabled, no completion sent
401/403 → disabled with a clear error
Azure OpenAI 2xx → enabled (Azure lists base models, not deployments)
otherwise (endpoint unsupported, model not listed) → falls back to the previous completion probe
Updated schemas/v4.0.0/rc.schema.json and docs in skills/dev-proxy/references.
Extends the existing clients (no new dependencies) rather than switching to Microsoft.Extensions.AI.
Validation
New unit tests in DevProxy.Abstractions.Tests/LanguageModel (headers, @env: resolution, probe paths)
E2E with local Ollama + OpenAIMockResponsePlugin: the startup check used only /models, mocked completions worked, and the key didn't appear in the logs
…net#2034
- Add `apiKey` to `languageModel` config with `@env:VAR_NAME` support.
Sent as a Bearer token (OpenAI-compatible, Ollama) or `api-key` header
(Azure OpenAI). The key is never logged.
- Add `AzureOpenAI` client targeting the Azure OpenAI v1 API.
- Check availability with `GET /models` instead of a billable completion,
falling back to the completion probe when /models is unsupported or
doesn't list the configured model.
- Update v4.0.0 rc.schema.json and docs.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Redact the configured API key from logged provider errors
- Fall back to a completion probe on /models 403 (restricted keys); 401 still disables
- Disable the LM when the fallback completion fails
- Guard /models JSON parsing against unexpected payload shapes
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The language-model HttpClient can leak Azure API keys through cross-origin redirects and trigger recursive requests when Dev Proxy intercepts hosted completions.
The language-model client uses the default proxy-aware HttpClient registered in DevProxy/Extensions/IServiceCollectionExtensions.cs:85–89. If its proxy settings route the hosted endpoint through Dev Proxy and the URL is watched by OpenAIMockResponsePlugin, an uncached completion is intercepted and calls the same client again, creating recursive requests instead of reaching the provider. Use a dedicated language-model handler that bypasses Dev Proxy, or add an explicit internal-request bypass in the proxy pipeline.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unresolved issues can incorrectly enable case-mismatched models, leave dedicated HTTP clients undisposed across reloads, and cause redirect tests to fail from reused ports.
For endpoints with case-sensitive model IDs, this comparison accepts an invalid configuration such as GPT-4.1-mini when /models lists gpt-4.1-mini. The shortcut then caches the client as enabled, while completion requests send the configured name unchanged and fail. Use ordinal, case-sensitive comparisons for both the exact ID and the :latest alias.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2034
Changes
apiKeyinlanguageModelconfig, with@env:VAR_NAMEsupport so keys stay out of config files. Sent asAuthorization: BearerforOpenAI(any OpenAI-compatible endpoint: OpenAI, GitHub Models, OpenRouter) andOllamaclients, and as theapi-keyheader forAzureOpenAI. The key is never logged.AzureOpenAIclient that reuses the OpenAI client against the Azure OpenAI v1 API (https://<resource>.openai.azure.com/openai/v1/,model= deployment name). It requires an API key.GET {url}/models::latesttag) → enabled, no completion sentschemas/v4.0.0/rc.schema.jsonand docs inskills/dev-proxy/references.Extends the existing clients (no new dependencies) rather than switching to Microsoft.Extensions.AI.
Validation
DevProxy.Abstractions.Tests/LanguageModel(headers,@env:resolution, probe paths)OpenAIMockResponsePlugin: the startup check used only/models, mocked completions worked, and the key didn't appear in the logs