Skip to content

feat(ai): position landing page as the headless agent framework - #1080

Merged
AlemTuzlak merged 4 commits into
mainfrom
ai-landing-headless-agent-copy
Jul 30, 2026
Merged

feat(ai): position landing page as the headless agent framework#1080
AlemTuzlak merged 4 commits into
mainfrom
ai-landing-headless-agent-copy

Conversation

@AlemTuzlak

@AlemTuzlak AlemTuzlak commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What

Revamps the TanStack AI landing copy to position TanStack AI as the headless agent framework — not tied to any specific stack, bring your own everything.

The old copy described a generic "AI SDK with a unified interface across multiple providers." It never used the word agent, and it omitted most of what the repo actually ships. I read origin/main of TanStack/ai and rewrote against the real feature set.

Features the old copy never mentioned

Code Mode (LLM writes a TypeScript program, executed in a V8 isolate / QuickJS WASM / Cloudflare Worker), coding-agent harnesses (Claude Code, Codex, OpenCode, Grok Build, plus any ACP agent, across local-process / Docker / Daytona / Vercel / Sprites / Cloudflare sandboxes), interrupts that pause and resume on a stateless server, memoryMiddleware, persistence with resumable streams, MCP and MCP Apps widgets, locks, Agent Skills, and the Bedrock and Mistral adapters.

Changes

HeroThe headless agent framework. Bring your own stack. The subhead names the loop's parts and real counts instead of gesturing at them.

Section 1 retitled from "typed tools" to the agent loop: the chat() cycle, composable (state) => boolean stop strategies, and needsApproval interrupts that resume exactly where they stopped with no database.

Section 2 — names all eleven official adapters plus openaiCompatible, and makes the per-model narrowing claim concrete (openaiText('gpt-5.5'); passing an image to a text-only model fails at compile time). OpenRouter now leads the provider workbench, matching the docs' recommended adapter.

Section 3 — AG-UI end to end versus a proprietary format with a translation layer, and the six supported transports.

New section — "Sandboxes, code mode, MCP, memory. Shipped, not planned." Four rows with real package names.

Modalities — adds summarize, music via generateAudio, word timestamps and diarization, and the async video job lifecycle. ModalityRail is generalized into FeatureRail and reused by both rails.

Hero graph — eight client bindings on a 4×2 grid; the server/runtime row now shuffles so Python and Go read as first-class AG-UI targets, with provider curves and the runtime tile following the active one; the TanStack AI Client node drops its redundant AG-UI sub-label and the server node reads SERVER rather than TYPESCRIPT.

Light-mode contrast fix — the shared --landing-accent-ink for the data category is pure #000000, so black text sat on mid-orange in the TanStack pills and user chat bubbles. Those two now use white text on a darkened accent fill. --landing-accent-ink itself is untouched, since it is shared with every other data-category landing page.

Angular registered@tanstack/ai-angular is published (0.3.1) and getting-started/quick-start-angular exists upstream, but neither was wired into the site config. tests/ai-framework-doc-links.test.ts hardcodes the expected list, so it is updated to match.

All prose avoids em-dashes.

Notes

  • Octane is named in prose and in the hero graph, but not in the framework picker. Its bindings ship as @octanejs/tanstack-ai (0.0.15) rather than a @tanstack package, and adding it to the picker needs an octane entry in the Framework union plus an octane-logo.svg that does not exist in this repo yet.
  • tests/local-repo-path.test.ts fails on this branch, and also on clean main. It asserts POSIX paths (/workspace/GitHub/charts) and gets Windows ones on a Windows checkout. Pre-existing and unrelated; I bypassed the pre-commit hook for that reason rather than touching it. Everything else passes: 113/115, 1 skipped.

Verification

Typecheck and lint clean. Verified in a browser in both light and dark mode: hero, all five sections, the shuffling runtime row (sampled TanStack AI → Python → Go), and the contrast fix at the frame where TanStack AI is the active runtime. No console errors.

Summary by CodeRabbit

  • New Features

    • Added Angular support for TanStack AI, including package and documentation links.
    • Refreshed the landing-page hero graph and chat runtime demo with active-server rotation and clearer runtime/protocol labeling.
    • Redesigned the feature showcase rail with updated modality content (including realtime voice).
  • Content Updates

    • Updated the landing copy to highlight real agent loops, typed primitives, headless usage, and clearer client/server boundaries.
    • Reworked sections and examples (including updated QuickStart and Devtools) and removed the prior “Honest comparison” content.
  • Tests

    • Expanded doc-link test coverage to include Angular.

Follow-up commits: quick start and devtools

