diff --git a/.changeset/persistence-v2.md b/.changeset/persistence-v2.md new file mode 100644 index 000000000..66ccbe706 --- /dev/null +++ b/.changeset/persistence-v2.md @@ -0,0 +1,43 @@ +--- +'@tanstack/ai': minor +'@tanstack/ai-client': minor +'@tanstack/ai-durable-stream': minor +'@tanstack/ai-persistence': minor +'@tanstack/ai-persistence-drizzle': minor +'@tanstack/ai-persistence-prisma': minor +'@tanstack/ai-angular': minor +'@tanstack/ai-preact': minor +'@tanstack/ai-react': minor +'@tanstack/ai-solid': minor +'@tanstack/ai-svelte': minor +'@tanstack/ai-vue': minor +--- + +Persistence v2: split state (middleware) vs delivery (transport) durability. + +State durability stays on the middleware layer as `withChatPersistence` / +`withGenerationPersistence`, backed by a store contract (messages, runs, +interrupts, metadata, locks, artifacts, blobs). The `@tanstack/ai-persistence` +package now ships a state-only middleware, an in-core memory backend, and a +shared conformance suite; `@tanstack/ai-persistence-drizzle` and +`@tanstack/ai-persistence-prisma` provide state backends. + +Delivery durability (replay a disconnected/reloaded stream) moves to the +transport layer via a pluggable `StreamDurability` sink — the SDK owns zero +delivery-event storage. The new `@tanstack/ai-durable-stream` package provides a +durable-streams-protocol `StreamDurability` adapter, and the client +(`@tanstack/ai-client`) plus every framework binding (`@tanstack/ai-react`, +`-solid`, `-vue`, `-svelte`, `-angular`, `-preact`) switch to resumable SSE with +interrupt-only resume. + +The home-grown delivery/event-log subsystem is removed: the in-band `cursor` on +`StreamChunk`, the `cursor` param on `chat()`, the public/internal event stores, +the `ResumeSource` seam, cursor-replay client machinery, and the deprecated +approval-store shim are all deleted (this feature is unreleased — no back-compat +shims). Interrupt resume (approvals / client-tool results via +`RunAgentInput.resume[]`) is preserved as state durability. + +The delivery-store / SQL-driver packages that only existed to back the removed +event log — `@tanstack/ai-persistence-sql`, `-sqlite`, `-postgres`, and +`-cloudflare` — are removed. They were never published (part of this same +unreleased persistence work), so no npm tombstone release is needed. diff --git a/docs/api/ai-angular.md b/docs/api/ai-angular.md index 438c3bf46..12ad892a7 100644 --- a/docs/api/ai-angular.md +++ b/docs/api/ai-angular.md @@ -381,9 +381,12 @@ export class CustomGenerationComponent { } ``` -**Options:** `connection?`, `fetcher?`, `id?`, `body?` (reactive), `devtools?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` +**Options:** `connection?`, `fetcher?`, `id?`, `body?` (reactive), `persistence?`, `autoResume?`, `initialResumeSnapshot?`, `resumeState?` (reactive), `devtools?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` -**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset` — all reactive state is a read-only `Signal`. +**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset`, `resume`, `resumeSnapshot`, `resumeState`, `pendingArtifacts`, `resultArtifacts` — all reactive state is a read-only `Signal`. + +For the end-to-end persistence setup, see +[Generation Persistence](../persistence/generation-persistence). ### `injectGenerateImage(options)` diff --git a/docs/api/ai-react.md b/docs/api/ai-react.md index 0cc599357..660e5cf93 100644 --- a/docs/api/ai-react.md +++ b/docs/api/ai-react.md @@ -86,7 +86,7 @@ Extends `ChatClientOptions` from `@tanstack/ai-client`: - `initialMessages?` - Initial messages array - `id?` - Unique identifier for this chat instance - `threadId?` - Thread ID for AG-UI run correlation. Persists across sends; auto-generated if omitted -- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-4o' }`) +- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-5.5' }`) - `body?` - **Deprecated.** Use `forwardedProps` instead. Still works for backward compatibility; values are merged into `forwardedProps` on the wire - `context?` - Typed client-local runtime context passed to client tool implementations. This value is not serialized to the server - `onResponse?` - Callback when response is received @@ -159,6 +159,24 @@ function that resolves per request. For error narrowing, import `UnsupportedResponseStreamError` and `StreamTruncatedError` from `@tanstack/ai-client`. +## Generation Hooks + +React also exports `useGeneration`, `useGenerateImage`, `useGenerateAudio`, +`useGenerateSpeech`, `useTranscription`, `useSummarize`, and +`useGenerateVideo`. + +Generation hook options include `connection` or `fetcher`, `id`, `body`, +`persistence`, `autoResume`, `initialResumeSnapshot`, `resumeState`, +`devtools`, `onResult`, `onError`, `onProgress`, and `onChunk`. + +Generation hook returns include `generate`, `result`, `isLoading`, `error`, +`status`, `stop`, `reset`, `resume`, `resumeSnapshot`, `resumeState`, +`pendingArtifacts`, and `resultArtifacts`. Video generation also returns +`jobId` and `videoStatus`. + +For the end-to-end persistence setup, see +[Generation Persistence](../persistence/generation-persistence). + ## Example: Basic Chat ```tsx diff --git a/docs/api/ai-solid.md b/docs/api/ai-solid.md index 855ce883e..a87426bfd 100644 --- a/docs/api/ai-solid.md +++ b/docs/api/ai-solid.md @@ -77,7 +77,7 @@ Extends `ChatClientOptions` from `@tanstack/ai-client`: - `initialMessages?` - Initial messages array - `id?` - Unique identifier for this chat instance - `threadId?` - Thread ID for AG-UI run correlation. Persists across sends; auto-generated if omitted -- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-4o' }`) +- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-5.5' }`) - `body?` - **Deprecated.** Use `forwardedProps` instead. Still works for backward compatibility; values are merged into `forwardedProps` on the wire - `context?` - Typed client-local runtime context passed to client tool implementations. This value is not serialized to the server - `onResponse?` - Callback when response is received @@ -121,6 +121,25 @@ interface UseChatReturn { **Note:** Unlike React, `messages`, `isLoading`, and `error` are SolidJS `Accessor` functions, so you need to call them to get their values (e.g., `messages()` instead of just `messages`). +## Generation Hooks + +Solid also exports `useGeneration`, `useGenerateImage`, `useGenerateAudio`, +`useGenerateSpeech`, `useTranscription`, `useSummarize`, and +`useGenerateVideo`. + +Generation hook options include `connection` or `fetcher`, `id`, `body`, +`persistence`, `autoResume`, `initialResumeSnapshot`, `resumeState`, +`devtools`, `onResult`, `onError`, `onProgress`, and `onChunk`. + +Generation hook returns include `generate`, `result`, `isLoading`, `error`, +`status`, `stop`, `reset`, `resume`, `resumeSnapshot`, `resumeState`, +`pendingArtifacts`, and `resultArtifacts`. Reactive values are Solid accessors, +so read `resumeState()` and `pendingArtifacts()`. Video generation also returns +`jobId` and `videoStatus`. + +For the end-to-end persistence setup, see +[Generation Persistence](../persistence/generation-persistence). + ## Connection Adapters Re-exported from `@tanstack/ai-client` for convenience: diff --git a/docs/api/ai-svelte.md b/docs/api/ai-svelte.md index 6f8278043..5ce2e24a3 100644 --- a/docs/api/ai-svelte.md +++ b/docs/api/ai-svelte.md @@ -75,7 +75,7 @@ Extends `ChatClientOptions` from `@tanstack/ai-client` (minus internal state cal - `initialMessages?` - Initial messages array - `id?` - Unique identifier for this chat instance - `threadId?` - Thread ID for AG-UI run correlation. Persists across sends; auto-generated if omitted -- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-4o' }`) +- `forwardedProps?` - Arbitrary client-controlled JSON forwarded to the server in the AG-UI `RunAgentInput.forwardedProps` field (e.g., `{ provider: 'openai', model: 'gpt-5.5' }`) - `body?` - **Deprecated.** Use `forwardedProps` instead. Still works for backward compatibility; values are merged into `forwardedProps` on the wire - `context?` - Typed client-local runtime context passed to client tool implementations. This value is not serialized to the server - `live?` - Enable live subscription mode (subscribes on creation) @@ -299,9 +299,12 @@ const gen = createGeneration({ // gen.result, gen.isLoading, gen.error, gen.status ``` -**Options:** `connection?`, `fetcher?`, `id?`, `body?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` +**Options:** `connection?`, `fetcher?`, `id?`, `body?`, `persistence?`, `autoResume?`, `initialResumeSnapshot?`, `resumeState?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` -**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset`, `updateBody` -- all state properties are reactive getters. +**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset`, `updateBody`, `dispose`, `resume`, `resumeSnapshot`, `resumeState`, `pendingArtifacts`, `resultArtifacts` -- all state properties are reactive getters. + +For the end-to-end persistence setup, see +[Generation Persistence](../persistence/generation-persistence). ### `createGenerateImage(options)` diff --git a/docs/api/ai-vue.md b/docs/api/ai-vue.md index 5b9cf0707..f8c4e3a81 100644 --- a/docs/api/ai-vue.md +++ b/docs/api/ai-vue.md @@ -316,9 +316,12 @@ const { generate, result, isLoading, error, status, stop, reset } = }); ``` -**Options:** `connection?`, `fetcher?`, `id?`, `body?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` +**Options:** `connection?`, `fetcher?`, `id?`, `body?`, `persistence?`, `autoResume?`, `initialResumeSnapshot?`, `resumeState?`, `onResult?`, `onError?`, `onProgress?`, `onChunk?` -**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset` -- all reactive state is `DeepReadonly>`. +**Returns:** `generate`, `result`, `isLoading`, `error`, `status`, `stop`, `reset`, `resume`, `resumeSnapshot`, `resumeState`, `pendingArtifacts`, `resultArtifacts` -- all reactive state is `DeepReadonly>`. Read refs with `.value` in `