feat: add Valkey-backed TaskStore and ResumableStreamStore
RI
3d ago+2164+2164+0123456789012345678901234567890123456789-78-78-01234567890123456789
PR Checklist
Please check if your PR fulfills the following requirements:
- The commit message follows our guidelines: https://voltagent.dev/docs/community/contributing/#commit-convention
Bugs / Features
- Related issue(s) linked https://github.com/VoltAgent/voltagent/issues/1258
- Tests for the changes have been added
- Docs have been added / updated
- Changesets have been added https://voltagent.dev/docs/community/contributing/#creating-a-changeset
What is the current behavior?
The @voltagent/a2a-server and @voltagent/resumable-streams packages only support in-memory storage. Task state and stream data are lost on restart and cannot be shared across multiple server instances.
What is the new behavior?
Adds Valkey-backed store implementations to both packages using the @valkey/valkey-glide client library:
@voltagent/a2a-server
- New
ValkeyTaskStoreclass implementing theTaskStoreinterface with composite key generation, JSON serialization, and optional TTL-based expiration. createValkeyTaskStorefactory function for easy instantiation.- New
taskStoreoption onA2AServerConfigso a store can be provided at construction time.
@voltagent/resumable-streams
- New
createResumableStreamValkeyStorefactory that wires Valkey pub/sub into the resumable-stream generic context, with per-channel dedicated GlideClient connections and a configurable max subscription limit (default 1000). - TTL support for active stream keys via optional
ttlSeconds. - Exports internal utilities (
markResumableStreamStoreType,buildActiveStreamKey,createActiveStreamStoreFromPublisher,mergeStreamAndActiveStore) for reuse by custom store implementations.
Shared
@valkey/valkey-glideadded as an optional peer dependency in both packages so consumers who don't use Valkey are unaffected.- Both stores support standalone and cluster Valkey deployments, configurable key prefixes, and optional TTL.
Example
- New
examples/with-valkey-storeproject demonstrating end-to-end integration of both stores with a SupportAgent, including environment config template and README.
Tests
- Comprehensive unit tests for
ValkeyTaskStore(load, save, error handling, cancellations, factory function). - Comprehensive unit tests for
createResumableStreamValkeyStore(publisher/subscriber adapters, TTL, subscription limits, close cleanup).
Notes for reviewers
- The
@valkey/valkey-glidepeer dependency is optional, no impact on existing consumers. - The resumable-streams Valkey store creates one dedicated GlideClient per subscription channel, which is a requirement of the Glide pub/sub model. The
maxSubscriptionsoption (default 1000) caps resource usage.
Summary by CodeRabbit
- New Features
- Added Valkey-backed persistence for A2A tasks and resumable streams, with configurable key prefixes and optional expiration. Supports standalone and cluster deployments.
- Added a Valkey store example with a sample assistant and setup instructions.
- Bug Fixes
- Agent failures are now recorded in task history and reflected in the task’s failed status.
- Invalid message content is rejected during request validation.
- Breaking Changes
- Server configuration can now specify a task store, taking precedence over an injected store or the in-memory fallback.
- Tests
- Added coverage for Valkey task and resumable-stream storage.