Quick start (new). The page had no code on it at all. There is now a server route and a client hook side by side, using the real signatures from the docs — including useChat({ connection: fetchServerSentEvents('/api/chat') }), not the { api } shape I originally sketched. A caption notes the server route is byte-identical across every binding.

Devtools (new). Was four words inside a paragraph. Now a mock panel in the page's own idiom (no screenshot to rot), showing the hook dashboard and a run timeline ending on interrupt · run resumable, which ties back to the interrupts claim earlier on the page.

Comparison section: removed. It was built, then pulled at review, so no comparison ships in this PR. Two findings from that work outlive the section.

Worth a separate pass in the AI repo

docs/comparison/vercel-ai-sdk.md in tanstack/ai is stale. vercel/ai now ships code-mode, harness-claude-code, harness-codex, harness-opencode, harness-deepagents, sandbox-vercel, and devtools packages, so treating code mode, sandboxed harnesses, MCP, or memory as ours alone is no longer accurate.

Snippet corrections

Auditing my own code caught two wrong identifiers, both fixed: the OpenRouter adapter exports openRouterText, not openrouterText; and there is no bare realtimeToken export, since realtime tokens are per-provider (openaiRealtimeToken, elevenlabsRealtimeToken, grokRealtimeToken, geminiRealtimeToken).

The server snippet is now a TanStack Start route using createFileRoute with server.handlers.POST. The client snippet resolves an interrupt via interrupt.resolveInterrupt(true), keyed on interrupt.id and labelled from interrupt.toolName, checked against docs/interrupts/tool-approval. Every other identifier was audited against exports on origin/main.

Also in this commit: code identifiers in the always-dark code surface use fixed token colors, because --landing-accent-bright resolves to a dark terracotta in light mode and was unreadable on the dark block. Both quick-start windows flex so their code panes match height.

Verified in the browser in light and dark mode: all eight sections, both new panels, table scrolls horizontally inside its own container without the page scrolling. Typecheck and lint clean.

Reframe the TanStack AI landing copy around the agent loop and a
bring-your-own-stack story, grounded in what the tanstack/ai repo
actually ships rather than the old generic "AI SDK" framing.

- Hero and library descriptions lead with the headless agent framework
  positioning: the loop, its parts, and the absence of a hosted gateway
  or proprietary wire format.
- Retitle the tools section to the agent loop and cover stop strategies
  and needsApproval interrupts that resume on a stateless server.
- Name all eleven official provider adapters plus openaiCompatible, and
  describe per-model type narrowing concretely.
- Add a section for the rest of the agent stack: Code Mode isolates,
  coding-agent harnesses, MCP and MCP Apps, memory and persistence.
- Expand the modality rail with summarize, music, diarization, and the
  async video job lifecycle; generalize ModalityRail into FeatureRail so
  both rails share one component.
- Hero graph: eight client bindings on a 4x2 grid, a shuffling
  server/runtime row so Python and Go read as first-class AG-UI targets,
  and the runtime tile follows it.
- Use white text on a darkened accent fill for the TanStack pills and
  user chat bubbles; the shared --landing-accent-ink is pure black and
  read badly on orange in light mode.

Register the Angular bindings, which ship upstream as
@tanstack/ai-angular (published, 0.3.1) but were missing from the site
config, and update ai-framework-doc-links to match. Octane is named in
prose only: its bindings ship as @octanejs/tanstack-ai rather than a
@TanStack package, so the framework picker would need a logo asset and
a Framework union entry.

Prose avoids em-dashes throughout.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2d4fd214-042b-4ded-a75d-26c62054b97a

📥 Commits

Reviewing files that changed from the base of the PR and between a14926d and 1a6b6e4.

📒 Files selected for processing (1)
  • src/components/landing/AiLanding.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/landing/AiLanding.tsx

📝 Walkthrough

Walkthrough

The PR refreshes TanStack AI landing content, expands the rotating hero graph with server selection, replaces the modality rail with shared feature data, updates project metadata, and adds Angular package and documentation link coverage.

Changes

AI landing refresh

