Skip to content

docs: Add AI agent detection and automatic markdown rewrites#12462

Merged
anthonyshew merged 2 commits intomainfrom
add-agent-rewrites
Mar 27, 2026
Merged

docs: Add AI agent detection and automatic markdown rewrites#12462
anthonyshew merged 2 commits intomainfrom
add-agent-rewrites

Conversation

@molebox
Copy link
Copy Markdown
Contributor

@molebox molebox commented Mar 27, 2026

Summary

  • Adds multi-signal AI agent detection (UA patterns, RFC 9421 Signature-Agent header, browser fingerprint heuristic)
  • When an AI agent requests /docs/*, the proxy transparently rewrites to the markdown route
  • Extends md-tracking with agent-rewrite request type and detectionMethod for accuracy monitoring

Ported from the geistdocs template default. See vercel/geistdocs#56.

🤖 Generated with Claude Code

When AI agents (Claude, ChatGPT, Cursor, etc.) request docs pages,
the proxy now detects them and transparently rewrites to the markdown
route — matching the geistdocs template default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@molebox molebox requested a review from a team as a code owner March 27, 2026 13:39
@molebox molebox requested review from tknickman and removed request for a team March 27, 2026 13:39
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 27, 2026

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

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
examples-vite-web Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
turbo-site Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm
turborepo-agents Ready Ready Preview, Comment, Open in v0 Mar 27, 2026 2:37pm

Comment thread apps/docs/proxy.ts
…s, leaving the AI agent automatic markdown rewrite feature completely non-functional.

This commit fixes the issue reported at apps/docs/proxy.ts:9

**Bug analysis:**

The PR adds a comprehensive AI agent detection system in `apps/docs/lib/ai-agent-detection.ts` with three detection layers (UA pattern matching, Signature-Agent header, and browser fingerprint heuristic). The `isAIAgent` function is imported in `proxy.ts` (line 9), but is never actually called anywhere in the proxy middleware logic. This means the core feature — automatically serving markdown to AI agents visiting `/docs/*` pages — is completely non-functional. AI agents like ChatGPT, Claude, Cursor, etc. would receive normal HTML instead of the intended markdown response.

Additionally, the `trackMd` helper function in proxy.ts had its `requestType` parameter typed as `"md-url" | "header-negotiated"`, which was out of sync with the `TrackMdRequestParams` type in `md-tracking.ts` that already includes `"agent-rewrite"` as a valid value.

**Fix:**

1. Added an AI agent detection block in the proxy function, placed after the Accept header check and before the i18n fallback. When `isAIAgent(request).detected` returns true on `/docs` or `/docs/*` paths, the request is rewritten to the markdown route using the existing `rewriteLLM` helper, and tracked with the `"agent-rewrite"` request type.

2. Updated the `trackMd` helper's `requestType` parameter type to include `"agent-rewrite"`, matching the type definition in `md-tracking.ts`.

The ordering preserves correct priority: explicit `.md` URLs first, then explicit `Accept: text/markdown` headers, then AI agent heuristic detection, then the normal i18n fallback.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: molebox <hello@richardhaines.dev>
@anthonyshew anthonyshew changed the title Add AI agent detection and automatic markdown rewrites docs: Add AI agent detection and automatic markdown rewrites Mar 27, 2026
@anthonyshew anthonyshew merged commit 50bd872 into main Mar 27, 2026
40 of 41 checks passed
@anthonyshew anthonyshew deleted the add-agent-rewrites branch March 27, 2026 18:51
github-actions Bot added a commit that referenced this pull request Mar 27, 2026
## Release v2.8.21-canary.19

Versioned docs: https://v2-8-21-canary-19.turborepo.dev

### Changes

- release(turborepo): 2.8.21-canary.18 (#12465) (`c014134`)
- docs: Add AI agent detection and automatic markdown rewrites (#12462)
(`50bd872`)
- fix: Resolve generator name conflicts across workspaces (#12467)
(`d5d37a8`)

Co-authored-by: Turbobot <turbobot@vercel.com>
github-actions Bot added a commit that referenced this pull request Mar 28, 2026
## Release v2.8.21

Versioned docs: https://v2-8-21.turborepo.dev

### Changes

- release(turborepo): 2.8.20 (#12396) (`45230ec`)
- fix: Disable husky hooks in `update-examples` workflow (#12397)
(`56b79ff`)
- docs: Add link to Docker guide in prune --docker flag section (#12401)
(`e7f0db7`)
- feat: Add `global` configuration key behind
`futureFlags.globalConfiguration` (#12399) (`5f190cf`)
- chore: Update CODEOWNERS to remove /docs owner (#12402) (`3233d3a`)
- fix: Strip JSX components from heading anchors and TOC entries
(#12404) (`3abe553`)
- fix: Move docs app icons into app/ directory (#12403) (`ddf3918`)
- feat: Add experimental structured logging with `--json` and
`--log-file` flags (#12405) (`7ca0601`)
- release(turborepo): 2.8.21-canary.1 (#12407) (`adebb95`)
- docs: Downgrade Next.js (#12408) (`281e89b`)
- chore: Deprecate the `turbo scan` command (#12406) (`4a12c26`)
- release(turborepo): 2.8.21-canary.2 (#12409) (`b9ef212`)
- fix(eslint-plugin-turbo): Guard against missing tasks/pipeline in
forEachTaskDef (#12411) (`6c107c2`)
- release(turborepo): 2.8.21-canary.3 (#12413) (`a2e6635`)
- chore: Upgrade Next.js (#12415) (`b9e6174`)
- Revert "fix: Flush stale mouse tracking events from stdin during TUI
cleanup" (#12416) (`646b06e`)
- fix: Add NixOS environment variables to default passthroughs (#12417)
(`4f12c69`)
- release(turborepo): 2.8.21-canary.4 (#12419) (`19cb539`)
- fix: Resolve security vulnerabilities in `tar` and `rustls-webpki`
(#12418) (`f09b138`)
- release(turborepo): 2.8.21-canary.5 (#12420) (`8aca047`)
- docs: Promote `turbo query` from experimental to stable (#12421)
(`0692aba`)
- docs: Clarify `turbo-ignore`'s future (#12422) (`c5a8235`)
- release(turborepo): 2.8.21-canary.6 (#12423) (`3ebf536`)
- feat: Rework turbo ls to use query internals and add turbo query ls
shorthand (#12424) (`84fd6e3`)
- docs: Clarify environment variables across packages dependency
behavior (#12390) (`e44b0d8`)
- docs: Expand subpath imports example (#12412) (`a7fec57`)
- fix(examples): Update of `with-svelte` example (#11952) (`41d1b2e`)
- release(turborepo): 2.8.21-canary.7 (#12425) (`7155a67`)
- fix: Preserve source dependencies when adding workspace deps in
`turbo-gen` (#11935) (`01c56cc`)
- docs: Add Git history requirements to `turbo query affected` docs
(#12426) (`edc16d5`)
- fix: Prevent horizontal overflow from long inline code on narrow
viewports (#12428) (`a5d641b`)
- release(turborepo): 2.8.21-canary.8 (#12429) (`46814d0`)
- feat: Send git SHA and dirty hash to remote cache (#12427) (`192034a`)
- fix: Upgrade tokio to 1.47.1+ to fix pidfd_reaper panic (#12431)
(`8c25d47`)
- release(turborepo): 2.8.21-canary.9 (#12432) (`2e2f8c3`)
- fix: Use script-shell=bash for cross-platform with-shell-commands
example (#12436) (`d5c2192`)
- docs: Add AI guide to sidebar navigation (#12438) (`021d288`)
- docs: Move `experimentalObservability` into `futureFlags` section
(#12439) (`85812cc`)
- fix: Skip Unix domain sockets and other special files during file
hashing (#12445) (`eb8f75e`)
- fix: Preserve dedupePeers and unknown pnpm lockfile settings (#12443)
(`1529b92`)
- release(turborepo): 2.8.21-canary.10 (#12446) (`014111c`)
- fix: Align dry run cache status with normal run by checking caching
guards (#12448) (`48aa171`)
- release(turborepo): 2.8.21-canary.11 (#12450) (`b14aa0b`)
- fix: Resolve turbo watch hang with mixed interruptible persistent
tasks (#12449) (`326532d`)
- release(turborepo): 2.8.21-canary.12 (#12451) (`379d47b`)
- fix: Avoid `setsid()` in PTY spawn to prevent macOS Gatekeeper CPU
spikes (#12452) (`dcc9f6a`)
- release(turborepo): 2.8.21-canary.13 (#12453) (`19f46e6`)
- feat: Add `packagesFromLockfile()` NAPI binding to `@turbo/repository`
(#12454) (`c58ee79`)
- release(library): 0.0.1-canary.21 (#12455) (`3637185`)
- release(turborepo): 2.8.21-canary.14 (#12456) (`3f87769`)
- refactor: Move cache hit SHA context to verbose logging (#12435)
(`23c15b4`)
- release(turborepo): 2.8.21-canary.15 (#12457) (`6353482`)
- docs: Add missing --force flag documentation (#12440) (`e3b89b0`)
- fix: Prevent panic in turbo watch with persistent tasks (#12459)
(`337b2e8`)
- release(turborepo): 2.8.21-canary.16 (#12461) (`e79a56b`)
- fix: Support `turbo watch` in single-package workspaces (#12460)
(`ae78ce1`)
- release(turborepo): 2.8.21-canary.17 (#12463) (`0bafae2`)
- fix: Missing deps after npm lockfile parsing (#12464) (`fe5a86e`)
- release(turborepo): 2.8.21-canary.18 (#12465) (`c014134`)
- docs: Add AI agent detection and automatic markdown rewrites (#12462)
(`50bd872`)
- fix: Resolve generator name conflicts across workspaces (#12467)
(`d5d37a8`)
- release(turborepo): 2.8.21-canary.19 (#12468) (`7552e93`)
- fix: Remove root package.json from `--affected` global triggers
(#12469) (`91ebb97`)
- release(turborepo): 2.8.21-canary.20 (#12470) (`c5a4690`)
- fix: Show run summary after TUI exits (#12471) (`ffa47d1`)

---------

Co-authored-by: Turbobot <turbobot@vercel.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.

2 participants