UNPKG

@adonis-agora/agent

Version:

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

78 lines • 3.85 kB
import type { LucidRawRunner } from '../stores/lucid.js'; /** * Text channels' short-lived state, every entry with a TTL: the provider message ids already taken * (so a webhook delivered twice starts one turn), a question waiting for the person's answer, an * outcome already relayed. * * {@link InMemoryChannelStore} only sees its own process. With several replicas a retry, an answer * or a settled proposal can land on another one, so use a shared store there: * {@link lucidChannelStore} (the default when the agent's own store is Lucid), * {@link redisChannelStore}, or your own. */ export interface ChannelStore { /** * Take `key` for `ttlMs` — atomically. `true` when it was free (now taken), `false` when someone * already took it. */ claim(key: string, ttlMs: number): boolean | Promise<boolean>; /** The live value under `key`, or `null`. */ get(key: string): string | null | Promise<string | null>; /** Store `value` under `key` for `ttlMs`, replacing what was there. */ set(key: string, value: string, ttlMs: number): void | Promise<void>; delete(key: string): void | Promise<void>; } /** Process-local {@link ChannelStore}: a single replica, tests, development. */ export declare class InMemoryChannelStore implements ChannelStore { #private; private readonly maxEntries; /** @param maxEntries Past this many live keys, the oldest are forgotten first. */ constructor(maxEntries?: number); claim(key: string, ttlMs: number): boolean; get(key: string): string | null; set(key: string, value: string, ttlMs: number): void; delete(key: string): void; } /** * The slice of a Redis client {@link redisChannelStore} uses — an `@adonisjs/redis` connection * (ioredis) has it: `redisChannelStore(redis)` or `redisChannelStore(redis.connection('main'))`. */ export interface ChannelStoreRedis { set(key: string, value: string, px: 'PX', ttlMs: number, nx: 'NX'): Promise<unknown>; set(key: string, value: string, px: 'PX', ttlMs: number): Promise<unknown>; get(key: string): Promise<string | null>; del(key: string): Promise<unknown>; } /** A {@link ChannelStore} shared by every replica, over Redis (`SET … PX … NX` for claims). */ export declare function redisChannelStore(redis: ChannelStoreRedis, options?: { prefix?: string; }): ChannelStore; export interface LucidChannelStoreOptions { /** A named connection of the `Database` manager. Default: the one `db` is. */ connection?: string; /** Default `agent_channel_state`. */ table?: string; /** * Create the table (and its index) on first use. Default `true`; `false` when a migration owns it * (`createAgentTables` and the published migration create it under the default name). */ autoCreateTables?: boolean; /** How often a claim also deletes expired rows. Default 10 minutes. */ purgeEveryMs?: number; } /** A Lucid `Database` (or one of its connections): raw SQL, and named connections when it has them. */ export type LucidChannelStoreDatabase = LucidRawRunner & { connection?(name?: string): LucidRawRunner; }; /** * A {@link ChannelStore} in the app's SQL database through Lucid — shared by every replica, no Redis * needed. One row per key in `agent_channel_state`; a claim is one `INSERT` that skips on a duplicate * key (`ON CONFLICT DO NOTHING`, `INSERT IGNORE` on MySQL), so the primary key is the lock. Expired * rows are deleted as claims come in (`purgeEveryMs`), and an expired key can be taken again. * * ```ts * import db from '@adonisjs/lucid/services/db' * channels.handle(adapter, { …, store: lucidChannelStore(db) }) * ``` */ export declare function lucidChannelStore(database: LucidChannelStoreDatabase, options?: LucidChannelStoreOptions): ChannelStore; //# sourceMappingURL=store.d.ts.map