Skip to content

[AAASM-4336] 📝 (metadata): Generate SDK-version pins across example sub-projects#255

Merged
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-4336/docs/examples_shared_metadata
Jul 9, 2026
Merged

[AAASM-4336] 📝 (metadata): Generate SDK-version pins across example sub-projects#255
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-4336/docs/examples_shared_metadata

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

What changed

Adds a single-source-of-truth SDK version pipeline to this repo. Every
example sub-project used to hand-maintain its Agent Assembly SDK
version in two places (its manifest and its README) and every sweep
caught a subset that had drifted. This PR replaces that with:

  1. metadata/sdk-versions.yaml — the single source of truth for
    the Python, Node, and Go SDK version pins and install commands.
  2. scripts/generate_example_metadata.py — a stdlib-only Python
    generator that rewrites the SDK pin in every in-scope manifest and
    inserts a bounded <!-- BEGIN GENERATED: sdk-install --> ... <!-- END GENERATED --> block into every affected README. Idempotent.
  3. .github/workflows/example-metadata-check.yml — CI drift
    check that runs the generator and fails on any diff.
  4. CONTRIBUTING.md — maintainer note explaining the pattern
    and the bump policy.

The PR is intentionally content-neutral for pins: the SoT captures the
currently-shipped versions (Python 0.0.1rc3, Node 0.0.1-rc.3, Go
v0.0.1-rc.3), no examples get bumped. Historical / provenance text
(e.g. "written against 0.0.1-rc.3") is untouched, per the sibling
docs-drift epic convention.

Files touched by category

  • Source of truth: metadata/sdk-versions.yaml
  • Generator: scripts/generate_example_metadata.py
  • CI: .github/workflows/example-metadata-check.yml
  • Docs: CONTRIBUTING.md
  • Python READMEs (13 examples): python/{agno-tool-policy, crewai-research-crew, custom-tool-policy, google-adk, haystack-tool-policy, langchain-basic-agent, langchain-research-agent, langgraph, llamaindex-tool-policy, microsoft-agent-framework-tool-policy, openai-agents-sdk, pydantic-ai, smolagents-tool-policy}/README.md
  • Node READMEs (6 examples): node/{custom-tool-policy, langchain-js-basic-agent, langgraph-js, mastra, openai-node-tool-policy, vercel-ai}/README.md
  • Go READMEs (4 examples + top-level): go/{basic-agent, cli-runtime-integration, langchaingo, tool-policy}/README.md, go/README.md

No manifest files are modified in this PR — every existing pin already
matches the SoT.

