Skip to content

Accept project-scoped AI Foundry endpoints#23

Open
TheovanKraay wants to merge 1 commit into
AzureCosmosDB:mainfrom
TheovanKraay:feature/normalize-foundry-project-endpoint
Open

Accept project-scoped AI Foundry endpoints#23
TheovanKraay wants to merge 1 commit into
AzureCosmosDB:mainfrom
TheovanKraay:feature/normalize-foundry-project-endpoint

Conversation

@TheovanKraay

Copy link
Copy Markdown
Contributor

Accept project-scoped AI Foundry endpoints

Why

ai_foundry_endpoint only accepts the account-level inference endpoint today (https://<resource>.services.ai.azure.com or .openai.azure.com), because the toolkit talks to the model APIs through the OpenAI SDK (AzureOpenAI(azure_endpoint=...)). But the Azure AI Foundry portal commonly hands users a project-scoped URL instead:

https://<resource>.services.ai.azure.com/api/projects/<project-name>

Pasting that into AI_FOUNDRY_ENDPOINT yields opaque 404/routing errors. The parameter name promises "a Foundry endpoint" but the implementation silently demands an Azure OpenAI one.

This surfaced while integrating the toolkit into the Microsoft Agent Framework as a CosmosMemoryContextProvider (new agent-framework-azure-cosmos-memory package). The goal there is a single-endpoint experience: one AI Foundry endpoint drives both the memory pipeline (this toolkit) and the chat agent (the framework's FoundryChatClient). The catch — the framework's client accepts the project URL natively, but the toolkit rejects the exact same value unless the user manually strips /api/projects/<name>.

Why fix it here (and not in the Agent Framework integration)

ai_foundry_endpoint is the toolkit's own public contract, so the toolkit should own what's valid for it. Fixing it here benefits every consumer (direct users, the Agent Framework provider, future integrations), not just one wrapper. Pushing normalization into the integration layer would paper over the leaky abstraction and leave the next caller to rediscover the same papercut. Since, for *.services.ai.azure.com resources, the project path is just a suffix on the same host that serves inference, the safe, canonical fix lives right where the endpoint is consumed.

What changed

  • New helper normalize_ai_foundry_endpoint() in _utils.py: strips a
    trailing /api/projects/<name>[/...] (case-insensitive), trims whitespace and
    trailing slash, passes None/empty through, and leaves non-project endpoints
    unchanged.
  • Applied once in _BaseMemoryClient._init_base_config — the single config
    chokepoint shared by the sync and async clients.
  • Docs: .env.template documents the accepted forms; CHANGELOG.md updated.

Behavior (non-breaking)

Input Result
https://r.services.ai.azure.com/api/projects/p https://r.services.ai.azure.com
https://r.services.ai.azure.com / https://r.openai.azure.com unchanged
https://r.services.ai.azure.com/ https://r.services.ai.azure.com
None / "" unchanged

Tests

10 new tests (8 for the helper, 2 on the base client). Full unit suite green except 5 pre-existing duration_ms > 0.0 reconcile-telemetry timing flakes (confirmed failing on main; unrelated).

Scope

Covers the modern *.services.ai.azure.com case via pure string normalization (no new deps). Legacy hub/project endpoints on a different host than the linked Azure OpenAI resource would need AIProjectClient lookup — left as a follow-up.

Normalize ai_foundry_endpoint so a project-scoped Foundry URL (.../api/projects/<name>) is stripped to the inference base the OpenAI SDK expects. Lets callers paste whichever endpoint form the Foundry portal shows them. Adds unit tests, CHANGELOG, and .env.template guidance.
Copilot AI review requested due to automatic review settings June 24, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the toolkit’s handling of ai_foundry_endpoint so users can provide Azure AI Foundry project-scoped URLs (as commonly copied from the Foundry portal) and have them automatically normalized to the account-level inference base URL required by the OpenAI SDK.

Changes:

  • Added normalize_ai_foundry_endpoint() to strip /api/projects/<name>[/…], trim whitespace, and remove trailing slashes.
  • Applied normalization at the shared configuration chokepoint (_BaseMemoryClient._init_base_config).
  • Added unit tests plus documentation updates (.env.template, CHANGELOG.md).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
azure/cosmos/agent_memory/_utils.py Adds endpoint normalization helper for Foundry project-scoped URLs.
azure/cosmos/agent_memory/_base/base_client.py Applies normalization when initializing shared client config.
tests/unit/test_utils.py Adds unit coverage for the new normalization helper.
tests/unit/_base/test_base_client.py Verifies normalization is applied during base client initialization.
.env.template Documents accepted endpoint forms (including project-scoped URLs).
CHANGELOG.md Notes new behavior for ai_foundry_endpoint in Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +204 to +208
if not endpoint:
return endpoint
trimmed = endpoint.strip()
trimmed = _AI_FOUNDRY_PROJECT_PATH_RE.sub("", trimmed)
return trimmed.rstrip("/")

@aayush3011 aayush3011 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, other than the copilot comment and the lint builds failing

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants