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
.github/workflows/python-dependency-maintenance.yml runs weekly and has concluded success on every scheduled run since 2026-08-03. It has not, however, validated a single upper bound in that window. The Run dependency upper-bound validation step was skipped on all five runs, so no package's bounds have been maintained for five weeks while the workflow reported green.
Mechanism. The upper-bound step is gated on the preceding step's outcome:
- name: Run dependency bounds test scenariosid: validate_bounds_testcontinue-on-error: true # line 68run: uv run poe validate-dependency-bounds-test --package "*"
- name: Run dependency upper-bound validationid: validate_rangesif: steps.validate_bounds_test.outcome == 'success' # line 74run: uv run poe validate-dependency-bounds-project --mode upper --package "*"
continue-on-error: true maps the failing step's conclusion to success (which is what the job status and the run badge report), while outcome stays failure — and outcome is what line 74 reads. The result is a run that looks green from the outside and silently does nothing.
Step outcomes per scheduled run (gh run view <id> --json jobs):
Date
Run
Run dependency upper-bound validation
2026-07-27
30239325494
success — last time it ran
2026-08-03
30786524929
skipped
2026-08-10
31355767987
skipped
2026-08-17
31993805435
skipped
2026-08-24
32689375667
skipped
2026-08-31
33356153685
skipped
Every one of those runs reports conclusion: success.
Root cause. The bounds test aborts on the first failing package, and since 2026-08-03 that is always packages/anthropic, always identically. agent_framework_anthropic/_vertex_client.py:23 imports google.auth.credentials under TYPE_CHECKING, but the package declares plain anthropic>=0.80.0,<0.117.0 (no [vertex] extra) and nothing in the repo declares google-auth. The isolated probe therefore has no google-auth to resolve and Pyright fails. The full workspace sync resolves google-auth transitively, which is why the normal poe pyright passes and this never shows up in local or PR CI.
This became a failure with #7342 (merged 2026-07-28), which narrowed probe surfaces so packages stop inheriting transitive extras such as core[all]. That was the right change; packages/core got a dependency-pyright escape hatch for exactly this situation, and packages/anthropic needed one and did not get it. The last passing run is 2026-07-27, the day before #7342 merged.
Why nobody was paged. The workflow's issue-creation step dedupes on title, and #6661 "Dependency bounds test failed" has been open and untouched since 2026-06-22, so each run logs Issue already exists and posts nothing. #6661's body describes a different, since-fixed packages/core failure.
Code Sample
Reproduces on a clean checkout of main. Note that --dry-run only prints the probe commands and cannot reproduce this; the real run is required.
cd python
uv run python -m scripts.dependencies.validate_dependency_bounds --mode test --package anthropic
Error Messages / Stack Traces
Local reproduction, byte-identical to the CI logs for all five runs:
packages\anthropic: lower failed
Task 'pyright' failed for packages\anthropic at resolution 'lowest-direct'.
_vertex_client.py:23:10 - error: Import "google.auth.credentials" could not be resolved (reportMissingImports)
_vertex_client.py:23:56 - error: Type of "GoogleCredentials" is unknown (reportUnknownVariableType)
_vertex_client.py:47:9 - error: Type of parameter "credentials" is partially unknown (reportUnknownParameterType)
_vertex_client.py:120:9 - error: Type of parameter "credentials" is partially unknown (reportUnknownParameterType)
4 errors, 0 warnings, 0 informations
CI, run 33356153685 (2026-08-31T04:11:42Z), same four errors:
packages/anthropic: lower failed
Task 'pyright' failed for packages/anthropic at resolution 'lowest-direct'.
/home/runner/work/.../agent_framework_anthropic/_vertex_client.py:23:10 - error:
Import "google.auth.credentials" could not be resolved (reportMissingImports)
Package Versions
agent-framework-anthropic 1.0.0b260827 (workspace main); the failure is workspace tooling, not a released package.
Python Version
3.13 (UV_PYTHON in the workflow); reproduced locally on 3.13.
Additional Context
I intend to implement this, using the documented extension point rather than a workaround — python/scripts/dependencies/README.md:49: "Uses a package-defined dependency-pyright task when present, allowing dependency probes to type-check the package implementation without requiring optional lazy namespace packages." The fix mirrors packages/core: a pyrightconfig.dependency.json plus a [tool.poe.tasks.dependency-pyright] entry, for packages/anthropic and packages/openai — the two packages whose failure is a probe artifact rather than a real defect (see the inventory below). Repo-wide Pyright is untouched and still checks every file in both packages in full.
What this unblocks. Those two fixes take the gate from 29/35 to 31/35; four real defects remain, listed below, and the gate will not go green until they are addressed too. Once it does, the upper-bound optimizer runs again and resumes maintaining bounds repo-wide. As a concrete example, this is what it picks for the fastapi ceiling in #8042 once it can run — the probe passes Pyright and the full test suite at fastapi 0.141.1:
That also confirms #7342's isolation fix works: the probe no longer inherits DevUI's fastapi<0.138.1, which is what produced the false conflict in #7339.
Follow-ups I am deliberately leaving out of the fix, as maintainer calls:
The masking itself.continue-on-error: true plus an outcome-gated successor means a five-week outage presents as five green runs. Whether the job should fail, or the gate should be restructured, is a decision about failure semantics I would rather not make unilaterally.
Both packages arguably under-declare an optional surface.agent-framework-anthropic ships AnthropicVertexClient while pinning plain anthropic>=0.80.0,<0.117.0 (no [vertex] extra); agent-framework-openai supports Entra ID auth while nothing declares azure-identity. If either is meant to work out of the box, declaring the dependency (anthropic[vertex], an explicit azure-identity) is the real fix and the escape hatch could then be dropped. That changes a published dependency surface, so it needs a maintainer's call.
Raising the fastapi ceilings (Python: [Bug]: agent-framework-ag-ui caps fastapi<0.140.0, which excludes every current release #8042). Left to --mode upper, which is the component designed to choose and validate them. Note that devui (fastapi>=0.115.0,<0.138.1, a runtime dependency) — not ag-ui — is the binding constraint for anyone installing both; hosting-responses declares fastapi under [dependency-groups] test, so it never constrains consumers.
First-failure abort._run_test_mode is sequential and returns on the first failing package, so one brittle package disables bounds maintenance for all 35 — and hides how many others are also broken. Establishing the inventory below required probing each package separately to work around it. Continuing past failures and reporting them together would have surfaced all six on 2026-08-03 instead of one.
The complete blocker inventory. Because the gate aborts on the first failure, fixing one package does not imply a green run — it just moves the abort. To get the real list rather than a lower bound, I probed all 35 packages individually (--mode test --package <name> per package, on Python 3.13 to match UV_PYTHON in the workflow). 29 pass, 6 fail; the fix I am preparing covers two of the six.
needs agent-framework-openai, declares only agent-framework-core
ModuleNotFoundError
azure-contentunderstanding
pyright
to_llm_input(custom_metadata=…) absent at declared floor
TypeError at the floor
foundry_hosting
test
one MCP test in test_responses.py fails at the floor
behavioural break at the floor
They divide cleanly.
Two are probe artifacts, and my fix covers both.anthropic and openai type-check against surfaces they deliberately do not declare because those surfaces are optional — openai's own docstrings say "Credential objects require the optional azure-identity package". A full workspace sync resolves them transitively, so repo-wide Pyright passes and only the isolated probe sees them missing. This is exactly the case dependency-pyright exists for.
Four are real defects that this gate existed to catch. Details for each:
declarative under-declares mcp._mcp_handler.py and _executors_mcp.py import mcp lazily at runtime, and the code states the assumption outright — except ImportError: # pragma: no cover - mcp is a hard dep. But pyproject.toml declares agent-framework-core, httpx, powerfx, pyyaml and no mcp; core declares mcp only in its all extra. So importing the package succeeds and executing its MCP executors raises ImportError for anyone who installed it normally.
lab under-declares agent-framework-openai. Fails with ModuleNotFoundError: No module named 'agent_framework_openai' — "the package agent-framework-openai is required to use…" — while declaring only agent-framework-core.
azure-contentunderstanding has a floor that never worked._context_provider.py:765 calls to_llm_input(..., custom_metadata={"source": filename}); the declared azure-ai-contentunderstanding>=1.2.0b2 has no such parameter. The lower bound is not stale, it is wrong: installing at the floor gives a TypeError at call time.
foundry_hosting fails a test at its floor. Consistently 1 failed / 285 passed at lowest-direct. Which MCP test in tests/test_responses.py surfaces varies between runs (the suite runs under pytest-xdist worksteal), and the validator truncates pytest output, so the precise assertion needs a direct run in the pinned environment.
declarative and lab are worth calling out together: both previously received their missing dependency through the core[all] leakage that #7342 removed. #7342 did not cause those two — it exposed them. They have been shipping under-declared, and the gate that would have said so has been dark since Aug 3.
I am not fixing the four here. They are different packages and different bounds, and two of them change a published dependency surface, which is a maintainer call. Filing them so the state of the gate is visible up front rather than surfacing one abort at a time, and because they are the concrete cost of five weeks without this gate.
Description
.github/workflows/python-dependency-maintenance.ymlruns weekly and has concluded success on every scheduled run since 2026-08-03. It has not, however, validated a single upper bound in that window. TheRun dependency upper-bound validationstep was skipped on all five runs, so no package's bounds have been maintained for five weeks while the workflow reported green.Mechanism. The upper-bound step is gated on the preceding step's
outcome:continue-on-error: truemaps the failing step's conclusion tosuccess(which is what the job status and the run badge report), whileoutcomestaysfailure— andoutcomeis what line 74 reads. The result is a run that looks green from the outside and silently does nothing.Step outcomes per scheduled run (
gh run view <id> --json jobs):Run dependency upper-bound validationEvery one of those runs reports
conclusion: success.Root cause. The bounds test aborts on the first failing package, and since 2026-08-03 that is always
packages/anthropic, always identically.agent_framework_anthropic/_vertex_client.py:23importsgoogle.auth.credentialsunderTYPE_CHECKING, but the package declares plainanthropic>=0.80.0,<0.117.0(no[vertex]extra) and nothing in the repo declaresgoogle-auth. The isolated probe therefore has nogoogle-authto resolve and Pyright fails. The full workspace sync resolvesgoogle-authtransitively, which is why the normalpoe pyrightpasses and this never shows up in local or PR CI.This became a failure with #7342 (merged 2026-07-28), which narrowed probe surfaces so packages stop inheriting transitive extras such as
core[all]. That was the right change;packages/coregot adependency-pyrightescape hatch for exactly this situation, andpackages/anthropicneeded one and did not get it. The last passing run is 2026-07-27, the day before #7342 merged.Why nobody was paged. The workflow's issue-creation step dedupes on title, and #6661 "Dependency bounds test failed" has been open and untouched since 2026-06-22, so each run logs
Issue already existsand posts nothing. #6661's body describes a different, since-fixedpackages/corefailure.Code Sample
Reproduces on a clean checkout of
main. Note that--dry-runonly prints the probe commands and cannot reproduce this; the real run is required.Error Messages / Stack Traces
Local reproduction, byte-identical to the CI logs for all five runs:
CI, run 33356153685 (2026-08-31T04:11:42Z), same four errors:
Package Versions
agent-framework-anthropic 1.0.0b260827 (workspace
main); the failure is workspace tooling, not a released package.Python Version
3.13 (
UV_PYTHONin the workflow); reproduced locally on 3.13.Additional Context
I intend to implement this, using the documented extension point rather than a workaround —
python/scripts/dependencies/README.md:49: "Uses a package-defineddependency-pyrighttask when present, allowing dependency probes to type-check the package implementation without requiring optional lazy namespace packages." The fix mirrorspackages/core: apyrightconfig.dependency.jsonplus a[tool.poe.tasks.dependency-pyright]entry, forpackages/anthropicandpackages/openai— the two packages whose failure is a probe artifact rather than a real defect (see the inventory below). Repo-wide Pyright is untouched and still checks every file in both packages in full.What this unblocks. Those two fixes take the gate from 29/35 to 31/35; four real defects remain, listed below, and the gate will not go green until they are addressed too. Once it does, the upper-bound optimizer runs again and resumes maintaining bounds repo-wide. As a concrete example, this is what it picks for the
fastapiceiling in #8042 once it can run — the probe passes Pyright and the full test suite atfastapi0.141.1:That also confirms #7342's isolation fix works: the probe no longer inherits DevUI's
fastapi<0.138.1, which is what produced the false conflict in #7339.Follow-ups I am deliberately leaving out of the fix, as maintainer calls:
continue-on-error: trueplus anoutcome-gated successor means a five-week outage presents as five green runs. Whether the job should fail, or the gate should be restructured, is a decision about failure semantics I would rather not make unilaterally.agent-framework-anthropicshipsAnthropicVertexClientwhile pinning plainanthropic>=0.80.0,<0.117.0(no[vertex]extra);agent-framework-openaisupports Entra ID auth while nothing declaresazure-identity. If either is meant to work out of the box, declaring the dependency (anthropic[vertex], an explicitazure-identity) is the real fix and the escape hatch could then be dropped. That changes a published dependency surface, so it needs a maintainer's call.fastapiceilings (Python: [Bug]: agent-framework-ag-ui caps fastapi<0.140.0, which excludes every current release #8042). Left to--mode upper, which is the component designed to choose and validate them. Note that devui (fastapi>=0.115.0,<0.138.1, a runtime dependency) — not ag-ui — is the binding constraint for anyone installing both;hosting-responsesdeclares fastapi under[dependency-groups] test, so it never constrains consumers._run_test_modeis sequential and returns on the first failing package, so one brittle package disables bounds maintenance for all 35 — and hides how many others are also broken. Establishing the inventory below required probing each package separately to work around it. Continuing past failures and reporting them together would have surfaced all six on 2026-08-03 instead of one.The complete blocker inventory. Because the gate aborts on the first failure, fixing one package does not imply a green run — it just moves the abort. To get the real list rather than a lower bound, I probed all 35 packages individually (
--mode test --package <name>per package, on Python 3.13 to matchUV_PYTHONin the workflow). 29 pass, 6 fail; the fix I am preparing covers two of the six.anthropicTYPE_CHECKINGimport of undeclaredgoogle.authopenaiTYPE_CHECKINGazure.core+ lazyazure.identity, undeclareddeclarativemcpImportErroron a normal installlabagent-framework-openai, declares onlyagent-framework-coreModuleNotFoundErrorazure-contentunderstandingto_llm_input(custom_metadata=…)absent at declared floorTypeErrorat the floorfoundry_hostingtest_responses.pyfails at the floorThey divide cleanly.
Two are probe artifacts, and my fix covers both.
anthropicandopenaitype-check against surfaces they deliberately do not declare because those surfaces are optional —openai's own docstrings say "Credential objects require the optionalazure-identitypackage". A full workspace sync resolves them transitively, so repo-wide Pyright passes and only the isolated probe sees them missing. This is exactly the casedependency-pyrightexists for.Four are real defects that this gate existed to catch. Details for each:
declarativeunder-declaresmcp._mcp_handler.pyand_executors_mcp.pyimportmcplazily at runtime, and the code states the assumption outright —except ImportError: # pragma: no cover - mcp is a hard dep. Butpyproject.tomldeclaresagent-framework-core,httpx,powerfx,pyyamland nomcp;coredeclaresmcponly in itsallextra. So importing the package succeeds and executing its MCP executors raisesImportErrorfor anyone who installed it normally.labunder-declaresagent-framework-openai. Fails withModuleNotFoundError: No module named 'agent_framework_openai'— "the package agent-framework-openai is required to use…" — while declaring onlyagent-framework-core.azure-contentunderstandinghas a floor that never worked._context_provider.py:765callsto_llm_input(..., custom_metadata={"source": filename}); the declaredazure-ai-contentunderstanding>=1.2.0b2has no such parameter. The lower bound is not stale, it is wrong: installing at the floor gives aTypeErrorat call time.foundry_hostingfails a test at its floor. Consistently 1 failed / 285 passed atlowest-direct. Which MCP test intests/test_responses.pysurfaces varies between runs (the suite runs underpytest-xdistworksteal), and the validator truncates pytest output, so the precise assertion needs a direct run in the pinned environment.declarativeandlabare worth calling out together: both previously received their missing dependency through thecore[all]leakage that #7342 removed. #7342 did not cause those two — it exposed them. They have been shipping under-declared, and the gate that would have said so has been dark since Aug 3.I am not fixing the four here. They are different packages and different bounds, and two of them change a published dependency surface, which is a maintainer call. Filing them so the state of the gate is visible up front rather than surfacing one abort at a time, and because they are the concrete cost of five weeks without this gate.