Layer / File(s) Summary
Landing content and graph model
src/components/landing/AiLanding.tsx
Landing copy, provider prompt data, hero client/server definitions, staged chat messages, accessibility text, and accent styling are updated.
Rotating hero runtime flow
src/components/landing/AiLanding.tsx
The hero rotates servers, highlights the active server, routes graph lines from it, and displays its label in the runtime tile.
Agent stack feature rail
src/components/landing/AiLanding.tsx
QuickStart, tool, provider, protocol, agent-stack, and modality content are revised and rendered through shared feature-rail data.
Library metadata and Angular links
src/libraries/ai.tsx, src/libraries/libraries.ts, tests/ai-framework-doc-links.test.ts
TanStack AI metadata and feature highlights are rewritten; Angular package and documentation mappings are added and tested.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AiGraphChatHero
  participant aiHeroServers
  participant GraphNode
  participant RuntimeTile
  AiGraphChatHero->>aiHeroServers: rotate activeServer
  AiGraphChatHero->>GraphNode: highlight server and route provider lines
  AiGraphChatHero->>RuntimeTile: display active server label
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: reframing the AI landing page around TanStack AI as a headless agent framework.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ai-landing-headless-agent-copy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 30, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com 1a6b6e4 Commit Preview URL

Branch Preview URL
Jul 30 2026, 06:14 PM

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/landing/AiLanding.tsx (1)

422-424: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hardcoded "eight" will silently drift from aiHeroClients.length.

The screen-reader description hardcodes "eight" client adapters. If aiHeroClients (line 78) ever changes length — same risk already flagged in the code's own comment at line 95 about the grid layout — this text won't be updated in sync, giving screen-reader users an inaccurate count.

♻️ Suggested fix
       <span className="sr-only">
-        A client graph shows eight UI adapters converging on the TanStack AI
-        Client over AG-UI, then reaching an agent runtime in TypeScript, Python,
-        Go, or PHP, and interchangeable model providers.
+        A client graph shows {aiHeroClients.length} UI adapters converging on
+        the TanStack AI Client over AG-UI, then reaching an agent runtime in
+        TypeScript, Python, Go, or PHP, and interchangeable model providers.
       </span>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/landing/AiLanding.tsx` around lines 422 - 424, Update the
screen-reader description in AiLanding to derive the client-adapter count from
aiHeroClients.length instead of hardcoding “eight.” Keep the existing
description structure and surrounding architecture text unchanged while ensuring
the rendered count stays synchronized with the array.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/libraries/libraries.ts`:
- Around line 653-665: Align TanStack AI’s framework metadata and landing copy:
in src/libraries/libraries.ts, update the framework/package/docs mapping
associated with the visible frameworks list if React Native is supported;
otherwise, in src/libraries/ai.tsx, remove or qualify the React Native claim.
Ensure both sites consistently represent the same supported framework set.

---

Nitpick comments:
In `@src/components/landing/AiLanding.tsx`:
- Around line 422-424: Update the screen-reader description in AiLanding to
derive the client-adapter count from aiHeroClients.length instead of hardcoding
“eight.” Keep the existing description structure and surrounding architecture
text unchanged while ensuring the rendered count stays synchronized with the
array.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d3f5b028-d575-46b2-bc6e-14ec28d8785e

📥 Commits

Reviewing files that changed from the base of the PR and between 08cb7eb and 218bc98.

📒 Files selected for processing (4)
  • src/components/landing/AiLanding.tsx
  • src/libraries/ai.tsx
  • src/libraries/libraries.ts
  • tests/ai-framework-doc-links.test.ts

Comment on lines +653 to +665
tagline: 'The headless agent framework for TypeScript. Bring your own stack',
description:
'A powerful, open-source AI SDK with a unified interface across multiple providers. No vendor lock-in, no proprietary formats, just clean TypeScript and honest open source.',
'The headless agent framework for TypeScript. TanStack AI runs the agent loop as typed primitives you compose yourself: tool calls, reasoning, human-in-the-loop interrupts, memory, and streaming state. Eleven provider adapters, seven UI framework bindings, sandboxed code execution, MCP, and coding-agent harnesses behind one interface. Native AG-UI over the wire, MIT licensed, no hosted gateway and no platform to buy into.',
badge: 'beta',
repo: 'tanstack/ai',
frameworks: ['react', 'vue', 'solid', 'svelte', 'preact', 'vanilla'],
frameworks: [
'react',
'vue',
'solid',
'svelte',
'preact',
'angular',
'vanilla',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)libraries/(libraries\.ts|ai\.tsx)$' || true

echo "== outline libraries.ts =="
ast-grep outline src/libraries/libraries.ts --view compact || true

echo "== relevant libraries.ts lines =="
sed -n '620,690p' src/libraries/libraries.ts

echo "== relevant ai.tsx lines =="
sed -n '35,55p' src/libraries/ai.tsx

echo "== searches for react native/native frameworks in codebase =="
rg -n -i "react[- _]?native|native" src/libraries src -g '*.{ts,tsx,gold,md}' | head -n 200

Repository: TanStack/tanstack.com

Length of output: 18676


Align the React Native claim with TanStack AI’s framework metadata.

