UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

85 lines (84 loc) • 3.9 kB
/** * Redis Artifact Store * * The artifact backend for more than one machine. `LocalTempArtifactStore` * writes to a pod's own `/tmp`: a replica that did not store an artifact * cannot read it, a redeploy loses all of them, and `cleanup()` can only * expire what its own process wrote. Here every replica sees every artifact, * Redis expires them by TTL, and a paged read moves only the window. * * Layout, under `keyPrefix` (default `neurolink:artifact:`): * * <prefix><id> STRING the payload, verbatim * <prefix><id>:meta STRING JSON `RedisArtifactRecord` * * Both keys carry the same TTL and are written in one MULTI, so an id either * resolves completely or not at all. * * Range reads are honest about units. `retrieve_context` addresses characters; * `GETRANGE` addresses bytes. The record stores the payload's character length * next to its byte length, and only when the two are equal — pure ASCII, which * is what JSON tool output and logs almost always are — is a byte range used * as a character range. Anything else falls back to a whole read and a slice, * which is slower and still correct. A window never starts on the wrong * character. * * The connection is the same pool Redis conversation memory uses, keyed by * host, port and database, so a deployment that already keeps sessions in * Redis adds no connection by keeping artifacts there too. * * @module artifacts/redisArtifactStore */ import type { ArtifactMeta, ArtifactPageRequest, ArtifactRef, ArtifactStore, ArtifactWindow, RedisStorageConfig } from "../types/index.js"; /** Key prefix when the caller does not choose one. Never the conversation prefix. */ export declare const DEFAULT_ARTIFACT_KEY_PREFIX = "neurolink:artifact:"; /** Expiry when the caller does not choose one, or chooses an unusable one. */ export declare const DEFAULT_ARTIFACT_TTL_SECONDS = 86400; /** * Redis-backed artifact store: shared across replicas, expired by TTL, * range reads for ASCII payloads. * * @example * ```typescript * const store = new RedisArtifactStore({ url: process.env.REDIS_URL }); * const neurolink = new NeuroLink({ artifacts: { store } }); * // or let NeuroLink build it: { artifacts: { storage: "redis" } } * ``` */ export declare class RedisArtifactStore implements ArtifactStore { private readonly config; private client?; private connecting?; /** * @param config - Connection and key settings. `keyPrefix` defaults to * `neurolink:artifact:`. `ttl` is seconds and must be positive; it * defaults to 86400 (24 hours), and zero, negative or non-finite values * are replaced by that default with a warning — artifacts in Redis always * expire, there is no "keep forever". `userSessionsKeyPrefix` is * meaningless here and ignored. */ constructor(config?: RedisStorageConfig); generatePreview(payload: string): string; store(payload: string, meta: Omit<ArtifactMeta, "createdAt">): Promise<ArtifactRef>; retrieve(id: string): Promise<string | null>; retrieveRange(id: string, range: ArtifactPageRequest): Promise<ArtifactWindow | null>; delete(id: string): Promise<void>; /** * Nothing to sweep: Redis expires every artifact `ttl` seconds after it was * written, on every replica at once, which is what `cleanup()` on the local * store could never do. */ cleanup(olderThanMs: number): Promise<number>; /** * Release this store's reference on the pooled connection. * * Waits for a connect that is still in flight: otherwise the reference it * is about to acquire would be assigned after this returned, and nothing * would ever release it. */ close(): Promise<void>; private payloadKey; private metaKey; /** Connect on first use, once, and share the pooled client afterwards. */ private getClient; }