fix: derive the version from package metadata instead of hardcoding it in eight places (Closes #607)#625
Conversation
…t in eight places (Closes sreerevanth#607)
🧪 PR Test Results
Python 3.12 · commit 385d883 |
📝 WalkthroughWalkthroughThe package version now comes from installed distribution metadata with a fallback, and is reused by package exports, API responses, telemetry defaults, the CLI banner, and the README badge. ChangesDynamic version propagation
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
agentwatch/cli/demo.py (1)
570-589: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider using
rich.panel.Panelto render the banner.Since the project already uses
richfor terminal formatting elsewhere, you can simplify this logic by leveraging aPanel. This avoids manual padding math and string alignment while keeping the box layout intact.🛠️ Proposed refactor
- # The banner is fixed-width box art, so the title cannot simply be interpolated — a version - # string of a different length would push the closing `|` out of alignment and the box would - # visibly break. The padding is computed from the border instead, so any version renders square. - _title = f"AgentWatch - Demo Suite v{__version__}" - _border = "+" + "-" * 62 + "+" - _interior = len(_border) - 2 - _titled = "|" + " " * 9 + _title + " " * max(_interior - 9 - len(_title), 0) + "|" - - print( - bold( - "\n" - + _border - + "\n" - + _titled - + "\n" - + "| Reliability, Safety & Observability Layer for AI Agents |" - + "\n" - + _border - + "\n" - ) - ) + from rich import print as rprint + from rich.panel import Panel + from rich import box + + rprint() + rprint( + Panel( + "[bold]Reliability, Safety & Observability Layer for AI Agents[/bold]", + title=f"[bold]AgentWatch - Demo Suite v{__version__}[/bold]", + title_align="left", + border_style="bold", + expand=False, + box=box.ASCII + ) + ) + rprint()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@agentwatch/cli/demo.py` around lines 570 - 589, Replace the manual banner construction around `_title`, `_border`, `_interior`, and `_titled` with a `rich.panel.Panel`, using the existing Rich styling conventions to preserve the title and descriptive text within a boxed layout. Remove the manual padding and border calculations while keeping the banner’s displayed content and formatting intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@agentwatch/cli/demo.py`:
- Around line 570-589: Replace the manual banner construction around `_title`,
`_border`, `_interior`, and `_titled` with a `rich.panel.Panel`, using the
existing Rich styling conventions to preserve the title and descriptive text
within a boxed layout. Remove the manual padding and border calculations while
keeping the banner’s displayed content and formatting intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e465d317-90f2-4e71-ab5c-e357d80de4db
📒 Files selected for processing (6)
README.mdagentwatch/__init__.pyagentwatch/_version.pyagentwatch/api/server.pyagentwatch/cli/demo.pyagentwatch/telemetry/otel.py
Closes #607
Summary
0.2.0was written out by hand in eight places.pyproject.tomlis now the only one, and everythingthat displays a version reads it from the installed distribution metadata.
I filed this issue saying four places. It's eight, and the ones I'd missed are the ones that matter:
So the API was serving a hardcoded version to clients, and every exported trace was tagged with a
literal. For an observability tool, traces labelled with a version that nobody remembers to bump is
worse than a stale README badge — you can't correlate a regression to a release if the release number
is decorative.
How
New
agentwatch/_version.pyreadsimportlib.metadata.version("agentwatch-ai")once. Everythingelse imports
__version__from it.Three things worth explaining rather than leaving to be discovered in review:
It's a separate module, not just
__init__.__init__.pysets__version__before importingcore.watcher, so a submodule doingfrom agentwatch import __version__would work — by accident ofimport ordering.
_version.pyimports nothing from the package, so there's no cycle to reason about.Verified by importing
agentwatch,agentwatch.api.server,agentwatch.telemetry.otelandagentwatch.cli.democold.The lookup key is the distribution name, not the import name. The package is
agentwatch-ai;version("agentwatch")raisesPackageNotFoundError. Easy to get wrong, and it only fails at runtime.The demo banner is fixed-width box art. Interpolating a version of a different length would push
the closing
|out of line and visibly break the box. The padding is computed from the borderinstead, so any version renders square — checked against
0.2.0,1.0.0rc1,0.10.12,1.2.3.dev20260713and the fallback, all 64/64. At0.2.0it renders byte-identical to today.The README badge
Now a dynamic PyPI endpoint (
img.shields.io/pypi/v/agentwatch-ai) rather than a hardcodedv0.2.0, so it tracks releases on its own.Worth flagging: it will render whatever PyPI has published, which may not be
0.2.0if the releaseisn't out yet. That's arguably more honest — it shows what people can actually install — but it's a
visible change, so say the word if you'd rather I left the badge alone and kept this to the code.
README.md:474("v0.2.0 is being built now") is prose and can't be derived, so I've left it. It's theone remaining place a bump has to be done by hand.
Fallback
If the package isn't installed — a contributor running straight out of a clone —
importlib.metadataraises. Rather than making the package unimportable in exactly the situation someone is most likely to
hit, it falls back to
0.0.0+unknown. Deliberately not a plausible release number, so it can't bemistaken for one in a bug report.
CI installs the package, so CI always sees the real version.
Verified
ruff checkandruff format --checkcleanpip install -e .thenimport agentwatch→0.2.0, matchingimportlib.metadata.version()app.versionon the FastAPI app →0.2.0, so/healthand the root route now report the real onepython -m agentwatch.cli.demoruns end to end, box borders aligned, banner readsv0.2.0"0.2.0"left anywhere inagentwatch/One thing that fell out of testing and is worth recording: on a stale checkout, this printed
0.1.0—correctly, because
0.1.0was what was installed. The old hardcoded string printed0.2.0regardlessof what was actually running. That's the failure mode this fixes, and it turned up on the first run.
Summary by CodeRabbit
Bug Fixes
Documentation