Skip to content

blog: surviving the refresh - #1112

Open
AlemTuzlak wants to merge 1 commit into
mainfrom
blog/surviving-the-refresh
Open

blog: surviving the refresh#1112
AlemTuzlak wants to merge 1 commit into
mainfrom
blog/surviving-the-refresh

Conversation

@AlemTuzlak

@AlemTuzlak AlemTuzlak commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Launch post for the TanStack AI durability release.

What it covers

The problem framing is one user action: a reload mid-answer breaks the transcript, the stream, and the sandboxed agent doing the work. Three layers, three fixes.

  • How it works - one route with POST + GET and the useChat call, in a single snippet.
  • Layer 1 - chat persistence (withPersistence, client ownership choice, a defineMessageStore adapter).
  • Layer 2 - resumable streams (durability adapter, memoryStream to durableStream swap, SSE and NDJSON).
  • Layer 3 - generation persistence (withGenerationPersistence, useGenerateImage({ persistence: true })).
  • Layer 4 - durable sandboxed agent runs (journal, takeover, reapDetachedRuns).
  • Also in this release - server-side memory, the rebuilt interrupt lifecycle, multi-instance locks, the BytePlus adapter (Seedance video), and zod out of @tanstack/ai.

Notes

  • Every snippet is lifted from the new docs pages in TanStack/ai, so the API names, option shapes and model ids match what ships. Four snippets I first wrote from memory were corrected against the source.
  • Frontmatter matches the existing library: ai posts. Docs links use /ai/docs/....
  • No header image yet. 37 of 43 posts have one at /blog-assets/<slug>/header.png. Happy to add one before merge.
  • The release it announces is not published yet: it goes out with the batch in chore: bump unreleased docs dates, squash pending changesets ai#1051.

Summary by CodeRabbit

  • Documentation
    • Added "Surviving the refresh" release article documenting persistence and durability capabilities, including server-side chat and generation persistence, resumable stream protocols, durable agent execution, server-side memory management, multi-instance locking mechanisms, BytePlus adapter support, and comprehensive setup examples.

Launch post for the TanStack AI durability release: chat persistence,
resumable streams, generation persistence and durable sandboxed agent runs,
plus server-side memory, the rebuilt interrupt lifecycle, multi-instance
locks and the BytePlus adapter.

Every snippet is taken from the new docs pages, so the API names match what
ships.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The new “Surviving the refresh” article documents TanStack AI persistence and durability features. It covers chat recovery, resumable streams, media generation, sandboxed agents, server-side memory, interrupts, locks, the BytePlus adapter, and dependency changes.

Surviving the refresh article

Layer / File(s) Summary
Chat and stream durability
src/blog/surviving-the-refresh.md
Documents durable chat routes, transcript storage, delivery logs, custom persistence contracts, conformance tests, and resumable SSE and NDJSON streams.
Generation and agent recovery
src/blog/surviving-the-refresh.md
Documents persistent media generation, artifact restoration, durable sandboxed-agent runs, takeover and replay, sweeping, reclamation, and cross-process resumption.
Server-side state and controls
src/blog/surviving-the-refresh.md
Documents server-side memory, interrupt resolution, structured errors, client approval controls, and multi-instance sandbox locks.
Adapters and release references
src/blog/surviving-the-refresh.md
Documents the BytePlus ModelArk adapter, asynchronous Seedance video jobs, zod removal from the core dependency graph, and related documentation links.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 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 clearly identifies the blog article added by this pull request.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch blog/surviving-the-refresh

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.

@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: 2

🤖 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/blog/surviving-the-refresh.md`:
- Around line 107-120: Update the storage section text around defineMessageStore
to replace “typers” with “type helpers” or the correct exported type name, and
change “testkit” to “test kit” unless it is an official product name.
- Around line 164-170: Update the imports for the POST generation example to
include the exported generationParamsFromRequest helper from `@tanstack/ai`,
alongside generateImage and toServerSentEventsResponse, so the existing call
resolves correctly.
🪄 Autofix

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: db479a20-881a-4bf7-a646-f677fb53c982

📥 Commits

Reviewing files that changed from the base of the PR and between b91f028 and c67ec2a.

📒 Files selected for processing (1)
  • src/blog/surviving-the-refresh.md

Comment on lines +107 to +120
**Bring your own storage.** There is no required database. You implement a small store contract, and the package ships typers so you get autocomplete and contract checking with no annotations:

```ts
import { defineMessageStore } from '@tanstack/ai-persistence'

