added resumable streaming with minimal setup#673
Conversation
🦋 Changeset detectedLatest commit: 7859d25 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
Claude Code ReviewOverview: Adds resumable streaming capability to AIChatAgent with automatic stream restoration on reconnect. Issues Found1. Critical: Hook wrapping breaks subclass overrides (ai-chat-agent.ts:153-174) const _onConnect = this.onConnect.bind(this);
this.onConnect = async (connection: Connection, ctx: ConnectionContext) => {
if (this._activeStreamId) {
this._notifyStreamResuming(connection);
}
return _onConnect(connection, ctx);
};Subclasses that override these methods will have their implementations replaced. Consider using a hook/event system or template method pattern instead. 2. Unbounded chunk buffer memory leak (ai-chat-agent.ts:360-377) if (this._chunkBuffer.length >= CHUNK_BUFFER_SIZE) {
await this._flushChunkBuffer();
} else if (this._chunkBuffer.length >= CHUNK_BUFFER_MAX_SIZE) {
console.warn("Chunk buffer exceeded max size");
}After warning, chunks keep accumulating. Should force flush or drop chunks. 3. Race condition in flush lock (ai-chat-agent.ts:390-399) if (this._isFlushingChunks) return;
this._isFlushingChunks = true;
// ... async operationsMultiple concurrent calls can pass the check before the flag is set, causing duplicate flushes and potential data corruption. 4. SQL injection via template literals (ai-chat-agent.ts:403) this.sql`insert into cf_ai_chat_stream_chunks (id, stream_id, body, chunk_index, created_at)
values ${values}`;Should use proper parameterized queries with 5. Stale stream threshold too aggressive (ai-chat-agent.ts:31) 6. No error handling in resume flow (ai-react.tsx:236-270) 7. Test worker implementation is incomplete (tests/worker.ts) Minor Issues
Testing Coverage✅ Good test coverage for basic flow VerdictNEEDS WORK - The hook wrapping pattern (#1) and race condition (#3) need fixes before merge. The other issues should be addressed but are less critical. |
deathbyknowledge
left a comment
There was a problem hiding this comment.
Looks good, only had a few thoughts. This needs a test though.
| }; | ||
|
|
||
| async onStart() { | ||
| await super.onStart(); |
There was a problem hiding this comment.
What is this for?
There was a problem hiding this comment.
not needed anymore with Sunil's suggestion
| @@ -0,0 +1 @@ | |||
| /// <reference types="vite/client" /> | |||
There was a problem hiding this comment.
tbh, we don't really need it, removed
| // Check if stream is stale (started too long ago) | ||
| if (streamAge > STREAM_STALE_THRESHOLD_MS) { | ||
| // Mark stale stream as error and don't restore | ||
| this.sql` |
There was a problem hiding this comment.
Just a thought, do we rather delete the entry here instead? As a user I'm not sure I want to keep taking storage with older stream metadata
| * Stream chunks are sent only after the client acknowledges with CF_AGENT_STREAM_RESUME_ACK. | ||
| */ | ||
| override async onConnect(connection: Connection, ctx: ConnectionContext) { | ||
| await super.onConnect(connection, ctx); |
There was a problem hiding this comment.
Is the super.onConnect needed?
| * Override onConnect to notify clients about active streams that can be resumed. | ||
| * Stream chunks are sent only after the client acknowledges with CF_AGENT_STREAM_RESUME_ACK. | ||
| */ | ||
| override async onConnect(connection: Connection, ctx: ConnectionContext) { |
There was a problem hiding this comment.
instead of overriding directly here, can we do it like we dp in the base agent class? so that consumers won't have to call super.onConnect
There was a problem hiding this comment.
good call, yes, we totally should do that
1c2884a to
e4b095f
Compare
Added support for resumable streaming with minimal setup.
Documents the new resumable streaming feature added to AIChatAgent class in PR cloudflare/agents#673. This feature provides automatic stream resumption when clients disconnect and reconnect during AI model responses, which is especially useful for long-running reasoning models. Key additions: - New resumable-streaming.mdx page in api-reference section - Server implementation examples using AIChatAgent - Client implementation examples using useAgentChat hook - Technical details on how resumable streaming works internally - Configuration guidance for SQLite migrations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This documentation covers the new automatic resumable streaming feature in AIChatAgent and useAgentChat, which allows AI chat responses to automatically resume when clients reconnect after disconnection. Key features documented: - Automatic stream persistence to SQLite - Client reconnection handling - Server-side and client-side implementation examples - Configuration options for disabling resume Based on PR cloudflare/agents#673 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Synced from cloudflare/agents PR #673: added resumable streaming with minimal setup This documentation covers the automatic resumable streaming feature in AIChatAgent that allows chat streams to seamlessly resume after disconnections. Source PR: cloudflare/agents#673 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
* Add resumable streaming documentation Synced from cloudflare/agents PR #673: added resumable streaming with minimal setup This documentation covers the automatic resumable streaming feature in AIChatAgent that allows chat streams to seamlessly resume after disconnections. Source PR: cloudflare/agents#673 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * adding resumable streaming to the docs --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: katereznykova <kreznykova@cloudflare.com>
something to play with https://resumable-stream-chat.katjareznikova.workers.dev