Add Chat SDK state adapter and messenger admin UI#1570
Merged
Conversation
Build out the chat-sdk-messenger example into a fuller admin-oriented app while keeping the core architecture centered on Chat SDK ingress, an Agents-backed state adapter, and Think-owned conversation intelligence. The example now serves a Vite/React admin dashboard, exposes parent-owned admin APIs for setup/conversation/job inspection, gates browser access to known ConversationAgent subagents, and adds a one-click Telegram webhook setup flow for local quick tunnels and deployed Workers. This makes the example easier to run, inspect, and operate without turning the admin Think pane into an implicit messenger sender. Harden the AI reply delivery path for Telegram by introducing a bounded visible stream bridge. Think still receives and persists the full model response, while Telegram gets a conservative first streaming message and any overflow is posted as provider-safe follow-up chunks. Expected Telegram final-edit no-op errors after the visible stream reaches the soft limit are treated as delivery completion instead of model interruption, while real first-stream failures and overflow chunk failures remain delivery errors so managed fibers are not incorrectly completed. Update @cloudflare/think so programmatic chat() and clearMessages() calls broadcast message updates to connected clients. This keeps the admin Think pane live when messenger-originated turns arrive through RPC rather than WebSocket input. Refresh the example docs and TODOs around quick tunnels, admin dashboard behavior, long Telegram replies, managed reply job inspection, and future SDK extraction candidates. Standardize remaining repo docs and sample env files on .env/.env.example while keeping local secret files ignored. Add focused coverage for the admin APIs, subagent gating, Think broadcast behavior, bounded streaming, Telegram chunk splitting, and delivery-error classification. Co-authored-by: Cursor <cursoragent@cursor.com>
Tighten the chat-sdk-messenger local development flow around Quick Tunnels by making the Vite plugin start a tunnel by default, removing the separate tunnel script, and updating the setup UI to avoid invalid Telegram webhook attempts from localhost. The admin dashboard now surfaces a prominent localhost warning that points users to the printed trycloudflare.com URL while still allowing local-only inspection when needed. Keep Telegram webhook setup safer by rejecting non-HTTPS setup requests before calling the Telegram API. This prevents the confusing Telegram error where localhost-derived webhook URLs are rejected as non-HTTPS, and gives the example a clearer failure mode when opened from the wrong origin. Improve the Think admin pane as a debugging surface. It now renders all UI message parts instead of collapsing messages to text only: text remains inline, while reasoning traces, tool calls/results, and unknown message parts appear as collapsible JSON sections. Telegram delivery remains text-only, so internal reasoning/tool data stays confined to the admin UI. Update Think so RPC-driven chat() turns broadcast live chat response chunks to connected WebSocket clients. Messenger-originated turns still stream through the RPC callback to Telegram, but connected admin clients now receive the same live cf_agent_use_chat_response frames instead of seeing the assistant message only after final persistence. Add regression coverage for HTTPS-only webhook setup and RPC chat stream broadcasting to connected Think clients. Co-authored-by: Cursor <cursoragent@cursor.com>
Split the chat-sdk-messenger example along the boundaries we expect to matter for a future SDK extraction. Keep ChatIngressAgent focused on orchestration while moving provider policy, admin directory mapping, and AI reply delivery helpers into smaller modules. The Telegram provider module now owns webhook setup, HTTPS validation, message delivery limits, long-message chunking, final-edit no-op classification, and Telegram-specific state key sharding. This removes Telegram-specific dedupe key handling from the generic Agents-backed Chat SDK state adapter. The intelligence delivery module now owns managed AI reply fiber names, snapshots, recovery mode, and failure mode policy. The admin directory module owns conversation/job DTOs and row-to-view mapping helpers. These files make the example a better staging ground for deciding what eventually belongs in agents/src/chat-sdk without prematurely extracting Telegram or admin UI product code. Replace the ChatStateAgent recurring cleanup interval with lazy one-shot cleanup scheduling. Expiring writes now schedule the next cleanup only when needed, update the scheduled cleanup when an earlier expiry appears, and reschedule after cleanup only if expiring rows remain. Cleanup metadata tracks the next expiry and schedule id so state shards without expiring records do not pay for a forever schedule, which is a better shape for SDK-owned state infrastructure. Update README/TODO notes to document the module layout and extraction candidates, and adjust tests to cover provider-owned Telegram key sharding instead of baking Telegram behavior into the generic state adapter. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 7c9d8a5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
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 |
Include a favicon for the chat-sdk-messenger example by adding public/favicon.ico and adding a <link rel="icon" href="/favicon.ico" /> in the head of index.html so browsers display the site icon.
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Merged
threepointone
added a commit
that referenced
this pull request
May 21, 2026
* Expand chat SDK messenger admin and delivery flows Build out the chat-sdk-messenger example into a fuller admin-oriented app while keeping the core architecture centered on Chat SDK ingress, an Agents-backed state adapter, and Think-owned conversation intelligence. The example now serves a Vite/React admin dashboard, exposes parent-owned admin APIs for setup/conversation/job inspection, gates browser access to known ConversationAgent subagents, and adds a one-click Telegram webhook setup flow for local quick tunnels and deployed Workers. This makes the example easier to run, inspect, and operate without turning the admin Think pane into an implicit messenger sender. Harden the AI reply delivery path for Telegram by introducing a bounded visible stream bridge. Think still receives and persists the full model response, while Telegram gets a conservative first streaming message and any overflow is posted as provider-safe follow-up chunks. Expected Telegram final-edit no-op errors after the visible stream reaches the soft limit are treated as delivery completion instead of model interruption, while real first-stream failures and overflow chunk failures remain delivery errors so managed fibers are not incorrectly completed. Update @cloudflare/think so programmatic chat() and clearMessages() calls broadcast message updates to connected clients. This keeps the admin Think pane live when messenger-originated turns arrive through RPC rather than WebSocket input. Refresh the example docs and TODOs around quick tunnels, admin dashboard behavior, long Telegram replies, managed reply job inspection, and future SDK extraction candidates. Standardize remaining repo docs and sample env files on .env/.env.example while keeping local secret files ignored. Add focused coverage for the admin APIs, subagent gating, Think broadcast behavior, bounded streaming, Telegram chunk splitting, and delivery-error classification. Co-authored-by: Cursor <cursoragent@cursor.com> * Polish messenger admin streaming and tunnel workflow Tighten the chat-sdk-messenger local development flow around Quick Tunnels by making the Vite plugin start a tunnel by default, removing the separate tunnel script, and updating the setup UI to avoid invalid Telegram webhook attempts from localhost. The admin dashboard now surfaces a prominent localhost warning that points users to the printed trycloudflare.com URL while still allowing local-only inspection when needed. Keep Telegram webhook setup safer by rejecting non-HTTPS setup requests before calling the Telegram API. This prevents the confusing Telegram error where localhost-derived webhook URLs are rejected as non-HTTPS, and gives the example a clearer failure mode when opened from the wrong origin. Improve the Think admin pane as a debugging surface. It now renders all UI message parts instead of collapsing messages to text only: text remains inline, while reasoning traces, tool calls/results, and unknown message parts appear as collapsible JSON sections. Telegram delivery remains text-only, so internal reasoning/tool data stays confined to the admin UI. Update Think so RPC-driven chat() turns broadcast live chat response chunks to connected WebSocket clients. Messenger-originated turns still stream through the RPC callback to Telegram, but connected admin clients now receive the same live cf_agent_use_chat_response frames instead of seeing the assistant message only after final persistence. Add regression coverage for HTTPS-only webhook setup and RPC chat stream broadcasting to connected Think clients. Co-authored-by: Cursor <cursoragent@cursor.com> * Modularize chat SDK messenger example boundaries Split the chat-sdk-messenger example along the boundaries we expect to matter for a future SDK extraction. Keep ChatIngressAgent focused on orchestration while moving provider policy, admin directory mapping, and AI reply delivery helpers into smaller modules. The Telegram provider module now owns webhook setup, HTTPS validation, message delivery limits, long-message chunking, final-edit no-op classification, and Telegram-specific state key sharding. This removes Telegram-specific dedupe key handling from the generic Agents-backed Chat SDK state adapter. The intelligence delivery module now owns managed AI reply fiber names, snapshots, recovery mode, and failure mode policy. The admin directory module owns conversation/job DTOs and row-to-view mapping helpers. These files make the example a better staging ground for deciding what eventually belongs in agents/src/chat-sdk without prematurely extracting Telegram or admin UI product code. Replace the ChatStateAgent recurring cleanup interval with lazy one-shot cleanup scheduling. Expiring writes now schedule the next cleanup only when needed, update the scheduled cleanup when an earlier expiry appears, and reschedule after cleanup only if expiring rows remain. Cleanup metadata tracks the next expiry and schedule id so state shards without expiring records do not pay for a forever schedule, which is a better shape for SDK-owned state infrastructure. Update README/TODO notes to document the module layout and extraction candidates, and adjust tests to cover provider-owned Telegram key sharding instead of baking Telegram behavior into the generic state adapter. Co-authored-by: Cursor <cursoragent@cursor.com> * Add Chat SDK state adapter Co-authored-by: Cursor <cursoragent@cursor.com> * Add favicon to chat-sdk-messenger example Include a favicon for the chat-sdk-messenger example by adding public/favicon.ico and adding a <link rel="icon" href="/favicon.ico" /> in the head of index.html so browsers display the site icon. * Handle post-limit model failures Co-authored-by: Cursor <cursoragent@cursor.com> * Bind conversation facet in messenger tests Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR turns the
chat-sdk-messengerexample into a fuller, reviewable messenger app and extracts its reusable Chat SDK state layer into theagentspackage.Chat SDK state adapter
agents/chat-sdkpackage entrypoint withcreateChatSdkState(),ChatSdkStateAdapter,ChatSdkStateAgent,defaultThreadShard(), anddefaultKeyShard().createChatSdkState()to the built-inChatSdkStateAgentand defaultsparentfromgetCurrentAgent()in normal Agent lifecycle/request contexts.chatas an optional peer dependency foragentsand includes the newchat-sdkentry in the build and package exports.Messenger example
examples/chat-sdk-messengerto consumeagents/chat-sdkrather than carrying its own local state adapter implementation.agentspackage exports instead of localagents/chat-sdkaliases in Vite, Vitest, and TypeScript config.Sub-agent configuration and test harness docs
new_sqlite_classesunless also used as top-level Durable Objects.new_sqlite_classesacross the reviewed test/example configs.@cloudflare/vitest-pool-workerscurrently needs facet classes listed as bindings forctx.exportscompatibility.Repro / notes
Test plan
Ran the focused verification for the package and example:
npm run build -w agentsnpm run typecheck -w @cloudflare/agents-chat-sdk-messengernpm run test:workers -w agents -- src/tests/chat-sdk.test.tsnpm test -w @cloudflare/agents-chat-sdk-messengerNotes:
agents/chat-sdkthrough the built package export, soagentsmust be built before running the example tests locally. This matches the expected CI ordering.npm run build -w agentsstill emits the existingrolldown-plugin-dtswarning about enablingdts.eager, but the build exits successfully.Made with Cursor