@cloudflare/ai-chat@0.8.3

cloudflare/agents@cloudflare/ai-chat@0.8.3Jun 5, 2026by github-actions[bot]

AI Summary

This patch release (@cloudflare/ai-chat@0.8.3) optimizes SQLite write performance by batching and packing chat-persistence operations, reducing database rows written and round-trips by up to ~10×. The changes include packing stream chunks into single SQLite rows, batched DELETE queries for message cleanup and submission deletion, and batched incident TTL sweeps.

Key Highlights

  • ResumableStream now packs buffered stream chunks into single SQLite rows (JSON arrays) instead of one row per chunk, reducing storage by ~10×
  • Message cleanup now uses batched DELETE ... WHERE id IN (...) queries instead of individual DELETE statements per row
  • @cloudflare/think deleteSubmissions() now batch deletes terminal submissions in a single query
  • Chat-recovery incident TTL sweep now uses batched storage.delete(keys) calls (up to 128 keys) instead of individual awaited deletes
  • Backward compatible: reads transparently unpack both new packed segments and legacy per-chunk rows

New Features

  • Packed SQLite storage for stream chunks (JSON arrays of chunk bodies) with per-segment byte cap for 2 MB limit
  • Batched DELETE queries with configurable bound parameter limits (100 for messages, full batch for submissions)
  • Batched storage.delete() calls for incident cleanup (up to 128 keys per call)
  • New shared helpers exported: buildInClauseStrings and MAX_BOUND_PARAMS from agents/chat

Full Release Notes

### Patch Changes

-   [#1686](https://github.com/cloudflare/agents/pull/1686) [`1e49880`](https://github.com/cloudflare/agents/commit/1e498803fe26970aa264678d5ae3a2c96dd28258) Thanks [@threepointone](https://github.com/threepointone)! - Batch and pack chat-persistence SQLite writes to reduce rows written and round-trips.
    -   `agents`: `ResumableStream` now **packs** each buffered group of stream chunks into a single SQLite row (a JSON array of chunk bodies) instead of writing one row per chunk. Single-chunk and large-chunk segments are stored unwrapped, and a per-segment byte cap keeps rows within the 2 MB SQLite row limit. This cuts chunk rows written / stored / scanned-on-replay by up to ~10×. Reads (replay, orphan reconstruction, `getStreamChunks`) transparently unpack both packed segments and legacy per-chunk rows, so existing stored data keeps working. Adds shared `buildInClauseStrings` and `MAX_BOUND_PARAMS` helpers exported from `agents/chat`.
    -   `@cloudflare/ai-chat`: message cleanup (stale-row pruning and `maxPersistedMessages` enforcement) previously issued one `DELETE` per row in a loop; it now deletes rows in batched `DELETE ... WHERE id IN (...)` queries (capped at 100 bound parameters per query).
    -   `@cloudflare/think`: `deleteSubmissions()` cleanup previously issued one `DELETE` per terminal submission (up to 500 per call); it now deletes rows in batched `DELETE ... WHERE submission_id IN (...)` queries.
    -   `@cloudflare/ai-chat` & `@cloudflare/think`: chat-recovery incident TTL sweep previously deleted each stale incident with a separate awaited `storage.delete(key)` (which also defeats Durable Object write-coalescing); it now deletes incidents in batched `storage.delete(keys)` calls (up to 128 keys per call).