Index the 96 AG-UI documentation pages hosted on docs.copilotkit.ai - #164
Merged
Merged
Conversation
The two silent failures this config has had were both invisible to every unit test in the suite, because they lived in the YAML that ships rather than in any synthetic fixture: the API reference tree went unclaimed for months, and the 96 live ag-ui pages still are. This reads deploy/copilotkit-docs.yaml itself and asserts, through the real matchesPatterns and deriveUrl, which files the docs source claims and what URL each one derives. Red as committed: the four ag-ui coverage cases fail.
showcase/shell-docs/src/content/ag-ui/ is 96 .mdx files served live at docs.copilotkit.ai/ag-ui/<slug> by src/app/ag-ui/[[...slug]], and all 96 are in the production sitemap. No configured source claimed one of them: the docs source already walked their parent directory, but its file_patterns named only the docs/ and reference/ subtrees. CopilotKit includes AG-UI, so they are indexed here. They near-duplicate the upstream ag-ui-protocol/ag-ui docs tree that the ag-ui-docs source indexes, which is why this is one more pattern on the existing docs source rather than a separate source: a separate source could not feed search-docs (a search tool takes exactly one source), so it would need a third docs tool sitting between two that already confuse each other. The two tool descriptions now say which site's links each one hands back. No change to url_derivation was needed and none was made. ag-ui/ is not under content/docs/, so it falls through the ordered strip_prefix list to the content/ prefix and keeps its directory: content/ag-ui/concepts/agents.mdx -> /ag-ui/concepts/agents. Measured through the real walkSourceFiles + deriveUrl path against a fresh CopilotKit checkout (7a36707ab): 866 -> 962 files, +96. The manifest of all 866 pre-existing docs/ and reference/ URLs is byte-identical before and after. All 96 derived ag-ui URLs appear in the production sitemap, 96/96; 88 return HTTP 200 live and 8 return HTTP 500 — a pre-existing render fault on the docs site itself, not a derivation error, since an invented slug under the same route returns 404. The unclaimed-content audit now reports zero clusters for this repo, down from the one 96-file .mdx cluster it was built to find.
jpr5
added a commit
that referenced
this pull request
Sep 13, 2026
) ## What is wrong `showcase/shell-docs/src/content/ag-ui/` no longer exists. **CopilotKit#7092, "fix(docs): remove retired AG-UI mirror"**, merged `2026-09-11T22:44:24Z` (`tylerslaton`, merge `3e86b8d55`) — **112 files, 20 additions, 25,059 deletions** — deleted the whole tree plus `src/app/sitemap.ts` and `src/app/llms-mdx/[[...slug]]/route.ts`. Confirmed against the live API: ``` $ gh api repos/CopilotKit/CopilotKit/contents/showcase/shell-docs/src/content --jq '.[].name' docs doctest.json framework-overviews reference snippets ``` #164 (`298b7fa`) had added `showcase/shell-docs/src/content/ag-ui/**/*.mdx` to the `docs` source's `file_patterns`. Its full walk completed `2026-09-11T08:11:58Z` — about **14 hours before** the deletion landed. We indexed a tree that was retired that night. Today the production sitemap still advertises 96 `/ag-ui/` URLs from a stale build; 88 serve 200 and 8 already return 500. As the site rebuilds, those URLs die, and our index keeps handing them out. **No content becomes unsearchable.** `search-ag-ui-docs` already indexes the upstream `ag-ui-protocol/ag-ui` repo (~1,317 chunks) and answers with `docs.ag-ui.com` links, which resolve. Only the link target changes — to the one that will still exist. ## What changed 1. **Removed the `ag-ui` `file_patterns` entry** and the comment block above it that argued for indexing the tree. 2. **Restored both tool descriptions to their pre-#164 text, verbatim.** This is the most important part of the change. `search-docs` claimed to cover "the AG-UI protocol pages hosted on the CopilotKit docs site (docs.copilotkit.ai/ag-ui/...)" — a **false claim**, and it is what an LLM reads to decide which tool to call. It now reads: > Search the CopilotKit product documentation (https://docs.copilotkit.ai) — > guides, concepts, quickstarts, API reference, and how-tos for building with > CopilotKit. Use this for CopilotKit usage and configuration questions. NOT > for AG-UI protocol docs (use search-ag-ui-docs) and NOT for source code > (use search-code). This is a semantic search, so prefer performing multiple > queries with different phrases instead of a single long query, until you > find all the context you need. `search-ag-ui-docs` — which #164 softened into "one of two near-identical copies" — is again described as **the** AG-UI documentation, with no mention of a second copy. 3. **`unclaimed_exempt_paths`: stale comment replaced, no exemption added.** #164's comment said `content/ag-ui/` "is deliberately absent from this list and always will be: it is not exempt, it is CLAIMED". That reasoning is obsolete. The directory is gone, so the `unclaimed_content` audit has nothing to walk there and cannot fire either way; an exemption would only blind the audit to whatever lands at that path next. ### Per-file decision on the rest of #164 `git show 298b7fa --stat` lists three files. | File | Decision | Reasoning | |---|---|---| | `deploy/copilotkit-docs.yaml` | **revert the ag-ui parts** | The subject of this PR. Nothing else #164 touched in it. | | `scripts/test-path-filter.ts` | **KEEP, comment corrected** | #164 changed only comments here. One named "three page subtrees (docs/, reference/, ag-ui/)"; now two. Reverting verbatim would restore a comment that was *already* wrong before #164 — it claimed the source path is `content/docs/`, which #159 had widened to `content/`. | | `src/__tests__/copilotkit-docs-config.test.ts` | **KEEP, assertions updated** | Deploy-config coverage barely existed before this file, and that absence is exactly why both of this config's silent failures — the unindexed reference tree, and now this — stayed invisible. Deleting it would restore the blind spot. Its ag-ui cases are inverted (the tree must **not** be claimed) and a third `describe` block is new: what `search-docs` advertises. Its machine-relay block postdates #164 and is untouched. | ## RED → GREEN Harness calls the **shipped** `walkSourceFiles()` and `deriveUrl()` over the **shipped** `deploy/copilotkit-docs.yaml`. No database, no network, no production. The checkout is CopilotKit **`4b7c0d35fd505e981a03cd7d3cba400234b0eb4b`** — the first parent of the deletion merge, i.e. `main` immediately *before* #7092. That commit is required to demonstrate the before-state at all: at any commit after it the files are simply gone, so a red run there would prove nothing about our config. **RED** (config as on `main`): ``` TOTAL enumerated: 962 content/docs/: 682 content/reference/: 184 content/ag-ui/: 96 [PRESENT] .../content/ag-ui/concepts/agents.mdx -> https://docs.copilotkit.ai/ag-ui/concepts/agents [PRESENT] .../content/ag-ui/concepts/architecture.mdx -> https://docs.copilotkit.ai/ag-ui/concepts/architecture [PRESENT] .../content/ag-ui/agentic-protocols.mdx -> https://docs.copilotkit.ai/ag-ui/agentic-protocols [PRESENT] .../content/ag-ui/sdk/js/core/events.mdx -> https://docs.copilotkit.ai/ag-ui/sdk/js/core/events ``` **GREEN** (this branch, same command, same checkout): ``` TOTAL enumerated: 866 content/docs/: 682 content/reference/: 184 content/ag-ui/: 0 [ ABSENT] .../content/ag-ui/concepts/agents.mdx [ ABSENT] .../content/ag-ui/concepts/architecture.mdx [ ABSENT] .../content/ag-ui/agentic-protocols.mdx [ ABSENT] .../content/ag-ui/sdk/js/core/events.mdx ``` **File-count delta: 962 → 866, exactly −96.** The prose and reference counts do not move. ## Negative check: the existing 866 URLs are byte-identical #159 and #164 both came close to breaking the ordered, first-match-wins `url_derivation.strip_prefix`. Removing a pattern must not disturb it. Full `path → URL` manifests for the `docs/` and `reference/` subtrees, before and after: ``` red rows: 866 green rows: 866 diff exit=0, 0 lines cmp: BYTE-IDENTICAL md5 c88778a79e5b9d4da7e5bf34a0a27cbb (both) docs/quickstart.mdx -> https://docs.copilotkit.ai/quickstart reference/hooks/useAgent.mdx -> https://docs.copilotkit.ai/reference/hooks/useAgent ``` **Mutation-tested, so the empty diff is not vacuous.** Swapping the two `strip_prefix` entries so the shorter `content/` prefix wins first — the exact defect this check exists to catch — produces **1,364 differing rows**, every prose page gaining a spurious `/docs` segment (`/quickstart` → `/docs/quickstart`). The check fires. Restoring the config returns the manifest to byte-identical. The new assertions are mutation-tested the same way: against #164's config, **7 of them fail** (4 ag-ui coverage cases, 3 tool-description cases). ## Local gate `npm run build` ✅ · `npx tsc --noEmit` ✅ · `npm test` **198 files / 3,949 tests passed, 0 failed, 1 skipped** ✅ · `node scripts/check-test-shapes.mjs` ✅ (no new violations) · `npx prettier --check` on all three touched files ✅ No pre-existing failure to control for — the suite is fully green. ## Deploying this: a reindex IS required **Merging this config change does not remove already-indexed chunks.** The ~866 ag-ui chunks sitting in the `docs` source stay there until a full walk of that source rewrites it. The chunks will keep being returned, with dying `docs.copilotkit.ai/ag-ui/...` links, until then. #160's `config_fingerprint` should force that walk automatically, since `file_patterns` is folded into the fingerprint. Measured on the two configs: ``` 8274a4799a6d331b97b48a4a74a74cc5 docs source @ origin/main 2bf63ca62d74ba10ad4698363f3c5f7b docs source @ this branch ``` The branch value is *exactly* the pre-#164 fingerprint, so the stored value no longer matches and the orchestrator takes the full-walk path. **How an operator confirms it, after deploy and the next reindex:** 1. `/health` — the `docs` source's document count falls from ~962 back toward **~866**, i.e. down by roughly the ag-ui contribution (**~866 chunks across 96 files**). 2. `search-docs` for something only those pages said (e.g. "AG-UI RunAgentInput", "AG-UI Rust SDK subscriber") returns **no** `docs.copilotkit.ai/ag-ui/...` URLs; `search-ag-ui-docs` answers the same query with `docs.ag-ui.com` links. 3. The reindex audit reports no new unclaimed cluster for CopilotKit/CopilotKit. If the count does not move, the fingerprint path did not fire and a manual full reindex of the `docs` source is the fallback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is wrong
showcase/shell-docs/src/content/ag-ui/in CopilotKit/CopilotKit is 96.mdxfiles that are live documentation pages — served athttps://docs.copilotkit.ai/ag-ui/<slug>bysrc/app/ag-ui/[[...slug]], and all 96 are in the production sitemap. No configured source claimed a single one of them. Thedocssource already walked their parent directory (src/content/, widened in #159), but itsfile_patternsnamed only thedocs/andreference/subtrees.#163's new
unclaimed_contentcheck found this on its first real run and deliberately left it unexempted, pending a decision. The decision: index them here — CopilotKit includes AG-UI.Extend the existing source, not a new one
A
type: searchtool takes exactly onesource, so a separatecopilotkit-ag-ui-docssource could not feedsearch-docs— it would need a third docs tool, sitting between two that already confuse each other (search-docsandsearch-ag-ui-docs). That is the opposite of "CopilotKit includes AG-UI". The tree also needs no different walk root, no differentbase_url, no different derivation, and the webhookpath_triggersfordocsalready coversrc/content/. One morefile_patternsentry is the whole change.Honest note on overlap: 94 of these 96 files also exist in
ag-ui-protocol/ag-ui'sdocs/tree, which theag-ui-docssource already indexes — mostly the same prose, drifted in formatting. They are indexed twice on purpose, because the two copies hand back different links:ag-ui-docsanswers withdocs.ag-ui.com/..., this one with thedocs.copilotkit.ai/ag-ui/...page a CopilotKit reader is actually on. Both tool descriptions now say so, so an agent can route deliberately instead of guessing.No change to
url_derivation— and proof that none was neededThe ordered
strip_prefixlist is first-match-wins, and getting it wrong here would mint plausible URLs that 404 — a search result that lies, which is worse than no result.ag-ui/is not undercontent/docs/, so it falls through to thecontent/prefix and keeps its directory. Verified against the real route, not by reading the YAML.Red → green (real enumeration + real URL derivation, fresh checkout
7a36707ab, no DB, no production)Harness calls the shipped
walkSourceFiles()andderiveUrl()over the real config.RED (config as on
main):GREEN (this branch):
URL correctness: 96/96
Every one of the 96 derived URLs was checked against the production sitemap (
curl -s https://docs.copilotkit.ai/sitemap.xml, 3791 locs):/ag-uientry is/ag-uiitself, the overview page with no backing file (its body is rendered inline byOverviewContent), correctly not derived./ag-ui/concepts/agents-definitely-not-a-page→ 404): 88 return HTTP 200, 8 return HTTP 500.The 8 are
development/updates,sdk/dart/client/overview, and sixsdk/rust/*pages. They are not a derivation error: an invented slug on the same route returns a clean 404, these return 500 after the route matched, they are in the sitemap, and they 500 identically before and after this change (nothing here touches the docs site). That is a pre-existing render fault on docs.copilotkit.ai and worth a separate issue on CopilotKit/CopilotKit. Indexing them is still right — the content is real and the links become good the moment the site is fixed.No regression: the existing 866 URLs are byte-identical
Full
path → URLmanifests for thedocs/andreference/subtrees, before and after, diffed:docs/quickstart.mdx → /quickstartandreference/hooks/useAgent.mdx → /reference/hooks/useAgentboth unchanged.The
unclaimed_contentfinding clears#163's check, run against the updated config over the same checkouts:
showcase/shell-docs/src/content/ag-ui .mdx x96middlewares .ts x34middlewares .ts x34(unchanged, unrelated)The audit that found this goes quiet, and no new cluster appears.
Regression guard
src/__tests__/copilotkit-docs-config.test.tsis new and reads the shippeddeploy/copilotkit-docs.yaml, asserting through the realmatchesPatternsandderiveUrlwhich files thedocssource claims and what URL each derives. Both of this config's silent failures — the reference tree, and now ag-ui — were invisible to every existing unit test precisely because they lived in the YAML rather than in a fixture. Committed red (4 failing coverage cases), green after the config change.Deploying this: a reindex is needed, and it should fire by itself
Indexing the pages requires a full walk of the
docssource — merging the config does not move content on its own. #160'sconfig_fingerprintshould force that automatically, becausefile_patternsis one of the fields folded into the fingerprint. Measured on the two configs:The stored fingerprint no longer matches, so the orchestrator's acquisition branch takes the full-walk path instead of diffing HEAD against itself.
How an operator confirms it landed, after deploy and the next reindex:
/health— thedocssource's document count moves from ~866 toward ~962.search-docsfor something only these pages say (e.g. "AG-UI RunAgentInput", "AG-UI Rust SDK subscriber") returns results withdocs.copilotkit.ai/ag-ui/...URLs.If the count does not move, the fingerprint path did not fire and a manual full reindex of the
docssource is the fallback.Local gate
npm run build✅ ·npx tsc --noEmit✅ ·npm test191 files / 3730 tests passed, 0 failed ✅ ·node scripts/check-test-shapes.mjs✅ ·npx prettier --checkon all three touched files ✅