Notes on the scope decision

  • Scenario Python manifests are covered by the generator; their pin
    operator is >= (as opposed to == in the top-level python/*
    examples). The regex handles both.
  • Scenario Node packages that do not depend on @agent-assembly/sdk
    are intentionally skipped: they have no SDK version to advertise
    and no manifest line to rewrite.

Related ticket

Closes AAASM-4336. See https://lightning-dust-mite.atlassian.net/browse/AAASM-4336.

How to verify

Idempotency (this is what CI enforces):

python scripts/generate_example_metadata.py
git diff --exit-code

Language spot-checks (one representative example per language, from the
ticket's acceptance criteria):

(cd python/langchain-basic-agent && uv sync --frozen)
(cd node/mastra && pnpm install --frozen-lockfile)
(cd go/basic-agent && go build ./...)

All three pass locally.

Checklist

  • PR title follows [AAASM-XXXX] <GitEmoji> (<scope>): <summary>
  • No secrets, API keys, or .env files committed
  • Example sub-projects include their own README.md with prerequisites and run instructions
  • SDK/runtime version dependencies are documented or pinned

Chisanan232 and others added 8 commits July 9, 2026 10:29
Introduces `metadata/sdk-versions.yaml` at the repo root as the single source
of truth for the Agent Assembly SDK versions advertised across every example
sub-project. Captures the currently-pinned versions (python `0.0.1rc3`, node
`0.0.1-rc.3`, go `v0.0.1-rc.3`) plus install-command templates. Consumed by
the forthcoming `scripts/generate_example_metadata.py` generator to rewrite
manifests and bounded README blocks; CI enforces drift.

Refs AAASM-4336.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add scripts/generate_example_metadata.py — a stdlib-only generator that
regenerates SDK-version pins and bounded README install blocks from the
SoT at metadata/sdk-versions.yaml.

This first landing covers Python: every python/*/pyproject.toml and every
scenarios/*/python/pyproject.toml is rewritten via a narrow regex on the
agent-assembly==... dependency line, and each corresponding README.md gets
a <!-- BEGIN GENERATED: sdk-install --> ... <!-- END GENERATED --> block
inserted below the H1 (or replaced in place on subsequent runs).

The generator is idempotent — a second invocation reports "No changes" —
which is the property CI relies on for drift detection. Node, Go, and
scenarios/* support extend this in follow-up commits.

Refs AAASM-4336.
Run scripts/generate_example_metadata.py to insert the sdk-install
bounded block on every python/*/README.md. Manifest pins already match
the SoT so no pyproject.toml files are touched.

Every python example now advertises the SDK version and install commands
through the generated block; hand-editing the block is caught by the CI
drift check (added in a later commit).

Refs AAASM-4336.
Add rewrite_node_manifest() and rewrite_go_manifest() plus their walker /
processor pairs. The generator now covers all three language groups from
a single invocation:

* Node: every node/*/package.json that pins @agent-assembly/sdk gets its
  version literal rewritten line-by-line (JSON key order preserved).
  Scenario node packages that do not depend on the SDK are skipped.
* Go: every go/*/go.mod line matching the go-sdk module gets its version
  rewritten, whether the pin lives as a bare `require` statement or
  inside a `require ( ... )` block. The top-level go/README.md also
  receives the sdk-install block since it advertises a version literal.

READMEs get the same bounded <!-- BEGIN GENERATED: sdk-install --> block
as the python outputs — flavored per language (pnpm/npm/yarn for node,
go get for go).

Refs AAASM-4336.
Insert the sdk-install bounded block on every node/*/README.md that
depends on @agent-assembly/sdk (6 examples). Manifest pins already
match the SoT so no package.json files are touched.

Refs AAASM-4336.
Insert the sdk-install bounded block on every go/*/README.md and on the
aggregate go/README.md, which advertises a version literal. Manifest
pins already match the SoT so no go.mod files are touched.

Refs AAASM-4336.
Add .github/workflows/example-metadata-check.yml. On every pull request
and push to master that touches an in-scope manifest, README, or the
generator itself, the workflow runs the generator and fails if it
produces any diff.

This is what stops the sweep-caught drift class where a subset of
example manifests get bumped but the corresponding READMEs (or vice
versa) advertise a stale version literal.

Refs AAASM-4336.
Add CONTRIBUTING.md explaining the SoT + generator + CI-check pattern
for keeping SDK version pins in sync across the 20+ example
sub-projects. Covers how to bump on a release, the bounded README block
convention, and what stays outside the generator's scope.

Refs AAASM-4336. Closes AAASM-4336.
@Chisanan232

Copy link
Copy Markdown
Contributor Author

Claude Code review — AAASM-4336

CI status: all 33 required checks green. mergeStateStatus: BLOCKED is branch protection (review requirement), not a CI failure.

AC coverage — final

Acceptance Criterion Status Evidence
metadata/sdk-versions.yaml at repo root, SoT for all 3 SDKs 36 lines, python/node/go with install-command templates
Python stdlib generator, no new deps scripts/generate_example_metadata.py (501 lines) — uses tomllib, re, json, pathlib only
Generator rewrites all in-scope manifests + bounded README blocks 12 python + 6 node + 4 go sub-projects covered; scenarios/* correctly skipped (audit found no drift-prone literals there)
CI drift check runs on every PR .github/workflows/example-metadata-check.yml — 49 lines
Every ~22 sub-project reads SDK version from SoT Bounded <!-- BEGIN GENERATED: sdk-install --> blocks in each sub-project README
Historical release / example-provenance content stays literal Zero manifest content changed; only additive README block insertion
python/* examples still install Spot-check: (cd python/langchain-basic-agent && uv sync --frozen) succeeded
node/* examples still install Spot-check: (cd node/mastra && pnpm install --frozen-lockfile) succeeded
go/* examples still build Spot-check: (cd go/basic-agent && go build ./...) succeeded
Maintainer note added 73-line CONTRIBUTING.md addition documenting SoT + generator + drift-check pattern
Generator idempotent Verified locally: 2nd run reports "No changes" and git diff --exit-code is clean

Side-effect summary

  • Zero manifest content change: no python/*/pyproject.toml, node/*/package.json, or go/*/go.mod was edited. Confirms content-neutral claim (SoT captures CURRENT pins, does not bump).
  • 22 READMEs each got one additive bounded block at the top; existing prose untouched.
  • Aggregate go/README.md picked up a bounded block because it advertised v0.0.1-rc.3 in prose (author-flagged deviation, correct call).
  • python/README.md and node/README.md intentionally left alone — they carry no SDK version literals to protect.
  • No example runtime code touched.

FE / rendered-content validation

  • Playwright not applicable — READMEs render on GitHub.com, no interactive frontend surface. Verified rendered output via GitHub Markdown API instead:
    • Sentinel comment count in rendered HTML: 0 (correctly invisible)
    • Install-text renders (agent-assembly appears 5× in rendered python/langchain-basic-agent/README.md)
    • Rendered HTML preserved at .validation-artifacts/AAASM-4336-example-readme-rendered.html

Notable calls the author made (all defensible)

  • Node + Go generator extension combined into commit 43fbe1a — symmetric code across languages, splitting would have produced artificial commits.
  • scenarios/* skipped — walker enumerates them; no drift-prone literals to rewrite. Not a coverage gap, just correct behavior for a repo shape where scenarios don't hardcode SDK versions.
  • No manifest rewrites in output commits — every pin already matches the SoT, so the generator only inserted README blocks. Expected for a content-neutral PR.

Verdict: ready to approve and merge. 8 commits, all AC met, content-neutral, drift-check gate now enforced in CI. Once this merges, the recurring "example X pinned to old version" sweep-ticket class should stop surfacing.

…ocs/examples_shared_metadata

# Conflicts:
#	python/agno-tool-policy/README.md
#	python/crewai-research-crew/README.md
#	python/google-adk/README.md
#	python/haystack-tool-policy/README.md
#	python/langchain-basic-agent/README.md
#	python/langgraph/README.md
#	python/llamaindex-tool-policy/README.md
#	python/microsoft-agent-framework-tool-policy/README.md
#	python/openai-agents-sdk/README.md
#	python/pydantic-ai/README.md
#	python/smolagents-tool-policy/README.md
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@Chisanan232

Copy link
Copy Markdown
Contributor Author

Merge-conflict resolution — AAASM-4336

Rebased against latest master (which now includes the org-URL rename from AAASM-4343 and 9 Dependabot bumps). Resolved via git merge — no force-push, no amends of my prior commits.

Conflict shape

11 python READMEs conflicted. All had the same shape:

  • My side (HEAD): inserted the bounded <!-- BEGIN GENERATED: sdk-install --> … <!-- END GENERATED --> block below the H1, kept the description line with the OLD repo URL (agent-assembly-examples).
  • Their side (origin/master, from AAASM-4343): updated only the description line to the NEW repo URL (examples).

Resolution

Kept the HEAD side's ordering (bounded block + description) and rewrote the OLD URL to the NEW URL inline. This preserves both changes without any information loss.

Also applied the same rename to:

  • All 4 go/*/README.md and the aggregate go/README.md — git auto-merged the sentinel-block insertion, but the OLD URL remained on the git clone line (fixed programmatically).
  • 3 python READMEs that auto-merged (git handled them because my block and their URL edit were on different lines).

metadata/sdk-versions.yaml, scripts/generate_example_metadata.py, CONTRIBUTING.md, and .github/workflows/example-metadata-check.yml — no changes needed; none referenced the renamed repo.

Post-merge validation (all green locally + on CI)

  • python3 scripts/generate_example_metadata.py — reports "No changes" (idempotent, no drift introduced by the merge)
  • git diff --exit-code — clean after generator run
  • Spot-checks:
    • (cd python/langchain-basic-agent && uv sync --frozen) — OK
    • (cd node/mastra && pnpm install --frozen-lockfile) — OK (picked up Dependabot's @types/node@26.1.1 bump cleanly)
    • (cd go/basic-agent && go build ./...) — OK
  • CI on merged commit: 32 checks pass, 0 fail — including the new Verify metadata drift job.

New head

ad4e3a8 merge commit on top of my original 8 commits. History intact — no rebase, no force-push.

@Chisanan232 Chisanan232 merged commit a14273e into master Jul 9, 2026
32 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-4336/docs/examples_shared_metadata branch July 9, 2026 12:28
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