The landing copy lists React Native as a supported binding, but the library metadata still shows seven listed framework bindings without a React Native framework/package/docs mapping. Add the mapping if it is supported, or remove/qualify the React Native claim.

📍 Affects 2 files
  • src/libraries/libraries.ts#L653-L665 (this comment)
  • src/libraries/ai.tsx#L45-L47
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/libraries/libraries.ts` around lines 653 - 665, Align TanStack AI’s
framework metadata and landing copy: in src/libraries/libraries.ts, update the
framework/package/docs mapping associated with the visible frameworks list if
React Native is supported; otherwise, in src/libraries/ai.tsx, remove or qualify
the React Native claim. Ensure both sites consistently represent the same
supported framework set.

Three sections the landing page was missing, each grounded in APIs and
facts checked against source rather than written from memory.

Quick start: the page never showed any code. A server route and a client
hook now sit side by side, using the real signatures from the docs,
including useChat({ connection: fetchServerSentEvents(...) }) rather than
an invented options shape. A caption notes the server route is identical
across every binding.

Devtools: previously four words inside a paragraph. Now a mock panel in
the page's own idiom, showing the hook dashboard and a run timeline that
ends on an interrupt with a resumable run, which ties back to the
interrupts claim earlier on the page.

Comparison: a three-way table against the Vercel AI SDK and Mastra,
framed as tradeoffs so each column has a real answer. Rows cover the
wire protocol, client bindings, where the agent runs, whether a hosted
service sits in the loop, and licensing. Verified from source:
@mastra/core 1.56 is Apache 2.0 with ee/ carved out and ships React plus
a framework-free client against its own Hono server; ai 7.0 is Apache
2.0 with React, Vue, Svelte, and Angular bindings.

Deliberately excluded from the table: code mode, sandboxed harnesses,
MCP, and memory. The in-repo comparison doc treats some of those as ours
alone, but vercel/ai now ships code-mode, harness-claude-code,
harness-codex, harness-opencode, sandbox-vercel, and devtools packages,
so claiming them would be wrong. The footnote says as much and gives the
versions and date it was checked.

Code identifiers in the always-dark code surface use fixed token colors;
--landing-accent-bright resolves to a dark terracotta in light mode and
was unreadable there. Both quick-start windows flex so their code panes
match height.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/landing/AiLanding.tsx`:
- Around line 379-382: Update the hero binding description and related listing
around the footer paragraph and comparison row to align the stated count with
the supported options, including Octane if it is part of the seven bindings.
Keep the framework-free ai-client distinct from the UI framework bindings and
ensure the prose and enumerations use the same set.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4766f6ca-062a-45bb-bd48-72585cf1ee02

📥 Commits

Reviewing files that changed from the base of the PR and between 218bc98 and 12f8e97.

📒 Files selected for processing (1)
  • src/components/landing/AiLanding.tsx

Comment thread src/components/landing/AiLanding.tsx
Remove the three-way comparison section, its table component, and its
data for now, along with the Scales icon import.

Fix two wrong identifiers in the quick start. The OpenRouter adapter
exports openRouterText, not openrouterText. Realtime tokens are
per-provider (openaiRealtimeToken, elevenlabsRealtimeToken,
grokRealtimeToken, geminiRealtimeToken); there is no bare realtimeToken
export, so the modality rail now names the OpenAI one.

Rewrite the server snippet as a TanStack Start route using
createFileRoute with server.handlers.POST, matching the shape in the
quick-start docs, rather than a bare framework-agnostic POST function.

Extend the client snippet to resolve an interrupt with
interrupt.resolveInterrupt(true), keyed on interrupt.id and labelled from
interrupt.toolName, all verified against docs/interrupts/tool-approval.
This also balances the two panes, which the taller server route had left
lopsided.

Every other identifier on the page was audited against exports in
tanstack/ai origin/main: chat, toolDefinition, openaiText,
openaiCompatible, summarize, generateSpeech, generateTranscription,
generateAudio, generateImage, generateVideo, RealtimeClient,
memoryMiddleware, mcpTool, maxIterations, and untilFinishReason all
resolve.
The old title, "An open protocol is the seam. Not our servers.", buried
the concrete claim behind a metaphor. State the compliance up front
instead, and move the eyebrow to "Open protocol" so it is not just a
restatement of the heading.

The body now earns the claim in order: compliant both ways, therefore the
runtime is replaceable, therefore the transport is yours.
@AlemTuzlak
AlemTuzlak merged commit 8a22746 into main Jul 30, 2026
7 checks passed
@AlemTuzlak
AlemTuzlak deleted the ai-landing-headless-agent-copy branch July 30, 2026 20:32
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