Skip to content

Python: [BREAKING] Migrate Foundry Local integration to SDK 2.1 - #9322

Draft
bmehta001 wants to merge 11 commits into
microsoft:mainfrom
bmehta001:fix-foundry-local-sdk-compatibility
Draft

bmehta001 wants to merge 11 commits into
microsoft:mainfrom
bmehta001:fix-foundry-local-sdk-compatibility

Conversation

@bmehta001

@bmehta001 bmehta001 commented Oct 12, 2026 •

Copy link
Copy Markdown

Motivation & Context

The Python Foundry Local adapter pins foundry-local-sdk>=0.5.1,<0.5.2 and imports the retired foundry_local API. Installing a current SDK therefore conflicts with the dependency declaration and breaks the adapter import. This updates the integration to the current SDK rather than only relaxing the version pin.

This PR is intentionally draft, pending maintainer agreement on the linked issue and human contributor review. The submitter explicitly chose a current-SDK-only migration instead of maintaining a dual-version adapter.

Description & Review Guide

  • What are the major changes? Require Python 3.11-3.14 and foundry-local-sdk>=2.1.0,<3; use foundry_local_sdk.Configuration, the shared SDK manager, catalog/model lifecycle APIs, and its built-in web service. Keep the existing Agent Framework OpenAI transport, middleware, sessions, and function-invocation layers. Refresh the lockfile, gate the meta-package extra on Python 3.11-3.14, and exclude this package from Python 3.10/3.15 workspace CI. SDK 2.1 pins ONNX Runtime 1.30.0, which has no Python 3.15 wheels.
  • What is the impact of these changes? This is a breaking migration: SDK 0.5.1/1.x and Python 3.10 are no longer supported by this integration. bootstrap=False requires a manager and web service already running in the same process. prepare_model=False requires an already loaded variant or manual preparation; the HTTP service does not load models on the first request. timeout applies to HTTP inference, not native preparation. Model IDs remain exact and device selection does not mutate the shared alias. Expose download progress/cancellation, native top_k/do_sample/early_stopping, existing SDK configuration, and catalog_type="local" (or CatalogType.LOCAL) for SDK-registered BYOM. Public catalog selection remains the default; both model lookup and HTTP inference use the selected catalog without cross-catalog fallback. Normalize token limits and structured-output schemas to the native HTTP contract, merge decoder metadata without mutating caller options, and use tool grammar before final-response schema grammar for required tool calls.
  • What do you want reviewers to focus on? Confirm the SDK support floor and changed bootstrap/preparation semantics. Review shared-manager ownership, exact variant targeting, endpoint construction, and native request normalization. Setup and rollback are serialized. Failed construction closes only a manager it created, or stops only the web service it started on an existing manager; an already running service remains running. The adapter continues using the standard function loop, not a new native-session transport.

The affected package now has 118 passing regression cases, covering lifecycle/concurrency/rollback, configuration, download controls, generation options and metadata precedence, streaming/usage, model overrides, structured output, automatic tool execution enabled/disabled, required tools combined with structured output in both response modes, middleware, session history, image serialization, HTTP errors, and cancellation/reuse. Local-catalog coverage adds alias/exact-ID selection, string/SDK-enum selectors, invalid-input rejection before setup, catalog isolation, manual preparation, download controls, device mismatch, service rollback, and HTTP routing/model overrides in both response modes. Repository-pinned Ruff, strict source Pyright, all five CI-profile test type checkers, and the existing Markdown code-block validator pass locally. No type-checker profile or Python target was weakened. Follow-up commit bc01d20 removes both adapter casts: request forwarding uses checked streaming/non-streaming overloads, the function layer explicitly accepts the advertised Foundry options, and the required model setting is narrowed with an explicit error guard.

Real SDK 2.1 inference was exercised on Windows/Python 3.13, separately from mocked transport coverage: 16 CPU feature cases pass, using qwen3-0.6b-generic-cpu:4 and qwen3.5-0.8b-generic-cpu:3. These cover text/streaming/usage, history, Pydantic output in both modes, JSON-object grammar, tools in both modes, native decoder settings and rejected invalid settings, early stream close/reuse, an exact eight-token output cap, model override, deterministic seeded sampling, and required tools followed by structured output in both modes. An additional real-native failed-construction probe confirms web-service rollback, manager reuse, and subsequent successful inference.

Real accelerated text and streaming inference also pass with qwen3-0.6b-cuda-gpu:2 and CUDAExecutionProvider. GPU observations reached 1,236 MiB VRAM and 45% utilization, rather than relying on provider metadata alone. A cancelled uncached download failed explicitly, then subsequent preparation succeeded with 255 progress observations including 0 and 100.

BYOM/local-catalog selection is exposed in fcfa815, after successful real SDK 2.1 validation. Local clients use /catalogs/local/v1; public clients retain /v1. Eight real BYOM-adapter feature cases pass using two SDK-local registrations of cached Qwen3 CPU assets: text/usage, Pydantic structured output, required tools followed by structured output, and exact model overrides, each in streaming and non-streaming modes. Alias resolution and native preparation also succeed, including a 100% local download-progress callback. The public catalog cannot resolve the local registration, and a failed public lookup leaves the existing local model/service intact. Applications own registration, assets, and shutdown; the adapter does not convert arbitrary model files. The local HTTP route exists in both v2.1.0 and current main; the earlier claim of a backend limitation was incorrect. Vision remains not verified: paired red/blue image probes did not distinguish the images, including a direct HTTP request with combined image/text content. The README does not claim vision support from image serialization or the presence of vision assets. Audio, embeddings, and native-session-only APIs are outside this chat adapter.

Upstream CI for prior head bc01d20 is green: 29 checks pass and 18 are skipped, with no failures or pending checks. Earlier runs encountered the unrelated Windows/Python 3.11 declarative approval/checkpoint assertion in TestApprovalFlow.test_auth_context_binding_survives_workflow_resume[True-True]; it passed on that run without modifying the declarative implementation or test. Fresh upstream CI for BYOM support at fcfa815 is pending.

Related Issue

Fixes #9321.

Original report: microsoft/homebrew-foundrylocal#31.

Maintainer agreement / ready-for-implementation approval has not yet been obtained. This draft is provided for discussion at the submitter's request; it does not claim to satisfy that approval requirement. The open .NET integration PR #5170 is separate from this Python SDK migration.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. Human contributor review and acceptance of responsibility are pending while this PR remains a draft.

AI assistance details: GitHub Copilot assisted with investigation, implementation, regression tests, documentation, dependency-lock refresh, native CPU/GPU validation, and this description. Validation helper workflows and downloaded artifacts are not part of this PR.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) -- a workflow keeps the label and title prefix in sync automatically.

Use the in-process SDK singleton and catalog model APIs with the existing OpenAI transport. Require Python 3.11 and document the breaking migration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
Copilot AI balanced review requested due to automatic review settings October 12, 2026 22:36
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 22:36 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 22:36 — with GitHub Actions Active
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible labels Oct 12, 2026
Follow the existing OpenAI test pattern so transport coverage works with both OpenAI 2.x and locked OpenAI 3.x/httpx2.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 22:39 — with GitHub Actions Active

Copilot AI 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.

🟡 Changes recommended

Python 3.15 compatibility declarations and CI gating are inconsistent, and singleton construction has a concurrency race.

5 open findings
What changed in this PR

Migrates the Python Foundry Local integration to SDK 2.1, addressing #9321 while retaining Agent Framework’s OpenAI transport.

Changes:

  • Adopts the SDK singleton, catalog/model lifecycle, and built-in web service.
  • Raises support to Python 3.11+ and updates dependencies and CI.
  • Expands migration documentation and regression tests.
File Description
.github/​workflows/​python-tests.yml Updates Python-version exclusions.
python/​packages/​core/​pyproject.toml Gates the Foundry Local extra.
python/​packages/​foundry_local/​AGENTS.md Updates package guidance.
python/​packages/​foundry_local/​README.md Documents usage and migration.
python/​packages/​foundry_local/​agent_framework_foundry_local/​_foundry_local_client.py Implements SDK 2.1 integration.
python/​packages/​foundry_local/​pyproject.toml Updates Python and SDK requirements.
python/​packages/​foundry_local/​tests/​conftest.py Adds SDK-aware fixtures.
python/​packages/​foundry_local/​tests/​test_foundry_local_client.py Expands lifecycle and transport tests.
python/​samples/​02-agents/​providers/​foundry/​foundry_local_agent.py Updates sample APIs and cleanup.
python/​uv.lock Resolves SDK 2.1 dependencies.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/python-tests.yml Outdated
Comment thread python/packages/core/pyproject.toml Outdated
Comment thread python/packages/foundry_local/pyproject.toml Outdated
Comment thread python/packages/foundry_local/README.md Outdated
SDK 2.1 pins ONNX Runtime 1.30.0, which has no Python 3.15 wheels. Exclude Foundry Local from the 3.15 workspace job and align package and extra metadata with Python 3.11-3.14.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 22:44 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 22:46 — with GitHub Actions Active
Hold the adapter setup lock through singleton initialization, web-service startup, model preparation, and failure rollback. Add concurrent success/failure regressions and keep invalid-input and transport tests compatible with all CI type checkers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 23:47 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 12, 2026 23:52 — with GitHub Actions Active
Avoid passing an unspecialized generic constructor to Executor.submit, and isolate the concurrency regressions from real HTTP client initialization.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 00:02 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 00:03 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 00:13 — with GitHub Actions Active
Normalize native token limits and response schemas, preserve required tool invocation before structured replies, expose download controls, and roll back services started during failed client setup. Expand transport and agent regressions and document public-catalog-only scope.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 18:38 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 18:39 — with GitHub Actions Active
The Foundry Local checks passed. The first full matrix failed in the existing declarative MCP approval/checkpoint regression and cancelled other matrix rows. GitHub requires repository-admin rights for a rerun, so trigger a fresh check run without changing unrelated code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 18:50 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 19:03 — with GitHub Actions Active
Forward streaming and non-streaming requests through checked overloads, declare the function layer's supported Foundry options explicitly, and narrow the required model setting with an explicit error guard.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 21:52 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 21:52 — with GitHub Actions Active
SDK 2.1 supports registered local models through /catalogs/local/v1. Keep local-catalog selection intentionally outside this adapter, rather than incorrectly describing it as a backend limitation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 22:22 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 22:22 — with GitHub Actions Active
Add explicit public/local catalog selection for model lookup and inference, retaining the public default and catalog isolation. Cover selection, invalid input, preparation, rollback, and streamed/non-streamed model overrides, and document SDK-owned registration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d8ebdb3c-28b8-4fa1-830d-3fa7d6333d9e
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 22:39 — with GitHub Actions Active
@bmehta001
bmehta001 deployed to github-app-auth October 13, 2026 22:41 — with GitHub Actions Active

This branch was successfully deployed

1 active deployment
github-app-auth — fcfa815b Deployed Oct 13, 2026 by bmehta001 via add_label #25250
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Usage: [PRs], Target: all PRs that introduce changes that are not backward compatible documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: Python: [Bug]: Foundry Local integration excludes current SDK versions

3 participants