@drew-foxall/a2a-js-taskstore-upstash-redis
v0.1.0
Published
Upstash Redis (HTTP-based) task store adapter for A2A SDK
Maintainers
Readme
@drew-foxall/a2a-js-taskstore-upstash-redis
Upstash Redis (HTTP-based) task store adapter for A2A SDK.
Installation
pnpm add @drew-foxall/a2a-js-taskstore-upstash-redis @upstash/redisFeatures
- Edge-compatible: HTTP-based Redis, works everywhere (Cloudflare Workers, Vercel Edge, Deno Deploy)
- No TCP required: Uses REST API instead of TCP connections
- Global replication: Upstash provides global read replicas
- TTL support: Automatic expiration of entries
- Efficient storage: Uses Redis Hash for push configs
Characteristics
| Feature | Value | |---------|-------| | Consistency | Strong (single region), Eventual (global) | | Query flexibility | Medium | | Setup complexity | Low | | Best for | High-throughput, edge deployments |
Setup
1. Create Upstash Redis Database
- Go to Upstash Console
- Create a new Redis database
- Copy the REST URL and token
2. Set Environment Variables
UPSTASH_REDIS_REST_URL=https://your-db.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-tokenUsage
Basic Setup
import { Redis } from '@upstash/redis';
import { UpstashRedisTaskStore, UpstashRedisPushNotificationStore } from '@drew-foxall/a2a-js-taskstore-upstash-redis';
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_URL!,
token: process.env.UPSTASH_REDIS_REST_TOKEN!,
});
const taskStore = new UpstashRedisTaskStore({ client: redis });
const pushStore = new UpstashRedisPushNotificationStore({ client: redis });With Hono on Cloudflare Workers
import { Hono } from 'hono';
import { Redis } from '@upstash/redis';
import { UpstashRedisTaskStore } from '@drew-foxall/a2a-js-taskstore-upstash-redis';
type Bindings = {
UPSTASH_REDIS_REST_URL: string;
UPSTASH_REDIS_REST_TOKEN: string;
};
const app = new Hono<{ Bindings: Bindings }>();
app.all('/a2a/*', async (c) => {
const redis = new Redis({
url: c.env.UPSTASH_REDIS_REST_URL,
token: c.env.UPSTASH_REDIS_REST_TOKEN,
});
const taskStore = new UpstashRedisTaskStore({ client: redis });
// Use with A2A SDK...
});
export default app;With TTL
const taskStore = new UpstashRedisTaskStore({
client: redis,
ttlSeconds: 86400, // 24 hours
});
const pushStore = new UpstashRedisPushNotificationStore({
client: redis,
ttlSeconds: 86400 * 7, // 7 days
});With Custom Prefix
const taskStore = new UpstashRedisTaskStore({
client: redis,
prefix: 'myapp:prod:', // Results in keys like 'myapp:prod:task:123'
});API Reference
UpstashRedisTaskStore
class UpstashRedisTaskStore implements TaskStore {
constructor(options: UpstashRedisTaskStoreOptions);
save(task: Task): Promise<void>;
load(taskId: string): Promise<Task | undefined>;
delete(taskId: string): Promise<void>;
exists(taskId: string): Promise<boolean>;
touch(taskId: string, ttlSeconds?: number): Promise<boolean>;
getTtl(taskId: string): Promise<number>;
}UpstashRedisPushNotificationStore
class UpstashRedisPushNotificationStore implements PushNotificationStore {
constructor(options: UpstashRedisPushNotificationStoreOptions);
save(taskId: string, config: PushNotificationConfig): Promise<void>;
load(taskId: string): Promise<PushNotificationConfig[]>;
delete(taskId: string, configId?: string): Promise<void>;
deleteAll(taskId: string): Promise<void>;
count(taskId: string): Promise<number>;
exists(taskId: string, configId: string): Promise<boolean>;
}Configuration Options
interface UpstashRedisTaskStoreOptions {
// Required
client: Redis;
// Optional
prefix?: string; // Default: 'a2a:'
ttlSeconds?: number; // TTL for entries
}Redis Key Structure
Tasks
- Key:
{prefix}task:{taskId} - Type: String (JSON)
Push Notifications
- Key:
{prefix}push:{taskId} - Type: Hash
- Fields:
{configId}→ JSON config
License
MIT