export const messages = defineMessageStore({
// Returns [] for a thread that was never saved. Never null.
loadThread: (threadId) => db.transcripts.read(threadId),
// A full replace: `messages` is the complete authoritative history.
saveThread: (threadId, messages) => db.transcripts.write(threadId, messages),
})
```

A basic adapter is about 40 lines, and `memoryPersistence()` covers local dev. If you are writing one, the shared conformance testkit now covers the generation stores too, so you can prove your implementation is correct instead of hoping.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the storage-section terminology.

“typers” is not a clear term. Use “type helpers” or the actual exported type name. If testkit is not a product name, write “test kit.”

🧰 Tools
🪛 LanguageTool

[grammar] ~120-~120: Ensure spelling is correct
Context: ...are writing one, the shared conformance testkit now covers the generation stores too, s...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 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/blog/surviving-the-refresh.md` around lines 107 - 120, Update the storage
section text around defineMessageStore to replace “typers” with “type helpers”
or the correct exported type name, and change “testkit” to “test kit” unless it
is an official product name.

Source: Linters/SAST tools

Comment on lines +164 to +170
import { generateImage, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiImage } from '@tanstack/ai-openai'
import { withGenerationPersistence } from '@tanstack/ai-persistence'
import { persistence } from './persistence'

export async function POST(request: Request) {
const { prompt, threadId } = await generationParamsFromRequest(request)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file locations =="
fd -a 'surviving-the-refresh\.md|persistence\.ts' . || true

echo "== blog file around lines 140-190 =="
cat -n src/blog/surviving-the-refresh.md | sed -n '130,190p'

echo "== surrounding sections mentioning generationParamsFromRequest =="
rg -n "generationParamsFromRequest|from '`@tanstack/ai`'" src/blog/surviving-the-refresh.md . --glob '!node_modules' --glob '!dist' --glob '!build' | head -200

echo "== package files mentioning `@tanstack/ai` version =="
for f in package.json pnpm-lock.yaml package-lock.json yarn.lock bun.lockb; do
  [ -f "$f" ] && { echo "--- $f"; rg -n "`@tanstack/ai`|`@tanstack/ai-openai`|`@tanstack/ai-persistence`" "$f" | head -100; }
done

Repository: TanStack/tanstack.com

Length of output: 8544


🌐 Web query:

@tanstack/ai 0.20.1 exports generationParamsFromRequest

💡 Result:

Yes, the @tanstack/ai package exports generationParamsFromRequest [1][2]. This function is used to parse and validate HTTP requests in the context of media generation (e.g., image generation), similar to how chatParamsFromRequest is used for chat agents [1][2][3][4]. In practice, you typically use it within a server-side route handler (such as a POST request handler) to extract parameters like the input and threadId from the incoming request [1][2]: import { generationParamsFromRequest } from '@tanstack/ai'; export async function POST(request: Request) { const { input, threadId } = await generationParamsFromRequest('image', request); //... proceed with generation logic } The function validates the request against the expected schema for the specified generation type (e.g., 'image') and throws a 400 response if the input is malformed, which is a pattern consistent with other request parsing utilities in the library [1][2][4]. Version 0.20.1 of @tanstack/ai exists and is referenced in the library's dependency history [5].

Citations:


Import generationParamsFromRequest in the generation example.

@tanstack/ai exports this helper, but the import list here does not include it, so the example code references an undefined call.

Proposed import
-import { generateImage, toServerSentEventsResponse } from '`@tanstack/ai`'
+import {
+  generateImage,
+  generationParamsFromRequest,
+  toServerSentEventsResponse,
+} from '`@tanstack/ai`'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { generateImage, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiImage } from '@tanstack/ai-openai'
import { withGenerationPersistence } from '@tanstack/ai-persistence'
import { persistence } from './persistence'
export async function POST(request: Request) {
const { prompt, threadId } = await generationParamsFromRequest(request)
import {
generateImage,
generationParamsFromRequest,
toServerSentEventsResponse,
} from '`@tanstack/ai`'
import { openaiImage } from '`@tanstack/ai-openai`'
import { withGenerationPersistence } from '`@tanstack/ai-persistence`'
import { persistence } from './persistence'
export async function POST(request: Request) {
const { prompt, threadId } = await generationParamsFromRequest(request)
🤖 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/blog/surviving-the-refresh.md` around lines 164 - 170, Update the imports
for the POST generation example to include the exported
generationParamsFromRequest helper from `@tanstack/ai`, alongside generateImage
and toServerSentEventsResponse, so the existing call resolves correctly.

@cloudflare-workers-and-pages

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 c67ec2a Commit Preview URL

Branch Preview URL
Aug 04 2026, 04:44 PM

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