@tpsdev-ai/langgraph-flair 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # @tpsdev-ai/langgraph-flair
2
+
3
+ LangGraph `BaseStore` adapter backed by [Flair](https://github.com/tpsdev-ai/flair) — durable agent memory with crypto-pinned per-agent identity, federated peer-to-peer sync, and cross-orchestrator portability.
4
+
5
+ Drop-in for LangGraph's `InMemoryStore`. The same memories your LangGraph agent writes are then visible to every other Flair-enabled harness:
6
+
7
+ - Claude Code / Cursor / Continue.dev / Codex (via [`@tpsdev-ai/flair-mcp`](../flair-mcp))
8
+ - OpenClaw (via [`@tpsdev-ai/openclaw-flair`](../openclaw-flair))
9
+ - n8n (via [`@tpsdev-ai/n8n-nodes-flair`](../n8n-nodes-flair))
10
+ - Hermes Agent (via [`hermes-flair`](../hermes-flair))
11
+ - Pi agent (via [`@tpsdev-ai/pi-flair`](../pi-flair))
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @tpsdev-ai/langgraph-flair @tpsdev-ai/flair-client
17
+ # Or, if you're already using LangGraph:
18
+ npm install @tpsdev-ai/langgraph-flair
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```typescript
24
+ import { FlairStore } from "@tpsdev-ai/langgraph-flair";
25
+ import { StateGraph } from "@langchain/langgraph";
26
+
27
+ const store = new FlairStore({ agentId: "my-agent" });
28
+
29
+ const graph = new StateGraph(...)
30
+ .compile({ store });
31
+
32
+ // Or with createReactAgent:
33
+ import { createReactAgent } from "@langchain/langgraph/prebuilt";
34
+ const agent = createReactAgent({ llm, tools, store });
35
+ ```
36
+
37
+ ## How LangGraph's namespace maps to Flair
38
+
39
+ LangGraph's `BaseStore` uses hierarchical namespaces (`["users", "profiles"]`) and string keys (`"user123"`). FlairStore maps each item to a Flair memory:
40
+
41
+ | LangGraph | Flair |
42
+ |-----------|-------|
43
+ | `namespace: ["users", "profiles"]` | `tags: ["lg-ns:users/profiles"]` |
44
+ | `key: "user123"` | id suffix: `lg:<agentId>:users/profiles:user123` |
45
+ | `value: { name: "Alice" }` | `content: '{"name":"Alice"}'` |
46
+ | `search.query: "..."` | semantic search via Flair's HNSW index |
47
+ | `search.filter: { age: { $gte: 18 } }` | applied client-side after retrieval |
48
+
49
+ ## Authentication
50
+
51
+ `FlairStore` inherits from `FlairClient`. Three options:
52
+
53
+ 1. **Ed25519 keypair** (preferred): set `FLAIR_AGENT_ID` and the client auto-resolves your key.
54
+ 2. **Explicit key path**: `new FlairStore({ agentId, keyPath: "/path/to/key.pem" })`
55
+ 3. **Basic auth fallback**: `new FlairStore({ agentId, adminUser, adminPassword })` for standalone deployments.
56
+
57
+ ```typescript
58
+ const store = new FlairStore({
59
+ agentId: "my-agent",
60
+ url: "https://flair.example.com", // or FLAIR_URL env var
61
+ adminPassword: process.env.FLAIR_ADMIN_PASS,
62
+ });
63
+ ```
64
+
65
+ ## What you get
66
+
67
+ - **Persistence**: memories survive process restarts and re-deploys.
68
+ - **Federation**: pair your local Flair to a hub; memories sync peer-to-peer.
69
+ - **Cross-orchestrator**: switch from LangGraph to OpenClaw to Claude Code without losing the agent's history.
70
+ - **Identity**: every memory is tied to a crypto-pinned `agentId`. No tenant-isolation slop.
71
+ - **Open source**: runs on your hardware. No SaaS lock-in.
72
+
73
+ ## Limitations (v1)
74
+
75
+ - LangGraph's `IndexConfig` (custom embedding model, per-field indexing) is ignored. Flair has its own embedding pipeline (`nomic-embed-text-v1.5`, 768-dim) and embeds the full content blob. If you need per-field embeddings, pre-extract and store as separate items.
76
+ - `search.filter` operators (`$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`) are applied client-side after retrieving the namespace prefix. Tag-based pre-filtering (the namespace) keeps this bounded; high-fanout filters across many memories will be slower.
77
+ - Namespace-prefix matching uses the full joined-path tag (`lg-ns:users/profiles`). Items in `["users", "profiles", "u123"]` are reachable via the `["users", "profiles"]` prefix because the search routine post-filters parsed namespaces against the requested prefix — but searching by a *single label anywhere in the namespace* (e.g. "all items with `profiles` somewhere") isn't supported. LangGraph's `BaseStore.search` API doesn't expose this surface either, so there's no read path that would benefit; if a future LangGraph extension adds it we'll add a derived index then.
78
+ - `listNamespaces` returns namespaces seen in your stored memories (best-effort scan). Empty namespaces aren't enumerable.
79
+
80
+ ## License
81
+
82
+ Apache 2.0 — same as Flair core.
@@ -0,0 +1,155 @@
1
+ /**
2
+ * FlairStore — LangGraph BaseStore implementation backed by Flair.
3
+ *
4
+ * Lets a LangGraph agent persist long-term memory ("Store" in LangGraph
5
+ * vocabulary) into a Flair instance, getting crypto-pinned per-agent
6
+ * identity, federated peer-to-peer sync, and cross-orchestrator portability
7
+ * for free. The same memories are then visible to any other Flair-enabled
8
+ * harness (Claude Code via flair-mcp, OpenClaw via openclaw-flair, n8n via
9
+ * n8n-nodes-flair, Hermes via hermes-flair, Pi via pi-flair).
10
+ *
11
+ * The adapter implements the abstract `batch()` method that every BaseStore
12
+ * subclass must provide. The base class's concrete `get/put/search/delete/
13
+ * listNamespaces` helpers all funnel through `batch()`, so we get the full
14
+ * surface from one entry point.
15
+ *
16
+ * # Mapping
17
+ *
18
+ * LangGraph Flair
19
+ * --------- -----
20
+ * namespace: string[] tags: ["lg-ns:<joined>", "lg-ns-part:<each>"]
21
+ * key: string id suffix (full id: "lg:<agentId>:<ns>:<key>")
22
+ * value: object content: JSON.stringify(value)
23
+ * search.query SemanticSearch q
24
+ * search.filter (eq/gt/lt) applied client-side after retrieval
25
+ * put(value=null) DELETE
26
+ *
27
+ * Namespace fan-out: each namespace label gets its own tag prefixed with
28
+ * `lg-ns-part:` so search filters can match prefixes, plus the full joined
29
+ * namespace as `lg-ns:` for exact lookups. (LangGraph forbids periods in
30
+ * labels, so we use `/` as the separator.)
31
+ *
32
+ * # Limitations (v1)
33
+ *
34
+ * - LangGraph's `IndexConfig` (custom embedding model + per-field indexing)
35
+ * is ignored. Flair has its own embedding pipeline (nomic-embed-text-v1.5)
36
+ * and embeds the full content blob. If you need per-field embedding,
37
+ * pre-extract the fields and put them as separate items.
38
+ * - `search.filter` operators ($eq/$ne/$gt/$gte/$lt/$lte) are applied
39
+ * client-side after retrieving the namespace prefix, so filter-heavy
40
+ * workloads can incur a network round-trip per matching memory. Tag-based
41
+ * pre-filtering (the namespace prefix) keeps this bounded in practice.
42
+ * - `listNamespaces` returns namespaces seen in the agent's stored memories.
43
+ * It can't enumerate empty namespaces.
44
+ *
45
+ * # Auth
46
+ *
47
+ * Inherits from FlairClient — Ed25519 keypair if available (preferred), or
48
+ * Basic auth via FLAIR_ADMIN_PASS for standalone deployments.
49
+ */
50
+ interface Item {
51
+ value: Record<string, any>;
52
+ key: string;
53
+ namespace: string[];
54
+ createdAt: Date;
55
+ updatedAt: Date;
56
+ }
57
+ interface SearchItem extends Item {
58
+ score?: number;
59
+ }
60
+ interface GetOperation {
61
+ namespace: string[];
62
+ key: string;
63
+ }
64
+ interface SearchOperation {
65
+ namespacePrefix: string[];
66
+ filter?: Record<string, any>;
67
+ limit?: number;
68
+ offset?: number;
69
+ query?: string;
70
+ }
71
+ interface PutOperation {
72
+ namespace: string[];
73
+ key: string;
74
+ value: Record<string, any> | null;
75
+ index?: false | string[];
76
+ }
77
+ interface ListNamespacesOperation {
78
+ matchConditions?: any[];
79
+ maxDepth?: number;
80
+ limit: number;
81
+ offset: number;
82
+ }
83
+ type Operation = GetOperation | SearchOperation | PutOperation | ListNamespacesOperation;
84
+ /**
85
+ * Apply a single LangGraph filter operator. Mirrors BaseStore's documented
86
+ * surface: $eq (default), $ne, $gt, $gte, $lt, $lte. Bare values are $eq.
87
+ *
88
+ * Exported for unit testing (Kern review on #370 — non-trivial logic with
89
+ * 7 branches must have coverage).
90
+ */
91
+ export declare function matchesFilter(value: any, condition: any): boolean;
92
+ /** Apply all field filters in a search request. Logical AND across fields. */
93
+ export declare function matchesAllFilters(value: Record<string, any>, filter: Record<string, any> | undefined): boolean;
94
+ /**
95
+ * Configuration for FlairStore. Same shape as FlairClient's config plus
96
+ * one extra: `agentId` is required (LangGraph isn't agent-aware on its own,
97
+ * so we pin it at construction time).
98
+ */
99
+ export interface FlairStoreConfig {
100
+ /** Required. The Flair agent identity to scope all memories under. */
101
+ agentId: string;
102
+ /** Flair URL. Defaults to FLAIR_URL env or http://localhost:19926. */
103
+ url?: string;
104
+ /** Path to Ed25519 private key file. Auto-resolved from agent id if omitted. */
105
+ keyPath?: string;
106
+ /** Or pass the key directly as PEM string. */
107
+ privateKey?: string;
108
+ /** Basic-auth fallback for standalone deployments without Ed25519. */
109
+ adminUser?: string;
110
+ adminPassword?: string;
111
+ /** Request timeout in ms. Default 30s. */
112
+ timeoutMs?: number;
113
+ }
114
+ /**
115
+ * FlairStore — drop-in replacement for LangGraph's `InMemoryStore` that
116
+ * persists into Flair. Extends LangGraph's `BaseStore` interface
117
+ * structurally without importing the abstract class directly (peer-dep
118
+ * pattern keeps the package install-light if a host already has langgraph).
119
+ *
120
+ * Usage:
121
+ * import { FlairStore } from "@tpsdev-ai/langgraph-flair";
122
+ * const store = new FlairStore({ agentId: "my-agent" });
123
+ * const graph = new StateGraph(...).compile({ store });
124
+ *
125
+ * Or pass it to the agent directly:
126
+ * const agent = createReactAgent({ llm, tools, store });
127
+ */
128
+ export declare class FlairStore {
129
+ private client;
130
+ private agentId;
131
+ constructor(config: FlairStoreConfig);
132
+ /** The LangGraph-required entry point. All concrete operations funnel here. */
133
+ batch<Op extends Operation[]>(operations: Op): Promise<any[]>;
134
+ get(namespace: string[], key: string): Promise<Item | null>;
135
+ put(namespace: string[], key: string, value: Record<string, any>, index?: false | string[]): Promise<void>;
136
+ delete(namespace: string[], key: string): Promise<void>;
137
+ search(namespacePrefix: string[], options?: {
138
+ filter?: Record<string, any>;
139
+ limit?: number;
140
+ offset?: number;
141
+ query?: string;
142
+ }): Promise<SearchItem[]>;
143
+ private dispatch;
144
+ private doGet;
145
+ private doPut;
146
+ private doSearch;
147
+ private doListNamespaces;
148
+ }
149
+ export declare function parseStoredId(id: string, agentId: string): {
150
+ namespace: string[];
151
+ key: string;
152
+ } | null;
153
+ export declare function hasNamespacePrefix(namespace: string[], prefix: string[]): boolean;
154
+ export type { Item, SearchItem, GetOperation, PutOperation, SearchOperation, ListNamespacesOperation };
155
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAQH,UAAU,IAAI;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,UAAU,UAAW,SAAQ,IAAI;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,eAAe;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;CAC1B;AAED,UAAU,uBAAuB;IAC/B,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,SAAS,GACV,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,uBAAuB,CAAC;AAqC5B;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,GAAG,OAAO,CAgBjE;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,OAAO,CAM9G;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,gBAAgB;IAgBpC,+EAA+E;IACzE,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAO7D,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAI3D,GAAG,CACP,SAAS,EAAE,MAAM,EAAE,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1B,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;IAIV,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,MAAM,CACV,eAAe,EAAE,MAAM,EAAE,EACzB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAC9F,OAAO,CAAC,UAAU,EAAE,CAAC;YAMV,QAAQ;YAQR,KAAK;YAOL,KAAK;YAkBL,QAAQ;YAiER,gBAAgB;CAuB/B;AAID,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYtG;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAMjF;AAmBD,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,uBAAuB,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,352 @@
1
+ /**
2
+ * FlairStore — LangGraph BaseStore implementation backed by Flair.
3
+ *
4
+ * Lets a LangGraph agent persist long-term memory ("Store" in LangGraph
5
+ * vocabulary) into a Flair instance, getting crypto-pinned per-agent
6
+ * identity, federated peer-to-peer sync, and cross-orchestrator portability
7
+ * for free. The same memories are then visible to any other Flair-enabled
8
+ * harness (Claude Code via flair-mcp, OpenClaw via openclaw-flair, n8n via
9
+ * n8n-nodes-flair, Hermes via hermes-flair, Pi via pi-flair).
10
+ *
11
+ * The adapter implements the abstract `batch()` method that every BaseStore
12
+ * subclass must provide. The base class's concrete `get/put/search/delete/
13
+ * listNamespaces` helpers all funnel through `batch()`, so we get the full
14
+ * surface from one entry point.
15
+ *
16
+ * # Mapping
17
+ *
18
+ * LangGraph Flair
19
+ * --------- -----
20
+ * namespace: string[] tags: ["lg-ns:<joined>", "lg-ns-part:<each>"]
21
+ * key: string id suffix (full id: "lg:<agentId>:<ns>:<key>")
22
+ * value: object content: JSON.stringify(value)
23
+ * search.query SemanticSearch q
24
+ * search.filter (eq/gt/lt) applied client-side after retrieval
25
+ * put(value=null) DELETE
26
+ *
27
+ * Namespace fan-out: each namespace label gets its own tag prefixed with
28
+ * `lg-ns-part:` so search filters can match prefixes, plus the full joined
29
+ * namespace as `lg-ns:` for exact lookups. (LangGraph forbids periods in
30
+ * labels, so we use `/` as the separator.)
31
+ *
32
+ * # Limitations (v1)
33
+ *
34
+ * - LangGraph's `IndexConfig` (custom embedding model + per-field indexing)
35
+ * is ignored. Flair has its own embedding pipeline (nomic-embed-text-v1.5)
36
+ * and embeds the full content blob. If you need per-field embedding,
37
+ * pre-extract the fields and put them as separate items.
38
+ * - `search.filter` operators ($eq/$ne/$gt/$gte/$lt/$lte) are applied
39
+ * client-side after retrieving the namespace prefix, so filter-heavy
40
+ * workloads can incur a network round-trip per matching memory. Tag-based
41
+ * pre-filtering (the namespace prefix) keeps this bounded in practice.
42
+ * - `listNamespaces` returns namespaces seen in the agent's stored memories.
43
+ * It can't enumerate empty namespaces.
44
+ *
45
+ * # Auth
46
+ *
47
+ * Inherits from FlairClient — Ed25519 keypair if available (preferred), or
48
+ * Basic auth via FLAIR_ADMIN_PASS for standalone deployments.
49
+ */
50
+ import { FlairClient } from "@tpsdev-ai/flair-client";
51
+ const NS_SEP = "/"; // LangGraph forbids periods in namespace labels
52
+ const TAG_PREFIX_FULL = "lg-ns:";
53
+ /** Single namespace tag — the joined-path form (e.g. "lg-ns:users/profiles").
54
+ *
55
+ * We previously also wrote per-segment tags (lg-ns-part:users, lg-ns-part:
56
+ * profiles) for "contains-label" queries, but LangGraph's BaseStore.search
57
+ * contract takes a `namespacePrefix` array — there's no surface for "items
58
+ * containing this label anywhere." The per-part tags inflated the Harper
59
+ * tag index with no read path. Dropped per Kern's review on #370.
60
+ *
61
+ * If a future LangGraph extension exposes a "search by label" API, we can
62
+ * add a derived index then — until then, dead storage is worse than a
63
+ * documented gap. */
64
+ function nsTags(namespace) {
65
+ return [`${TAG_PREFIX_FULL}${namespace.join(NS_SEP)}`];
66
+ }
67
+ function memoryId(agentId, namespace, key) {
68
+ return `lg:${agentId}:${namespace.join(NS_SEP)}:${key}`;
69
+ }
70
+ function isGet(op) {
71
+ return "key" in op && !("value" in op);
72
+ }
73
+ function isPut(op) {
74
+ return "key" in op && "value" in op;
75
+ }
76
+ function isSearch(op) {
77
+ return "namespacePrefix" in op;
78
+ }
79
+ function isListNs(op) {
80
+ return !("namespace" in op) && !("namespacePrefix" in op);
81
+ }
82
+ /**
83
+ * Apply a single LangGraph filter operator. Mirrors BaseStore's documented
84
+ * surface: $eq (default), $ne, $gt, $gte, $lt, $lte. Bare values are $eq.
85
+ *
86
+ * Exported for unit testing (Kern review on #370 — non-trivial logic with
87
+ * 7 branches must have coverage).
88
+ */
89
+ export function matchesFilter(value, condition) {
90
+ if (condition === null || typeof condition !== "object") {
91
+ return value === condition;
92
+ }
93
+ for (const [op, cmp] of Object.entries(condition)) {
94
+ switch (op) {
95
+ case "$eq":
96
+ if (value !== cmp)
97
+ return false;
98
+ break;
99
+ case "$ne":
100
+ if (value === cmp)
101
+ return false;
102
+ break;
103
+ case "$gt":
104
+ if (!(value > cmp))
105
+ return false;
106
+ break;
107
+ case "$gte":
108
+ if (!(value >= cmp))
109
+ return false;
110
+ break;
111
+ case "$lt":
112
+ if (!(value < cmp))
113
+ return false;
114
+ break;
115
+ case "$lte":
116
+ if (!(value <= cmp))
117
+ return false;
118
+ break;
119
+ default: return value === condition; // unknown operator → bare-eq fallback
120
+ }
121
+ }
122
+ return true;
123
+ }
124
+ /** Apply all field filters in a search request. Logical AND across fields. */
125
+ export function matchesAllFilters(value, filter) {
126
+ if (!filter)
127
+ return true;
128
+ for (const [field, condition] of Object.entries(filter)) {
129
+ if (!matchesFilter(value[field], condition))
130
+ return false;
131
+ }
132
+ return true;
133
+ }
134
+ /**
135
+ * FlairStore — drop-in replacement for LangGraph's `InMemoryStore` that
136
+ * persists into Flair. Extends LangGraph's `BaseStore` interface
137
+ * structurally without importing the abstract class directly (peer-dep
138
+ * pattern keeps the package install-light if a host already has langgraph).
139
+ *
140
+ * Usage:
141
+ * import { FlairStore } from "@tpsdev-ai/langgraph-flair";
142
+ * const store = new FlairStore({ agentId: "my-agent" });
143
+ * const graph = new StateGraph(...).compile({ store });
144
+ *
145
+ * Or pass it to the agent directly:
146
+ * const agent = createReactAgent({ llm, tools, store });
147
+ */
148
+ export class FlairStore {
149
+ client;
150
+ agentId;
151
+ constructor(config) {
152
+ if (!config.agentId) {
153
+ throw new Error("FlairStore requires `agentId` — pin the agent identity at construction time.");
154
+ }
155
+ this.agentId = config.agentId;
156
+ this.client = new FlairClient({
157
+ agentId: config.agentId,
158
+ url: config.url,
159
+ keyPath: config.keyPath,
160
+ privateKey: config.privateKey,
161
+ adminUser: config.adminUser,
162
+ adminPassword: config.adminPassword,
163
+ timeoutMs: config.timeoutMs,
164
+ });
165
+ }
166
+ /** The LangGraph-required entry point. All concrete operations funnel here. */
167
+ async batch(operations) {
168
+ return Promise.all(operations.map((op) => this.dispatch(op)));
169
+ }
170
+ // The same surface BaseStore exposes as concrete methods. Reproduced here
171
+ // so callers don't have to subclass to get them.
172
+ async get(namespace, key) {
173
+ return this.dispatch({ namespace, key });
174
+ }
175
+ async put(namespace, key, value, index) {
176
+ await this.dispatch({ namespace, key, value, index });
177
+ }
178
+ async delete(namespace, key) {
179
+ await this.dispatch({ namespace, key, value: null });
180
+ }
181
+ async search(namespacePrefix, options = {}) {
182
+ return this.dispatch({ namespacePrefix, ...options });
183
+ }
184
+ // ── private dispatch ─────────────────────────────────────────────────────
185
+ async dispatch(op) {
186
+ if (isGet(op))
187
+ return this.doGet(op);
188
+ if (isPut(op))
189
+ return this.doPut(op);
190
+ if (isSearch(op))
191
+ return this.doSearch(op);
192
+ if (isListNs(op))
193
+ return this.doListNamespaces(op);
194
+ throw new Error("FlairStore: unknown operation");
195
+ }
196
+ async doGet(op) {
197
+ const id = memoryId(this.agentId, op.namespace, op.key);
198
+ const mem = await this.client.memory.get(id);
199
+ if (!mem)
200
+ return null;
201
+ return memoryToItem(mem, op.namespace, op.key);
202
+ }
203
+ async doPut(op) {
204
+ const id = memoryId(this.agentId, op.namespace, op.key);
205
+ if (op.value === null) {
206
+ await this.client.memory.delete(id);
207
+ return;
208
+ }
209
+ const tags = nsTags(op.namespace);
210
+ const content = JSON.stringify(op.value);
211
+ // Subject lets Flair index the namespace head for fast prefix filtering.
212
+ const subject = op.namespace[0] ?? undefined;
213
+ await this.client.memory.write(content, {
214
+ id,
215
+ tags,
216
+ subject,
217
+ durability: "standard",
218
+ });
219
+ }
220
+ async doSearch(op) {
221
+ const limit = op.limit ?? 10;
222
+ const offset = op.offset ?? 0;
223
+ let candidates;
224
+ if (op.query) {
225
+ // Semantic search via Flair, then filter by namespace prefix client-side.
226
+ // Fetch a generous candidate pool so the post-filter still honors `limit`.
227
+ const fetched = await this.client.memory.search(op.query, {
228
+ limit: Math.max(limit + offset, 20) * 4,
229
+ });
230
+ candidates = fetched.map((r) => ({
231
+ id: r.id,
232
+ content: r.content,
233
+ score: r.score,
234
+ createdAt: r.createdAt,
235
+ tags: r.tags,
236
+ }));
237
+ }
238
+ else {
239
+ // Tag-based listing for the namespace prefix.
240
+ const fullTag = `${TAG_PREFIX_FULL}${op.namespacePrefix.join(NS_SEP)}`;
241
+ const fetched = await this.client.memory.list({
242
+ tags: op.namespacePrefix.length > 0 ? [fullTag] : [],
243
+ limit: Math.max(limit + offset, 20) * 4,
244
+ order: "createdAt-desc",
245
+ });
246
+ candidates = fetched.map((r) => ({
247
+ id: r.id,
248
+ content: r.content,
249
+ createdAt: r.createdAt,
250
+ tags: r.tags,
251
+ }));
252
+ }
253
+ const items = [];
254
+ for (const c of candidates) {
255
+ const parsed = parseStoredId(c.id, this.agentId);
256
+ if (!parsed)
257
+ continue;
258
+ // Namespace prefix gate (always applied — semantic-search candidates
259
+ // can come from any namespace).
260
+ if (!hasNamespacePrefix(parsed.namespace, op.namespacePrefix))
261
+ continue;
262
+ let value;
263
+ try {
264
+ value = JSON.parse(c.content);
265
+ }
266
+ catch {
267
+ // Tolerate non-LG content under the same agent — skip.
268
+ continue;
269
+ }
270
+ if (!matchesAllFilters(value, op.filter))
271
+ continue;
272
+ items.push({
273
+ namespace: parsed.namespace,
274
+ key: parsed.key,
275
+ value,
276
+ createdAt: c.createdAt ? new Date(c.createdAt) : new Date(0),
277
+ updatedAt: c.createdAt ? new Date(c.createdAt) : new Date(0),
278
+ score: c.score,
279
+ });
280
+ }
281
+ return items.slice(offset, offset + limit);
282
+ }
283
+ async doListNamespaces(op) {
284
+ // Best-effort: scan recent memories, derive distinct namespaces. Honors
285
+ // `limit` and `offset` against the derived list. maxDepth truncates each
286
+ // namespace to that many segments.
287
+ const fetched = await this.client.memory.list({
288
+ limit: 1000,
289
+ order: "createdAt-desc",
290
+ });
291
+ const seen = new Set();
292
+ const out = [];
293
+ for (const r of fetched) {
294
+ const parsed = parseStoredId(r.id, this.agentId);
295
+ if (!parsed)
296
+ continue;
297
+ let ns = parsed.namespace;
298
+ if (op.maxDepth !== undefined && ns.length > op.maxDepth)
299
+ ns = ns.slice(0, op.maxDepth);
300
+ const key = ns.join(NS_SEP);
301
+ if (seen.has(key))
302
+ continue;
303
+ seen.add(key);
304
+ out.push(ns);
305
+ if (out.length >= op.offset + op.limit)
306
+ break;
307
+ }
308
+ return out.slice(op.offset, op.offset + op.limit);
309
+ }
310
+ }
311
+ // ── helpers exported for testability ────────────────────────────────────────
312
+ export function parseStoredId(id, agentId) {
313
+ // id format: "lg:<agentId>:<ns-joined-by-/>:<key>"
314
+ const expectedPrefix = `lg:${agentId}:`;
315
+ if (!id.startsWith(expectedPrefix))
316
+ return null;
317
+ const rest = id.slice(expectedPrefix.length);
318
+ // The last `:` separates ns from key. Namespace can contain `/` but not `:`.
319
+ const lastColon = rest.lastIndexOf(":");
320
+ if (lastColon < 0)
321
+ return null;
322
+ const nsJoined = rest.slice(0, lastColon);
323
+ const key = rest.slice(lastColon + 1);
324
+ const namespace = nsJoined.length === 0 ? [] : nsJoined.split(NS_SEP);
325
+ return { namespace, key };
326
+ }
327
+ export function hasNamespacePrefix(namespace, prefix) {
328
+ if (prefix.length > namespace.length)
329
+ return false;
330
+ for (let i = 0; i < prefix.length; i++) {
331
+ if (namespace[i] !== prefix[i])
332
+ return false;
333
+ }
334
+ return true;
335
+ }
336
+ function memoryToItem(mem, namespace, key) {
337
+ let value = {};
338
+ try {
339
+ value = typeof mem.content === "string" ? JSON.parse(mem.content) : mem.content;
340
+ }
341
+ catch {
342
+ value = { __raw: mem.content };
343
+ }
344
+ return {
345
+ namespace,
346
+ key,
347
+ value,
348
+ createdAt: mem.createdAt ? new Date(mem.createdAt) : new Date(0),
349
+ updatedAt: mem.updatedAt ? new Date(mem.updatedAt) : (mem.createdAt ? new Date(mem.createdAt) : new Date(0)),
350
+ };
351
+ }
352
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@tpsdev-ai/langgraph-flair",
3
+ "version": "0.9.0",
4
+ "description": "LangGraph BaseStore adapter backed by Flair — durable agent memory with crypto-pinned identity, federation, and cross-orchestrator portability.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist/",
10
+ "LICENSE",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc --noCheck",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "keywords": [
24
+ "langgraph",
25
+ "langchain",
26
+ "flair",
27
+ "memory",
28
+ "agent",
29
+ "store"
30
+ ],
31
+ "homepage": "https://github.com/tpsdev-ai/flair/tree/main/packages/langgraph-flair",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/tpsdev-ai/flair.git",
35
+ "directory": "packages/langgraph-flair"
36
+ },
37
+ "license": "Apache-2.0",
38
+ "dependencies": {
39
+ "@tpsdev-ai/flair-client": "0.9.0"
40
+ },
41
+ "peerDependencies": {
42
+ "@langchain/langgraph-checkpoint": ">=0.0.10"
43
+ }
44
+ }