Skip to content

docs: generate correct numbered anchors for proto type links#1966

Open
msrivastav13 wants to merge 4 commits into
a2aproject:mainfrom
msrivastav13:fix/macros-numbered-anchors
Open

docs: generate correct numbered anchors for proto type links#1966
msrivastav13 wants to merge 4 commits into
a2aproject:mainfrom
msrivastav13:fix/macros-numbered-anchors

Conversation

@msrivastav13

@msrivastav13 msrivastav13 commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1945. This is the second of two PRs for that issue — #1965 fixes hand-written anchor links; this one fixes the generated links in the proto tables, which is the larger half of the problem the issue describes ("broken in many tables"). Either PR closes the issue; they can be merged independently.

Problem

The proto table macros in .mkdocs/macros.py (proto_to_table / proto_service_to_table) linked each non-primitive type to a bare lowercased slug:

label = f'[{label}](#{display_name.lower()})'   # Message -> #message

But specification.md section headers render to numbered anchors (e.g. #### 4.1.4. Message#414-message). So every type cross-reference inside the generated tables was a dead link — about 45 across the spec, including the #message example called out in #1945.

Fix

_format_type_for_docs now resolves each type name against a map built by scanning the spec's numbered headers (#### 4.1.4. Message#414-message). Types that have no dedicated header (e.g. SendMessageResponse, StreamResponse, the *Request wrappers — 15 of them) render as plain text instead of a broken link.

Verification

Local mkdocs build:

  • 'no such anchor' warnings for specification.md dropped from ~45 → 0
  • Spot-checked rendered HTML: Message#414-message, Task#411-task, AgentCard#441-agentcard; undocumented types render as plain <code> with no href.

The proto table macros (proto_to_table / proto_service_to_table) linked
each non-primitive type to a bare lowercased slug, e.g. Message -> #message.
But specification.md section headers render to numbered anchors such as
a2aproject#414-message, so every type cross-reference in the generated tables was a
dead link (~45 across the spec, including the #message example in a2aproject#1945).

_format_type_for_docs now resolves each type name against a map built from
the spec's numbered headers (#### 4.1.4. Message -> a2aproject#414-message). Types
that have no dedicated header (e.g. SendMessageResponse, StreamResponse,
*Request wrappers) render as plain text instead of a broken link.

Verified with a local mkdocs build: 'no such anchor' warnings for
specification.md dropped from ~45 to 0.

Part of a2aproject#1945
@msrivastav13 msrivastav13 requested review from a team as code owners June 21, 2026 13:25

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a mechanism to dynamically map protobuf type names to their numbered section headers in specification.md, preventing broken links in the generated documentation. It adds helper functions to parse the specification file, slugify the headers, and build an anchor map. The review feedback suggests initializing _ANCHOR_MAP as an empty dictionary instead of None to simplify lookups and eliminate the need for fallback checks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread .mkdocs/macros.py Outdated
Comment thread .mkdocs/macros.py Outdated
@msrivastav13 msrivastav13 changed the title fix(docs): generate correct numbered anchors for proto type links docs: generate correct numbered anchors for proto type links Jun 21, 2026
@msrivastav13

Copy link
Copy Markdown
Contributor Author

Note on CI: the build_and_deploy check (docs.yml) does not run on this PR because its paths: filter watches docs/**, mkdocs.yml, etc. but not .mkdocs/** — so a change to .mkdocs/macros.py alone doesn't trigger a docs rebuild. I verified the build locally instead:

$ mkdocs build   # via the repo's requirements-docs.txt
INFO - Documentation built in ~4s
# 'no such anchor' warnings for specification.md: ~45 (before) -> 0 (after)

Rendered HTML spot-check: Message#414-message, Task#411-task, AgentCard#441-agentcard; undocumented types (StreamResponse, *Request wrappers) render as plain <code> with no href.

Separately, maintainers may want to add .mkdocs/** to the docs.yml path filter so future changes to the rendering macros are covered by CI.

Address review feedback: initialize _ANCHOR_MAP to {} instead of None so
lookups don't need a None check or 'or {}' fallback.
@msrivastav13

Copy link
Copy Markdown
Contributor Author

Addressed review feedback

Applied both Gemini suggestions in d3f2dee: _ANCHOR_MAP is now initialized to {} instead of None, so the lookup is a plain _ANCHOR_MAP.get(display_name) with no None check or or {} fallback. Re-verified with a local build — still 0 no such anchor warnings.

Self code-review notes

I also reviewed the change myself for correctness:

  • Duplicate-header collisions: The header regex matches any numbered single-word header, so I checked for type-name collisions across the spec. The only one is Streaming (### 10.7 vs ### 11.7), which is a section title, not a proto type — no actual type resolves ambiguously. All real types map to their canonical §4 data-model anchors (Task#411-task, Message#414-message, Artifact#417-artifact, etc.).
  • Slug parity: _slugify mirrors the repo's configured pymdownx.slugs.slugify (case: lower) — lowercase, strip non-[a-z0-9 _-], spaces/underscores → -, collapse repeats. Confirmed against rendered HTML ids.
  • Graceful degradation: If specification.md is missing or a type has no header, _build_anchor_map returns/omits cleanly and the type renders as plain <code> — no exceptions, no dead links.
  • Scope: Pure rendering-logic change in .mkdocs/macros.py; no spec content or proto changes.

holtskinner pushed a commit that referenced this pull request Jun 22, 2026
## Summary

Fixes #1968.

The **Docs Build and Deploy** workflow (`.github/workflows/docs.yml`)
only triggers when `docs/**`, `mkdocs.yml`, `requirements-docs.txt`, or
the workflow file change. But the rendered site also depends on inputs
that are **not** in the path filter:

- **`.mkdocs/**`** — the macros module (`.mkdocs/macros`) and theme
overrides (`.mkdocs/overrides`), both referenced from `mkdocs.yml`
- **`specification/a2a.proto`** — the source the `proto_to_table` /
`proto_service_to_table` macros parse to generate the API tables
- **`scripts/build_docs.sh`** — the build entrypoint the workflow
actually runs

A change to any of these can break the build or alter every rendered
page while CI stays green. Concrete example: the macros anchor fix in
#1966 changes rendering logic for the whole spec, yet `build_and_deploy`
never ran on it because `.mkdocs/**` wasn't watched.

## Change

Add `.mkdocs/**`, `specification/a2a.proto`, and `scripts/build_docs.sh`
to both the `push` and `pull_request` path filters. No behavioral change
to the build itself — it just runs in more of the cases where it should.

## Verification

- `docs.yml` parses as valid YAML.
- Both `paths:` blocks updated identically.
- Cross-checked the added paths against `mkdocs.yml` (`custom_dir:
.mkdocs/overrides`, `module_name: .mkdocs/macros`) and
`scripts/build_docs.sh` (reads `specification/a2a.proto`).
- This PR self-demonstrates the fix: editing `docs.yml` triggered
`build_and_deploy`, which previously would not run for a `.mkdocs/`-only
change.

@msampathkumar msampathkumar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally. LGTM.

@msampathkumar

Copy link
Copy Markdown
Member

Nice work @msrivastav13.

This change updates the specification documents. So I have informed TSE to check and add second review.

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.

[Bug]: Invalid HTML anchors in spec

3 participants