Skip to content

fix(examples): sync requirements.txt with uv.lock; guard drift in CI - #966

Merged
blove merged 2 commits into
mainfrom
blove/examples-agui-requirements-sync
Sep 2, 2026
Merged

fix(examples): sync requirements.txt with uv.lock; guard drift in CI#966
blove merged 2 commits into
mainfrom
blove/examples-agui-requirements-sync

Conversation

@blove

@blove blove commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Problem

examples/ag-ui/python/Dockerfile installs from requirements.txt (a uv export --no-hashes snapshot), not from uv.lock directly. PR #964 bumped pyproject.toml/uv.lock to ag-ui-protocol>=0.1.22 and added a SubagentStartedEvent import that only exists in 0.1.22+, but left requirements.txt pinned to ag-ui-protocol==0.1.19.

Chain of failure:

  1. requirements.txt drifts from uv.lock (nothing catches this).
  2. The Railway ag-ui-demo image builds fine (pip installs the stale pins) but the container fails to import at boot (ImportError: cannot import name 'SubagentStartedEvent').
  3. The /ok healthcheck never comes up.
  4. The deploy job runs railway up --detach, which reports success regardless of whether the new deployment actually became healthy — so the OLD deployment stays live and the break is silent.

Fix

  • Re-ran uv sync && uv export --no-hashes -o requirements.txt in examples/ag-ui/python. The only substantive change is ag-ui-protocol==0.1.190.1.22 (plus its # via comment picking up the direct pyproject.toml pin). Autogenerated header preserved.
  • Verified the fix outside Docker: built a scratch venv from the exported requirements.txt (stripping the local -e . line exactly like the Dockerfile does) and imported src.server:app (and the narrower src.streaming.subagent_emitting_agent.SubagentEmittingAgent) from examples/ag-ui/python — both import cleanly now.
  • Checked the sibling lane, cockpit/ag-ui/subagents/python/requirements.txt — it already pins ag-ui-protocol==0.1.22 (landed via feat(cockpit): ag-ui subagents demo emits the protocol's SUBAGENT_* events #962), so no change needed there.
  • Added a CI drift guard so this can't recur silently: a uv export --no-hashes + diff step in the examples/ag-ui — e2e job, and in the per-cap Cockpit — e2e matrix job (skipped for caps that don't check in a requirements.txt, since most cockpit python caps aren't Docker-deployed). Both fail with an ::error:: pointing at the exact uv export command to fix it.

Test plan

  • uv export --no-hashes -o requirements.txt diff reviewed — only the expected version bump
  • Scratch-venv install from the exported requirements.txt + import src.server succeeds
  • cockpit/ag-ui/subagents/python/requirements.txt confirmed already at 0.1.22
  • .github/workflows/ci.yml YAML validated with yaml.safe_load
  • CI green on this PR (exercises the new drift-check step for real)

🤖 Generated with Claude Code

blove and others added 2 commits September 2, 2026 14:57
…ls ag-ui-protocol 0.1.22

PR #964 bumped pyproject.toml/uv.lock to ag-ui-protocol>=0.1.22 but left
requirements.txt (what the Dockerfile actually installs from) pinned to
0.1.19. The new SubagentStartedEvent import doesn't exist in 0.1.19, so the
Railway ag-ui-demo container fails at boot, /ok never comes up, and
`railway up --detach` silently leaves the old deployment live.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
requirements.txt is what the Dockerfile actually installs from, but uv sync/
uv.lock is what's kept in sync during normal dependency bumps — nothing
previously caught the two falling out of sync (see the prior commit). Add a
`uv export --no-hashes` + diff step to the examples/ag-ui e2e job and the
per-cap cockpit e2e job (skipped for caps that don't check in a
requirements.txt) so drift fails CI with a clear fix-it message instead of
surfacing as a silent production boot failure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@blove
blove enabled auto-merge (squash) September 2, 2026 21:57
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
threadplane Ready Ready Preview Sep 2, 2026 10:01pm UTC

Request Review

@github-actions github-actions Bot 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.

Automated approval: this PR received an intelligent (AI) code review. See the review comments on this PR.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Claude finished @blove's task in 0s —— View job


I'll analyze this and get back to you.

@blove
blove merged commit b57a57e into main Sep 2, 2026
62 of 76 checks passed
blove added a commit that referenced this pull request Sep 2, 2026
…port (#967)

* fix(ci): compare requirements.txt drift against git, not a scratch export

The guard added in #966 exports to /tmp/requirements.check.txt and diffs it
against the checked-in file. uv stamps the -o path it was given into the
export's header comment, so the two files differ on line 2 no matter how
fresh the checked-in export is:

    -#    uv export --no-hashes -o requirements.txt
    +#    uv export --no-hashes -o /tmp/requirements.check.txt

Every lane that has a requirements.txt fails: examples/ag-ui e2e and the six
cockpit/ag-ui cockpit e2e caps. Regenerate in place with the exact command the
error message tells you to run, and let `git diff --exit-code` decide — that
compares against the committed file, so real drift is still caught.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ci): honour what each requirements.txt actually is

Follow-up to the header fix in this branch. Two more ways the guard disagreed
with reality:

- Three lanes export with --no-dev (their header records it), but the guard
  always ran a bare --no-hashes export, so it demanded that pytest and
  pytest-asyncio be committed into the files the Railway images install from.
- cockpit/langgraph/streaming/python/requirements.txt is hand-maintained loose
  pins, not a uv export at all; the guard would have replaced it wholesale with
  a 257-line resolved export.

The guard now reads the command uv stamps into each file's own header: it skips
files that aren't uv exports, and mirrors --no-dev when the header used it.

aws-strands and microsoft-agent-framework are re-exported so their headers
record the --no-dev they were actually built with. Content is byte-identical —
the change is one header line each, no package added or removed from any image.

Verified across all 12 lanes that have a requirements.txt: 9 clean, 1 skipped
as hand-maintained, 2 corrected here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant