Skip to content

improvement(landing): search-length titles, model comparison pages, and free model tools - #9184

Open
waleedlatif1 wants to merge 8 commits into
stagingfrom
improvement/library-seo-titles
Open

waleedlatif1 wants to merge 8 commits into
stagingfrom
improvement/library-seo-titles

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Landing SEO work, folded into one PR:

Library search titles

  • Posts used one title for the H1, <title>, Open Graph and JSON-LD; with the " | Sim" suffix most library titles ran past 60 characters and were truncated in search results
  • Optional seoTitle / seoDescription frontmatter now drive <title>, the meta description and Open Graph/X copy; the H1, cards, feeds and JSON-LD keep title / description
  • check:library-content enforces the search title (suffix included) at 60 characters and the search description at 160 for every published post. No baseline, so parallel content PRs never conflict on one
  • Every current offender (library, blog, changelog) got a search title or description written from the article; counts and named tools were checked against each article
  • Author pages rendered "Name | Sim Library | Sim"; the title template already adds the brand

Model catalog

  • Provider pages target API pricing searches ("Anthropic (Claude) API Pricing & Models")
  • /models/context-windows compares context window, max output and price for every current model; retired models are excluded
  • 47 curated /models/compare/[pair] pages with a data-derived verdict priced at standard per-call rates through resolveModelTokenPricing; the build fails if a curated model is retired or removed

Free tools

  • /models/pricing-calculator prices requests and monthly volume per model with the exact tier and cached-input rules billing uses: the priced branch of priceModelUsage moved unchanged into a client-safe priceTokenUsage
  • /models/token-counter counts tokens in the browser: exact for OpenAI encodings (js-tiktoken loads on first input, one encode per encoding), labelled estimates for other providers; pasted text never leaves the page

Type of Change

  • New feature
  • Improvement

Testing

  • check:library-content passes (129 posts). New fixture test for the search length rules fails when the suffix is dropped from the count, when > becomes >=, and when drafts stop being exempt
  • test-landing-seo-e2e.ts: library seoTitle/seoDescription served in <title>, og:title and meta description with the H1 unchanged; every model page (including all compare pages in the sitemap) has a unique title ≤60 characters with one " | Sim" and a self canonical; unknown compare pairs 404; the token counter's initial HTML and scripts contain no js-tiktoken code
  • Pricing and tokenization tests: providers/pricing, cost-policy, lib/tokenization, provider usage tests; billing extraction verified line by line as unchanged
  • check:file-names, check:source-conventions, check:comment-hygiene, check:client-boundary, check:utils, check:unused-exports, biome

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 17, 2026 10:15pm UTC

Request Review

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 18 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread scripts/check-library-content.baseline.json Outdated
@greptile-apps

greptile-apps Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues remain.

Summary

The PR adds shorter search titles, model comparison pages, a pricing calculator, and a browser-only token counter.

  • Article search titles and descriptions can differ from the words readers see on the page.
  • Model pages and tools are easier to find from the model directory.
  • A context-window page compares current models by capacity and price.
  • Curated model pairs get side-by-side comparison pages with data-based verdicts.
  • A pricing calculator estimates model costs from token use and request volume.
  • A browser token counter counts pasted text without putting it in the URL.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Catalog[Model pricing] --> Shared[priceTokenUsage]
  Calculator[Calculator inputs] --> Shared
  Usage[Recorded model usage] --> Policy[priceModelUsage]
  Policy --> Shared
  Shared --> Estimate[Displayed estimate]
  Shared --> Cost[Recorded cost]
Loading

Reviews (4) · Last reviewed commit: "fix(models): format catalog dates in UTC..." · Reviewed by Greptile

Comment thread scripts/check-library-content.ts Outdated
@waleedlatif1 waleedlatif1 changed the title improvement(library): give posts search titles and descriptions that fit search results improvement(landing): search-length titles, model comparison pages, and free model tools Oct 17, 2026
@waleedlatif1
waleedlatif1 force-pushed the improvement/library-seo-titles branch from 9074dc0 to 4828f1a Compare October 17, 2026 21:48
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 141 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/app/(landing)/models/context-windows.ts Outdated
Comment thread apps/sim/app/(landing)/models/(shell)/token-counter/page.tsx Outdated
Comment thread apps/sim/app/(landing)/models/(shell)/compare/[pair]/page.tsx Outdated
Comment thread apps/sim/app/(landing)/models/components/model-tool-link/model-tool-link.tsx Outdated
Comment thread apps/sim/app/(landing)/models/(shell)/compare/[pair]/page.tsx Outdated
Comment thread apps/sim/app/(landing)/models/comparisons.ts
Comment thread apps/sim/app/(landing)/models/(shell)/compare/[pair]/page.tsx Outdated
Comment thread apps/sim/app/(landing)/models/(shell)/compare/[pair]/page.tsx
…fit search results

