UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

48 lines • 2.81 kB
import type { RedisStreamClient } from './redis-stream-client.js'; import type { SinkWriter, StreamFrame, TokenStreamSink } from './spi/token-stream-sink.js'; export interface RedisTokenStreamSinkOptions { /** Key/channel namespace. Defaults to `agent:stream`. Keys are `${keyPrefix}:${runId}:...`. */ keyPrefix?: string; /** * TTL (seconds) applied to a run's `chunks`/`state` keys so they self-expire — the framework never * calls {@link RedisTokenStreamSink.close}, so without this the replay buffer would accumulate in * Redis forever. The TTL is a sliding window refreshed on every write, so a long run stays alive and * a crashed run (that never `end`s) still expires. Defaults to 3600 (1h). Set `0` to disable and * retain keys until `close()`/manual cleanup (the pre-TTL behaviour). */ ttlSeconds?: number; } /** * A multi-replica {@link TokenStreamSink} over Redis — the shared-transport counterpart to the default * {@link import('./in-process-sink.js').InProcessTokenStreamSink}. The replica running the model turn * `open`s the writer and appends each token chunk to a Redis LIST (`${keyPrefix}:${runId}:chunks`) so * ANY replica can replay the whole stream so far (the same late-subscriber/reconnect guarantee the * in-process sink gives, but shared across pods), and PUBLISHes to a per-run channel * (`${keyPrefix}:${runId}`) to wake live subscribers. The run's terminal state lives in a marker key * (`${keyPrefix}:${runId}:state`), so an SSE handler on ANOTHER replica that subscribes after the run * finished still sees the ending and closes the stream. * * The yielded frames are identical (frame-for-frame) to the in-process sink's, so the agent-protocol * SSE the provider pipes is unchanged — swapping this in is transparent to clients. * * The host supplies a {@link RedisStreamClient} adapter over its own Redis driver; `subscribe` needs a * connection in subscriber mode (see the client docs). Wire it with `defineConfig({ sink: * tokenSinks.redis({...}) })`, which builds the adapter over `@adonisjs/redis` lazily. */ export declare class RedisTokenStreamSink implements TokenStreamSink { private readonly client; private readonly keyPrefix; private readonly ttlSeconds; constructor(client: RedisStreamClient, options?: RedisTokenStreamSinkOptions); /** Refresh the sliding TTL on `key` (no-op when TTL is disabled or the client can't `expire`). */ private touchTtl; private chunksKey; private stateKey; private channel; open(runId: string): SinkWriter; subscribe(runId: string): AsyncIterable<StreamFrame>; has(runId: string): Promise<boolean>; close(runId: string): Promise<void>; private hasEnded; } //# sourceMappingURL=redis-token-stream-sink.d.ts.map