Skip to content

fix(docs): sanitize emoji shortcodes in generated SDK docs - #631

Merged
christineschen merged 5 commits into
mainfrom
devin/1786394635-fix-docs-emoji-shortcodes
Oct 6, 2026
Merged

christineschen merged 5 commits into
mainfrom
devin/1786394635-fix-docs-emoji-shortcodes

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Parameters tables on openrouter.ai/docs/client-sdks/python/** render :heavy_minus_sign: as literal text. Speakeasy emits GitHub-flavored emoji shortcodes; GitHub expands them, Mintlify does not, and the docs site mounts this repo's docs/ tree directly through a sourceRef entry in openrouter-web's projects/docs/docs.json.

Editing the generated MDX alone would not hold, because the next speakeasy run rewrites it. So this PR pairs a one-time pass with a post-generation step:

  1. scripts/sanitize-docs-emoji.sh rewrites docs/**/*.mdx in place:

    :heavy_check_mark: -> ✅
    :heavy_minus_sign: -> ➖
    :warning:          -> ⚠️
    

    Scoped to docs/ only. README.md, README-PYPI.md, and the workflow YAML keep their shortcodes, which render correctly on GitHub and PyPI.

  2. The script runs in docs-nav.yaml immediately before gen-docs-nav.sh, the existing post-generation docs step.

  3. That workflow's path filter widens from docs/sdks/** to docs/**. The shortcodes live throughout docs/components, docs/operations, and docs/errors as well, and the old filter would skip a generation PR that touched only those trees.

    Regeneration PR chore: 🐝 Update SDK - Generate (spec change merged) 1.1.41 #633 landed on main while this PR was open and is exactly that case: its only docs change was docs/components/outputfusionservertoolitem.mdx, so Docs navigation was skipped while PR Validation ran. The widened filter is what closes it.

  4. The one-time pass: 1,429 files, 7,719 shortcodes replaced (rebased onto main on 2026-10-03).

  5. scripts/sanitize-docs-emoji.sh ends with a residual guard: if any standalone :[a-z][a-z0-9_+-]*: token (not preceded or followed by a word character or :) survives the substitution, it prints the file and line and exits non-zero, so a new shortcode Speakeasy starts emitting fails at generation time instead of shipping as literal text. Zero matches remain today, so the guard passes on current output.

Verification

  • Zero shortcode matches remain under docs/; the six :warning: occurrences in workflow YAML are untouched.
  • Re-running the script produces no diff.

Rebase (2026-10-03)

Reopened after Pylon #4403 reported the same bug from a customer. The vendor's suggested script only rewrites description fields in OpenAPI files, and the spec has no shortcodes in it, so it doesn't fix this. The shortcodes come from Speakeasy's docs templates.

  • Rebuilt on current main: same .github and scripts changes, then the one-time pass was re-run fresh instead of replaying the old generated-docs commits.

  • The residual guard now ignores URN-style colon runs. New OAuth docs on main contain urn:ietf:params:oauth:token-type:jwt, which the old pattern flagged as :params: etc.:

    - grep -HnE ':[a-z][a-z0-9_+-]*:'
    + grep -HnP '(?<![\w:]):[a-z][a-z0-9_+-]*:(?![\w:])'

Link to Devin session: https://openrouter.devinenterprise.com/sessions/1589ee9058c442958d427eac4e989f11
Open in Devin Desktop: https://openrouter.devinenterprise.com/desktop/session/1589ee9058c442958d427eac4e989f11?variant=devin

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Original prompt from jason.schrader