- Optional seoTitle/seoDescription frontmatter drive <title>, meta description, and Open Graph/X copy; the H1, cards, feeds, and JSON-LD keep title/description
- check:library-content ratchets search title (with the " | Sim" suffix) to 60 characters and description to 160, with a shrink-only baseline
- Rewrite search titles and descriptions for 12 library pages to match the queries they rank for
- Author pages no longer render the brand twice in their title
…ict check

- Drop the baseline so parallel content PRs never conflict on it; every published post now fits
- Add search titles and descriptions to the remaining library, blog, and changelog posts
- /models/pricing-calculator prices requests and monthly volume per model with the same tier and cached-input rules billing uses (priceTokenUsage, extracted unchanged from the billing cost policy)
- /models/token-counter counts tokens in the browser: exact for OpenAI encodings (js-tiktoken loaded on first input), labelled estimates for other providers; pasted text never leaves the page
- Both pages link from /models and appear in the sitemap and llms.txt
…nd model-vs-model pages

- Provider pages target API pricing searches ("Anthropic (Claude) API Pricing & Models")
- /models/context-windows compares context window, max output, and price for every current model; retired models are excluded
- 47 curated /models/compare pages with a data-derived verdict priced at standard per-call rates; the build fails if a curated model is retired or removed
…checks

- Model page chip links use ChipLink's outline variant instead of restyling it
- ComparisonLinks gets its own component folder
- One E2E check covers every model page's search title budget and canonical; a fixture test covers the search length rules
…e structure

- Context windows, the pricing tools, and comparisons skip evaluation-only models (native state and questions, not prompts)
- Token counter labels an OpenAI count as an estimate when exact encoding fails
- New model pages: desktop-first breakpoints, named props interfaces, section ids and labels, sr-only hero summaries; TSDoc on exported comparison helpers
@waleedlatif1
waleedlatif1 force-pushed the improvement/library-seo-titles branch from 4828f1a to 3c1ffd1 Compare October 17, 2026 22:06
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 141 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/app/(landing)/models/(shell)/compare/[pair]/page.tsx
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 141 files

Confidence score: 4/5

  • In apps/sim/app/(landing)/models/utils.ts, getLargestContextProviderModel can select an evaluation model, causing the provider FAQ to name jev-latest as the largest-context model. Exclude evaluation models from this selection.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/sim/app/(landing)/models/utils.ts">

<violation number="1" location="apps/sim/app/(landing)/models/utils.ts:895">
P2: `getLargestContextProviderModel` can select an evaluation model. The TypeSafe `jev-*` models have `capabilities.evaluation` and a 64k window, so the provider FAQ names `jev-latest` as the largest-context model. The context-windows page excludes evaluation models, so the FAQ contradicts the ranking its docstring says it matches. Filter with `isPromptModel` here.

(Based on your team's feedback about excluding evaluation models from context-window rankings.)</violation>
</file>

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

* by {@link compareByContextWindow} so provider FAQs agree with the context-window comparison.
*/
function getLargestContextProviderModel(provider: CatalogProvider): CatalogModel | null {
const candidates = provider.models.filter((model) => !model.retired && model.contextWindow)

@cubic-dev-ai cubic-dev-ai Bot Oct 17, 2026 •

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.

P2: getLargestContextProviderModel can select an evaluation model. The TypeSafe jev-* models have capabilities.evaluation and a 64k window, so the provider FAQ names jev-latest as the largest-context model. The context-windows page excludes evaluation models, so the FAQ contradicts the ranking its docstring says it matches. Filter with isPromptModel here.

(Based on your team's feedback about excluding evaluation models from context-window rankings.)

View Feedback

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At apps/sim/app/(landing)/models/utils.ts, line 895:

<comment>`getLargestContextProviderModel` can select an evaluation model. The TypeSafe `jev-*` models have `capabilities.evaluation` and a 64k window, so the provider FAQ names `jev-latest` as the largest-context model. The context-windows page excludes evaluation models, so the FAQ contradicts the ranking its docstring says it matches. Filter with `isPromptModel` here.

(Based on your team's feedback about excluding evaluation models from context-window rankings.) </comment>

<file context>
@@ -828,9 +874,55 @@ export function getCheapestProviderModel(provider: CatalogProvider): CatalogMode
+ * by {@link compareByContextWindow} so provider FAQs agree with the context-window comparison.
+ */
+function getLargestContextProviderModel(provider: CatalogProvider): CatalogModel | null {
+  const candidates = provider.models.filter((model) => !model.retired && model.contextWindow)
+  if (candidates.length === 0) return null
+  return candidates.reduce((best, model) =>
</file context>
Suggested change
const candidates = provider.models.filter((model) => !model.retired && model.contextWindow)
const candidates = provider.models.filter(
(model) => isPromptModel(model) && !model.retired && model.contextWindow
)
Fix with cubic

This branch was previously deployed

1 inactive deployment
Preview — d4ed3897 Deployed Oct 17, 2026 by vercel[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.

1 participant