fix(ai-persistence): make RunStore.findActiveRun required - #1004
Conversation
`findActiveRun` was optional on the `RunStore` contract and feature-detected at the call site (`store.findActiveRun?.(threadId)`). That made a backend which had not implemented it indistinguishable from one whose thread is genuinely idle — both answer `null` — so reconnect silently turned off in production instead of failing at build time. - Make `findActiveRun` required on `RunStore`; drop the optional call in `reconstructChat`. - Record the evolution policy in `types.ts`: store methods are required, capability tiers belong at the store level (omit `runs`, declare `ChatTranscriptStores`), never at the method level. - Drop the conformance skip so every backend providing `runs` must satisfy the invariants; implement `findActiveRun` in the test fixture store. - Update the adapter guide, the stores skill, and the changeset accordingly. - Enable `migrate: true` in the ts-react-chat persistent store example.
📝 WalkthroughWalkthrough
ChangesRunStore contract enforcement
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
🚀 Changeset Version Preview16 package(s) bumped directly, 34 bumped as dependents. 🟥 Major bumps
🟨 Minor bumps
🟩 Patch bumps
|
|
View your CI Pipeline Execution ↗ for commit e83018c
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-acp
@tanstack/ai-angular
@tanstack/ai-anthropic
@tanstack/ai-bedrock
@tanstack/ai-claude-code
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-codex
@tanstack/ai-devtools-core
@tanstack/ai-durable-stream
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-grok-build
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-memory
@tanstack/ai-mistral
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-opencode
@tanstack/ai-openrouter
@tanstack/ai-persistence
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-sandbox
@tanstack/ai-sandbox-cloudflare
@tanstack/ai-sandbox-daytona
@tanstack/ai-sandbox-docker
@tanstack/ai-sandbox-local-process
@tanstack/ai-sandbox-sprites
@tanstack/ai-sandbox-vercel
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
There was a problem hiding this comment.
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 `@docs/config.json`:
- Line 269: Update the updatedAt field in the documentation configuration to use
today’s review date, 2026-07-27, instead of the future date 2026-07-28.
🪄 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: 213dd69f-61ae-4151-8051-aeb565fe1628
📒 Files selected for processing (10)
.changeset/define-store-helpers.md.changeset/run-store-find-active-run-required.mddocs/config.jsondocs/persistence/build-your-own-adapter.mdexamples/ts-react-chat/src/lib/persistent-chat-store.tspackages/ai-persistence/skills/ai-persistence/stores/SKILL.mdpackages/ai-persistence/src/reconstruct.tspackages/ai-persistence/src/testkit/conformance.tspackages/ai-persistence/src/types.tspackages/ai-persistence/tests/persistence-fixtures.ts
| "to": "persistence/build-your-own-adapter", | ||
| "addedAt": "2026-07-24", | ||
| "updatedAt": "2026-07-27" | ||
| "updatedAt": "2026-07-28" |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use today’s date for updatedAt.
The current review date is July 27, 2026, but this value is future-dated as 2026-07-28. Change it to 2026-07-27.
As per coding guidelines, documentation timestamps must use today’s date for content changes.
🤖 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 `@docs/config.json` at line 269, Update the updatedAt field in the
documentation configuration to use today’s review date, 2026-07-27, instead of
the future date 2026-07-28.
Source: Coding guidelines
main squash-merged the two PRs this branch was stacked on (#988 sandbox instance durability, #1011 generation run persistence), so this branch's own copy of that foundation collided with the squashes. 17 files conflicted. Notable resolutions, beyond taking the union: - #1004 made `RunStore.findActiveRun` REQUIRED, and main added an explicit store-contract evolution policy naming that exact regression. This branch had relocated `RunStore` into `@tanstack/ai` with `findActiveRun?` optional, and `run-store.ts` merged CLEANLY -- so keeping our side would have silently reverted #1004. `findActiveRun` is now required in core too, dropped from the conformance suite's `skipMethods` union, and `fenceRunStore` forwards it unconditionally. `listByThread`/`listReclaimable` stay optional. - Generation persistence moved to main's `generationRuns` store, but main writes `status: 'interrupted'` with a `finishedAt` on abort. This branch made `interrupted` non-terminal ("parked, waiting for a human"), so that pairing would leave an aborted generation looking permanently active. Now writes `'aborted'`. - `snapshotStatus` in `reconstruct-generation.ts` switched exhaustively over the old 4-member `RunStatus`; ours adds `aborted`, so an aborted generation fell through and the function returned `undefined`. Now maps to `'error'`. - `chat-persistence.md`: kept main's new lifecycle mermaid diagram, corrected to the current semantics (completed/failed/aborted terminal, interrupted parked, detached stays running). - `docs/sandbox/durability.md`: kept our real `import` over main's `declare const`, per the repo's kiira snippet rule. Verified: 17 typechecks green (including examples/ts-react-chat and testing/e2e), oxlint green, kiira 911/911, test:docs, sherif, knip and oxfmt all clean. Unit: ai 1409, ai-persistence 150, ai-client 585, ai-react 176, ai-durable-stream 45, ai-sandbox 602/603 (pre-existing Windows path case). E2E not run: port 4010 is held by an unrelated showcase-aimock container and another worktree's in-flight Playwright run.
🎯 Changes
findActiveRunwas optional on theRunStorecontract and feature-detected at the call site (store.findActiveRun?.(threadId)). That made a backend which hadn't implemented it indistinguishable from one whose thread is genuinely idle — both answernull— so reconnect silently turned off in production instead of failing at build time. A client reloading (or switching back to) a still-generating thread restored the transcript but never resumed the live reply, with nothing to detect it.findActiveRunrequired onRunStore; drop the optional call inreconstructChat.types.ts: store methods are required, and capability tiers belong at the store level (omitruns, declareChatTranscriptStores) — never at the method level. An absent store is caught by the type system; an incomplete one fails silently at runtime.runsmust satisfy the invariants (most-recent-running wins, thread-scoped, null when idle); implementfindActiveRunin the test fixture store.ai-persistencestores skill, and thedefineRunStorechangeset accordingly.migrate: truein the ts-react-chat persistent store example.Breaking for adapter authors: any external
RunStoreimplementation withoutfindActiveRunnow gets a compile error — which is the point.✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
Bug Fixes
Documentation