/** * FlairStore — LangGraph BaseStore implementation backed by Flair. * * Lets a LangGraph agent persist long-term memory ("Store" in LangGraph * vocabulary) into a Flair instance, getting crypto-pinned per-agent * identity, federated peer-to-peer sync, and cross-orchestrator portability * for free. The same memories are then visible to any other Flair-enabled * harness (Claude Code via flair-mcp, OpenClaw via openclaw-flair, n8n via * n8n-nodes-flair, Hermes via hermes-flair, Pi via pi-flair). * * The adapter implements the abstract `batch()` method that every BaseStore * subclass must provide. The base class's concrete `get/put/search/delete/ * listNamespaces` helpers all funnel through `batch()`, so we get the full * surface from one entry point. * * # Mapping * * LangGraph Flair * --------- ----- * namespace: string[] tags: ["lg-ns:", "lg-ns-part:"] * key: string id suffix (full id: "lg:::") * value: object content: JSON.stringify(value) * search.query SemanticSearch q * search.filter (eq/gt/lt) applied client-side after retrieval * put(value=null) DELETE * * Namespace fan-out: each namespace label gets its own tag prefixed with * `lg-ns-part:` so search filters can match prefixes, plus the full joined * namespace as `lg-ns:` for exact lookups. (LangGraph forbids periods in * labels, so we use `/` as the separator.) * * # Limitations (v1) * * - LangGraph's `IndexConfig` (custom embedding model + per-field indexing) * is ignored. Flair has its own embedding pipeline (nomic-embed-text-v1.5) * and embeds the full content blob. If you need per-field embedding, * pre-extract the fields and put them as separate items. * - `search.filter` operators ($eq/$ne/$gt/$gte/$lt/$lte) are applied * client-side after retrieving the namespace prefix, so filter-heavy * workloads can incur a network round-trip per matching memory. Tag-based * pre-filtering (the namespace prefix) keeps this bounded in practice. * - `listNamespaces` returns namespaces seen in the agent's stored memories. * It can't enumerate empty namespaces. * * # Auth * * Inherits from FlairClient — Ed25519 keypair if available (preferred), or * Basic auth via FLAIR_ADMIN_PASS for standalone deployments. */ interface Item { value: Record; key: string; namespace: string[]; createdAt: Date; updatedAt: Date; } interface SearchItem extends Item { score?: number; } interface GetOperation { namespace: string[]; key: string; } interface SearchOperation { namespacePrefix: string[]; filter?: Record; limit?: number; offset?: number; query?: string; } interface PutOperation { namespace: string[]; key: string; value: Record | null; index?: false | string[]; } interface ListNamespacesOperation { matchConditions?: any[]; maxDepth?: number; limit: number; offset: number; } type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation; /** * Apply a single LangGraph filter operator. Mirrors BaseStore's documented * surface: $eq (default), $ne, $gt, $gte, $lt, $lte. Bare values are $eq. * * Exported for unit testing (Kern review on #370 — non-trivial logic with * 7 branches must have coverage). */ export declare function matchesFilter(value: any, condition: any): boolean; /** Apply all field filters in a search request. Logical AND across fields. */ export declare function matchesAllFilters(value: Record, filter: Record | undefined): boolean; /** * Configuration for FlairStore. Same shape as FlairClient's config plus * one extra: `agentId` is required (LangGraph isn't agent-aware on its own, * so we pin it at construction time). */ export interface FlairStoreConfig { /** Required. The Flair agent identity to scope all memories under. */ agentId: string; /** Flair URL. Defaults to FLAIR_URL env or http://localhost:19926. */ url?: string; /** Path to Ed25519 private key file. Auto-resolved from agent id if omitted. */ keyPath?: string; /** Or pass the key directly as PEM string. */ privateKey?: string; /** Basic-auth fallback for standalone deployments without Ed25519. */ adminUser?: string; adminPassword?: string; /** Request timeout in ms. Default 30s. */ timeoutMs?: number; } /** * FlairStore — drop-in replacement for LangGraph's `InMemoryStore` that * persists into Flair. Extends LangGraph's `BaseStore` interface * structurally without importing the abstract class directly (peer-dep * pattern keeps the package install-light if a host already has langgraph). * * Usage: * import { FlairStore } from "@tpsdev-ai/langgraph-flair"; * const store = new FlairStore({ agentId: "my-agent" }); * const graph = new StateGraph(...).compile({ store }); * * Or pass it to the agent directly: * const agent = createReactAgent({ llm, tools, store }); */ export declare class FlairStore { private client; private agentId; constructor(config: FlairStoreConfig); /** The LangGraph-required entry point. All concrete operations funnel here. */ batch(operations: Op): Promise; get(namespace: string[], key: string): Promise; put(namespace: string[], key: string, value: Record, index?: false | string[]): Promise; delete(namespace: string[], key: string): Promise; search(namespacePrefix: string[], options?: { filter?: Record; limit?: number; offset?: number; query?: string; }): Promise; private dispatch; private doGet; private doPut; private doSearch; private doListNamespaces; } export declare function parseStoredId(id: string, agentId: string): { namespace: string[]; key: string; } | null; export declare function hasNamespacePrefix(namespace: string[], prefix: string[]): boolean; export type { Item, SearchItem, GetOperation, PutOperation, SearchOperation, ListNamespacesOperation }; //# sourceMappingURL=index.d.ts.map