SYSTEM:
=== BEGIN THREAD HISTORY (in #gtm-agents) ===
<most_recent_message>
Jason Schrader (U0BLD9PFY30) [ts=1786394064.313869]: @Devin I found a few spots in our docs where emoji shortcodes are listed in text form and not displayed in tables, e.g. ✔️ renders as :heavy_check_mark: in the table instead of the actual icon. Let's identify the root cause then create a PR to get it all fixed up. From what I see, it's all under a table in the "Parameters" section of the different Client SDK files.
<https://openrouter.ai/docs/client-sdks/typescript/sdks/files/README|openrouter.ai/docs/…/README>
<https://openrouter.ai/docs/client-sdks/python/sdks/benchmarks/README|openrouter.ai/docs/…/README>
<https://openrouter.ai/docs/client-sdks/go/sdks/betaanalytics/README|openrouter.ai/docs/…/README>
</most_recent_message>
=== END THREAD HISTORY ===
Channel ID: C0AD8UNM761
Thread URL: https://openrouter.slack.com/archives/C0AD8UNM761/p1786394064313869?thread_ts=1786394064.313869&amp;cid=C0AD8UNM761

The latest message is the one right above that tagged you. The <most_recent_message> is the message that you should use to guide your goals + task for this session, and you should use the rest of the slack thread as context.
A [ts=...] marker on a Slack message is that message's timestamp. To act on a specific message with the slack tool (e.g. adding an emoji reaction via the reaction command), pass that value as timestamp along with the Channel ID — no extra lookup call is needed.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@mintlify

mintlify Bot commented Aug 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 10, 2026, 9:23 PM

@mintlify

mintlify Bot commented Aug 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 10, 2026, 9:23 PM

@mintlify

mintlify Bot commented Aug 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 10, 2026, 9:23 PM

@mintlify

mintlify Bot commented Aug 10, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 10, 2026, 9:23 PM

perry-the-pr-reviewer[bot]

This comment was marked as outdated.

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 11, 2026, 1:23 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 11, 2026, 1:23 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 11, 2026, 3:26 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 11, 2026, 3:26 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 11, 2026, 3:26 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 11, 2026, 3:26 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-production 🟡 Building – Aug 11, 2026, 4:23 AM

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
openrouter-staging 🟡 Building – Aug 11, 2026, 4:23 AM

perry-the-pr-reviewer[bot]

This comment was marked as outdated.

@jason-schrader-openrouter

Copy link
Copy Markdown

Closing in favor of coordination with our vendor

@devin-ai-integration devin-ai-integration Bot reopened this Oct 6, 2026
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1786394635-fix-docs-emoji-shortcodes branch from d2ab1ef to 40f5e23 Compare October 6, 2026 16:04
@mintlify

mintlify Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
openrouter-production 🟢 Ready View Preview Oct 6, 2026, 6:12 PM

@mintlify

mintlify Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
openrouter-staging 🟢 Ready View Preview Oct 6, 2026, 6:14 PM

@perry-the-pr-reviewer perry-the-pr-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perry's Review

Verdict: 💬 Comments / questions — the review is LGTM (both prior findings verified fixed; probe-tested, idempotent, CI green). Posted as a comment rather than an approval because the maintainer GitHub App on OpenRouterTeam currently lacks pull_requests:write, so the approval gate cannot carry the maintainer identity. A maintainer should re-approve once the permission is granted.
Risk: 🟢 Low

Findings, verification & risk assessment

Third-round review on 40f5e23. The prior suggestion (future-proof against unmapped Speakeasy shortcodes) and question (guard regex vs. fenced code blocks / URN-style colons) are both resolved, the script is correct and idempotent, and CI is green (gen-docs-nav SUCCESS, validate SUCCESS).

Prior findings — resolved

  1. Future-proofing against new Speakeasy emoji — the residual guard now fails the workflow (exit 1, file + line printed) if any standalone :word: shortcode survives the substitution, so a newly emitted shortcode is caught at generation time instead of shipping as literal text.
  2. Guard false positives — the regex was tightened to (?!...):(?![\w:]) lookarounds ((?<![\w:]):[a-z][a-z0-9_+-]*:(?![\w:])), which correctly ignores URN-style colon runs such as urn:ietf:params:oauth:token-type:jwt in generated docs.

What was verified this round

  • Sanitize script: identical to the approved pattern in the sibling SDKs — set -euo pipefail, repo-root resolution, docs/ existence check, scoped to docs/**/*.mdx, idempotent (re-run on the branch's docs tree produces zero diff), with a probe-tested guard: an injected unmapped :sparkles: shortcode correctly fails, a URN-only line correctly passes.
  • Path-filter widening docs/sdks/** → docs/** plus the script path is justified: regeneration PR #633 on main touched only one component page outside docs/sdks/, which the old filter would have skipped entirely.
  • Sanitize ordering in docs-nav.yaml is correct: sanitize runs before gen-docs-nav.sh so nav regeneration sees clean files.
  • README/README-PYPI diffs (example call changes) are part of the already-merged Speakeasy regeneration history on the branch, not authored logic.

Delta scope

The three PR-author commits (all Devin AI) are: the original sanitize pass, the URN-guard regex fix, and the docs rewrite applying the replacements. The wide src/ churn in the file list belongs to regenerated-spec commits already on main and is not part of this review's delta.

Estimated impact: worst case is a false-positive failure of the residual guard on a future generated-docs pattern that looks like a :word: shortcode — a one-line mapping or content fix in the docs generation workflow, with no runtime, data, or security surface affected.

Risk assessment & full factor table
Dimension Severity Risk Reasoning
Implementation risk 🟩 Low Script and workflow wiring are correct, idempotent, and probe-tested in review.
Premise risk 🟩 Low Post-generation sanitization with a fail-fast residual guard is the right design.
Estimated impact 🟩 Low Worst case is a contained CI failure in the docs pipeline, trivially correctable.
Risk Factor Severity Risk Reasoning
Reversibility 🟩 Low Revert restores the prior state; regeneration recreates output.
Detectability 🟩 Low The residual guard fails CI on any unmapped shortcode immediately.
Blast radius 🟩 Low Confined to the docs subtree mounted into the docs site.
Data integrity None No persisted state is touched.
Financial exposure None No billing surface.
Security and privacy exposure None No credential or auth path changed.
Propagation 🟩 Low Only the docs rendering pipeline consumes the output.
Availability None No serving path affected.
Recovery cost 🟩 Low A revert or one-line mapping fixes any issue.
Time to correct 🟩 Low Guard failures surface in the same workflow run.

Comment thread scripts/sanitize-docs-emoji.sh Outdated
…docs-emoji-shortcodes

# Conflicts:
#	docs/operations/createkeysdata.mdx
#	docs/operations/createkeysresponse.mdx
#	docs/operations/getkeydata.mdx
#	docs/operations/getkeyresponse.mdx
#	docs/operations/listdata.mdx
#	docs/operations/updatekeysdata.mdx
#	docs/operations/updatekeysresponse.mdx
@christineschen
christineschen merged commit 0748fd2 into main Oct 6, 2026
2 checks passed
@christineschen
christineschen deleted the devin/1786394635-fix-docs-emoji-shortcodes branch October 6, 2026 18:55

This branch was successfully deployed

1 active deployment
staging - docs — 079c5cdd Deployed Oct 6, 2026 by mintlify[bot]
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