agentsmcp-langgraph 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentMailbox contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # agentsmcp-langgraph
2
+
3
+ LangGraph checkpointer backed by [agentsmcp](https://www.npmjs.com/package/agentsmcp).
4
+ Drop-in `BaseCheckpointSaver` — your graph state lives in an AgentMailbox
5
+ thread, so it survives process restarts, runs across machines, and is
6
+ inspectable from any other agentsmcp client.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install agentsmcp-langgraph @langchain/langgraph
12
+ ```
13
+
14
+ You'll also need an agentsmcp HTTP server reachable from your process.
15
+ Run it locally with `npx agentsmcp-server`, or point at any deployment.
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { StateGraph } from "@langchain/langgraph";
21
+ import { AgentsmcpSaver } from "agentsmcp-langgraph";
22
+
23
+ const checkpointer = new AgentsmcpSaver({
24
+ server: process.env.AGENTSMCP_SERVER ?? "http://localhost:3000",
25
+ agentId: "langgraph@my-app", // stable identity = stable threads
26
+ apiKey: process.env.AGENTSMCP_API_KEY,
27
+ });
28
+ await checkpointer.connect();
29
+
30
+ const graph = workflow.compile({ checkpointer });
31
+
32
+ await graph.invoke(input, {
33
+ configurable: { thread_id: "session-abc" },
34
+ });
35
+ ```
36
+
37
+ Restart the process, invoke again with the same `thread_id`, and the
38
+ graph picks up exactly where it left off. Same property in another
39
+ process on another machine, as long as `agentId` and `thread_id` match.
40
+
41
+ ## How it maps
42
+
43
+ | LangGraph | agentsmcp |
44
+ | --- | --- |
45
+ | `thread_id` (RunnableConfig) | One thread per `thread_id` |
46
+ | `checkpoint_id` (uuid6) | Stored in the message payload |
47
+ | `Checkpoint` bytes | Base64'd into `payload.checkpoint` |
48
+ | `CheckpointMetadata` bytes | Base64'd into `payload.metadata` |
49
+ | `pendingWrites` | Sibling messages of `kind: "writes"`, merged on read |
50
+ | `checkpoint_ns` | Filter tag inside the payload — subgraphs isolated |
51
+
52
+ The recipient on every message is the synthetic agent
53
+ `{thread_id}@checkpoints`. It's never real; it just gives the thread
54
+ a stable identity so cold-restart can look it up by participant.
55
+
56
+ ## What you get vs `MemorySaver` / `SqliteSaver`
57
+
58
+ - **Cross-process** — write from one node, read from another. No file
59
+ to share, no DB to provision; just an HTTP URL.
60
+ - **Inspectable** — every checkpoint is a message on a thread. Any
61
+ agentsmcp client (the JS/Python SDK, the MCP adapter, `curl`) can
62
+ read the state of your graph at any point in its history.
63
+ - **Compressed when long** — once a thread crosses the configured
64
+ compression threshold (default 20 messages), the agentsmcp server
65
+ folds older checkpoints into a structured summary that you can use
66
+ alongside the verbatim recent window. Useful for very long graphs
67
+ where re-reading every checkpoint is wasteful.
68
+
69
+ ## Configuration
70
+
71
+ ```ts
72
+ new AgentsmcpSaver({
73
+ server, // default: AGENTSMCP_SERVER env, then localhost:3000
74
+ agentId, // default: AGENTSMCP_AGENT_ID env, then `langgraph@<hostname>`
75
+ apiKey, // default: AGENTSMCP_API_KEY env
76
+ serde, // default: LangGraph's JsonPlusSerializer
77
+ });
78
+ ```
79
+
80
+ If you want every process to share state, pin `agentId` to a stable
81
+ string. If you want each process to have its own slice, let it default
82
+ to the hostname.
83
+
84
+ ## Limitations (worth knowing)
85
+
86
+ - **`list()` reads the whole thread.** Fine for ~hundreds of
87
+ checkpoints. For very long threads, lean on compression and accept
88
+ that `list()` is paginated client-side.
89
+ - **No deduplication of repeat `put()`.** The agentsmcp server assigns
90
+ message IDs server-side, so a re-put produces a duplicate row;
91
+ `getTuple()` and `list()` dedupe by `checkpoint_id` on read.
92
+ - **Checkpoint writes are O(1) — but always a network round-trip.**
93
+ If your graph checkpoints aggressively in a hot loop, that's a real
94
+ cost; pair this saver with a local agentsmcp server for low latency.
95
+
96
+ ## License
97
+
98
+ MIT — see [LICENSE](../LICENSE).
@@ -0,0 +1,3 @@
1
+ export { AgentsmcpSaver, type AgentsmcpSaverOptions } from "./saver";
2
+ export type { CheckpointContext, CheckpointPayload, PendingWriteWire, WritesPayload, } from "./types";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,SAAS,CAAC;AACrE,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,GACd,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentsmcpSaver = void 0;
4
+ var saver_1 = require("./saver");
5
+ Object.defineProperty(exports, "AgentsmcpSaver", { enumerable: true, get: function () { return saver_1.AgentsmcpSaver; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAAqE;AAA5D,uGAAA,cAAc,OAAA"}
@@ -0,0 +1,3 @@
1
+ import * as nodeOs from "os";
2
+ export declare const os: typeof nodeOs;
3
+ //# sourceMappingURL=os-shim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-shim.d.ts","sourceRoot":"","sources":["../src/os-shim.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAC7B,eAAO,MAAM,EAAE,eAAS,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.os = void 0;
37
+ // Small re-export so the saver can import "os" without TS module-resolution
38
+ // gymnastics under commonjs+esModuleInterop=true.
39
+ const nodeOs = __importStar(require("os"));
40
+ exports.os = nodeOs;
41
+ //# sourceMappingURL=os-shim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-shim.js","sourceRoot":"","sources":["../src/os-shim.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4EAA4E;AAC5E,kDAAkD;AAClD,2CAA6B;AAChB,QAAA,EAAE,GAAG,MAAM,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { RunnableConfig } from "@langchain/core/runnables";
2
+ import { BaseCheckpointSaver, type Checkpoint, type CheckpointListOptions, type CheckpointMetadata, type CheckpointTuple, type ChannelVersions, type PendingWrite, type SerializerProtocol } from "@langchain/langgraph-checkpoint";
3
+ import type { ContextFrame } from "agentsmcp";
4
+ export interface AgentsmcpSaverOptions {
5
+ /** Where the agentsmcp HTTP server lives. Defaults to env or localhost:3000. */
6
+ server?: string;
7
+ /**
8
+ * Agent identity this saver writes as. Defaults to
9
+ * `langgraph@<hostname>`. Use a stable id so threads persist across
10
+ * process restarts.
11
+ */
12
+ agentId?: string;
13
+ /** Bearer token forwarded to agentsmcp. Defaults to env. */
14
+ apiKey?: string;
15
+ /** Plug your own LangGraph serializer if you have a custom one. */
16
+ serde?: SerializerProtocol;
17
+ }
18
+ /**
19
+ * LangGraph BaseCheckpointSaver backed by an agentsmcp HTTP server.
20
+ *
21
+ * One LangGraph thread (`config.configurable.thread_id`) maps to one
22
+ * agentsmcp thread. Every checkpoint and every batch of intermediate
23
+ * writes becomes one message on that thread. Process restart resumes
24
+ * by reading the thread.
25
+ *
26
+ * AgentsmcpSaver intentionally does not implement deterministic message
27
+ * IDs — the agentsmcp server generates them. Instead the LangGraph
28
+ * `checkpoint_id` is carried inside the payload and used as the
29
+ * primary key on read.
30
+ */
31
+ export declare class AgentsmcpSaver extends BaseCheckpointSaver {
32
+ private readonly mail;
33
+ private readonly agentId;
34
+ private connected;
35
+ /** langgraph thread_id → agentsmcp threadId (resolved lazily) */
36
+ private readonly threadCache;
37
+ constructor(opts?: AgentsmcpSaverOptions);
38
+ /** Register this saver's agent identity with the server. Idempotent. */
39
+ connect(): Promise<void>;
40
+ getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined>;
41
+ list(config: RunnableConfig, options?: CheckpointListOptions): AsyncGenerator<CheckpointTuple>;
42
+ put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, _newVersions: ChannelVersions): Promise<RunnableConfig>;
43
+ putWrites(config: RunnableConfig, writes: PendingWrite[], taskId: string): Promise<void>;
44
+ /**
45
+ * Look up the agentsmcp threadId for a given LangGraph thread_id.
46
+ * Hits the cache first; falls back to a thread listing on first call
47
+ * after a process restart.
48
+ */
49
+ private resolveThread;
50
+ private messageToTuple;
51
+ }
52
+ export type { ContextFrame };
53
+ //# sourceMappingURL=saver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saver.d.ts","sourceRoot":"","sources":["../src/saver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,WAAW,CAAC;AAUvD,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAe,SAAQ,mBAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;gBAE7C,IAAI,GAAE,qBAA0B;IAqB5C,wEAAwE;IAClE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUxB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAgCrE,IAAI,CACT,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,eAAe,CAAC;IAmD5B,GAAG,CACP,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,eAAe,GAC5B,OAAO,CAAC,cAAc,CAAC;IAsDpB,SAAS,CACb,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA2ChB;;;;OAIG;YACW,aAAa;YAmBb,cAAc;CAwE7B;AAuCD,YAAY,EAAE,YAAY,EAAE,CAAC"}
package/dist/saver.js ADDED
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentsmcpSaver = void 0;
4
+ const os_shim_1 = require("./os-shim");
5
+ const langgraph_checkpoint_1 = require("@langchain/langgraph-checkpoint");
6
+ const agentsmcp_1 = require("agentsmcp");
7
+ const serializer_1 = require("./serializer");
8
+ /**
9
+ * LangGraph BaseCheckpointSaver backed by an agentsmcp HTTP server.
10
+ *
11
+ * One LangGraph thread (`config.configurable.thread_id`) maps to one
12
+ * agentsmcp thread. Every checkpoint and every batch of intermediate
13
+ * writes becomes one message on that thread. Process restart resumes
14
+ * by reading the thread.
15
+ *
16
+ * AgentsmcpSaver intentionally does not implement deterministic message
17
+ * IDs — the agentsmcp server generates them. Instead the LangGraph
18
+ * `checkpoint_id` is carried inside the payload and used as the
19
+ * primary key on read.
20
+ */
21
+ class AgentsmcpSaver extends langgraph_checkpoint_1.BaseCheckpointSaver {
22
+ constructor(opts = {}) {
23
+ super(opts.serde);
24
+ this.connected = false;
25
+ /** langgraph thread_id → agentsmcp threadId (resolved lazily) */
26
+ this.threadCache = new Map();
27
+ const server = opts.server ??
28
+ process.env.AGENTSMCP_SERVER ??
29
+ process.env.AGENTMAILBOX_SERVER ??
30
+ "http://localhost:3000";
31
+ this.agentId =
32
+ opts.agentId ??
33
+ process.env.AGENTSMCP_AGENT_ID ??
34
+ `langgraph@${os_shim_1.os.hostname()}`;
35
+ this.mail = new agentsmcp_1.AgentMailbox({
36
+ agentId: this.agentId,
37
+ server,
38
+ apiKey: opts.apiKey ??
39
+ process.env.AGENTSMCP_API_KEY ??
40
+ process.env.AGENTMAILBOX_API_KEY,
41
+ });
42
+ }
43
+ /** Register this saver's agent identity with the server. Idempotent. */
44
+ async connect() {
45
+ if (this.connected)
46
+ return;
47
+ await this.mail.connect();
48
+ this.connected = true;
49
+ }
50
+ // ─────────────────────────────────────────────────────────────────
51
+ // BaseCheckpointSaver surface
52
+ // ─────────────────────────────────────────────────────────────────
53
+ async getTuple(config) {
54
+ await this.connect();
55
+ const thread_id = requireThreadId(config);
56
+ const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
57
+ const requested_id = config.configurable?.checkpoint_id;
58
+ const agentsmcpThreadId = await this.resolveThread(thread_id);
59
+ if (!agentsmcpThreadId)
60
+ return undefined;
61
+ const messages = await this.mail.threads().then(async (threads) => {
62
+ const t = threads.find((x) => x.id === agentsmcpThreadId);
63
+ return t ? t.messages : [];
64
+ });
65
+ const checkpointMsgs = messages.filter((m) => isCheckpointPayload(m.payload) && m.payload.checkpoint_ns === checkpoint_ns);
66
+ let target = requested_id
67
+ ? checkpointMsgs.find((m) => isCheckpointPayload(m.payload) &&
68
+ m.payload.checkpoint_id === requested_id)
69
+ : checkpointMsgs[checkpointMsgs.length - 1];
70
+ if (!target)
71
+ return undefined;
72
+ return this.messageToTuple(target, messages, thread_id, checkpoint_ns);
73
+ }
74
+ async *list(config, options) {
75
+ await this.connect();
76
+ const thread_id = requireThreadId(config);
77
+ const configured_ns = config.configurable?.checkpoint_ns;
78
+ const agentsmcpThreadId = await this.resolveThread(thread_id);
79
+ if (!agentsmcpThreadId)
80
+ return;
81
+ const threads = await this.mail.threads();
82
+ const t = threads.find((x) => x.id === agentsmcpThreadId);
83
+ if (!t)
84
+ return;
85
+ const messages = t.messages;
86
+ const checkpointMsgs = messages.filter((m) => {
87
+ if (!isCheckpointPayload(m.payload))
88
+ return false;
89
+ if (configured_ns !== undefined && m.payload.checkpoint_ns !== configured_ns) {
90
+ return false;
91
+ }
92
+ if (options?.before?.configurable?.checkpoint_id) {
93
+ const cutoff = options.before.configurable.checkpoint_id;
94
+ // LangGraph checkpoint_ids are uuid6 / lexicographically sortable.
95
+ return m.payload.checkpoint_id < cutoff;
96
+ }
97
+ return true;
98
+ });
99
+ // Newest first. agentsmcp returns messages timestamp-ascending.
100
+ checkpointMsgs.reverse();
101
+ const seenCheckpointIds = new Set();
102
+ let emitted = 0;
103
+ for (const m of checkpointMsgs) {
104
+ const cpId = m.payload.checkpoint_id;
105
+ if (seenCheckpointIds.has(cpId))
106
+ continue; // dedupe repeated put
107
+ seenCheckpointIds.add(cpId);
108
+ if (options?.limit !== undefined && emitted >= options.limit)
109
+ break;
110
+ yield await this.messageToTuple(m, messages, thread_id, m.payload.checkpoint_ns);
111
+ emitted += 1;
112
+ }
113
+ }
114
+ async put(config, checkpoint, metadata, _newVersions) {
115
+ await this.connect();
116
+ const thread_id = requireThreadId(config);
117
+ const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
118
+ const parent_checkpoint_id = config.configurable?.checkpoint_id;
119
+ const checkpointBlob = await (0, serializer_1.dumpToBase64)(this.serde, checkpoint);
120
+ const metadataBlob = await (0, serializer_1.dumpToBase64)(this.serde, metadata);
121
+ const payload = {
122
+ kind: "checkpoint",
123
+ checkpoint: checkpointBlob.data,
124
+ metadata: metadataBlob.data,
125
+ checkpoint_ns,
126
+ checkpoint_id: checkpoint.id,
127
+ parent_checkpoint_id,
128
+ };
129
+ // Stash the serializer type tags alongside in contextSnapshot so we
130
+ // can round-trip without hardcoding "json".
131
+ const ctx = {
132
+ checkpoint_id: checkpoint.id,
133
+ checkpoint_ns,
134
+ thread_id,
135
+ step: metadata.step ?? -1,
136
+ source: metadata.source ?? "input",
137
+ _checkpoint_type: checkpointBlob.type,
138
+ _metadata_type: metadataBlob.type,
139
+ };
140
+ const existing = this.threadCache.get(thread_id);
141
+ const sendResult = await this.mail.send(syntheticRecipient(thread_id), payload, {
142
+ threadId: existing,
143
+ contextSnapshot: ctx,
144
+ });
145
+ this.threadCache.set(thread_id, sendResult.threadId);
146
+ return {
147
+ configurable: {
148
+ thread_id,
149
+ checkpoint_ns,
150
+ checkpoint_id: checkpoint.id,
151
+ },
152
+ };
153
+ }
154
+ async putWrites(config, writes, taskId) {
155
+ await this.connect();
156
+ const thread_id = requireThreadId(config);
157
+ const checkpoint_ns = config.configurable?.checkpoint_ns ?? "";
158
+ const checkpoint_id = config.configurable?.checkpoint_id;
159
+ if (!checkpoint_id) {
160
+ throw new Error("AgentsmcpSaver.putWrites: config.configurable.checkpoint_id is required");
161
+ }
162
+ const wireWrites = await Promise.all(writes.map(async ([channel, value]) => {
163
+ const blob = await (0, serializer_1.dumpToBase64)(this.serde, value);
164
+ return { taskId, channel, value: blob.data, type: blob.type };
165
+ }));
166
+ const payload = {
167
+ kind: "writes",
168
+ checkpoint_id,
169
+ checkpoint_ns,
170
+ writes: wireWrites,
171
+ };
172
+ const existing = this.threadCache.get(thread_id);
173
+ const sendResult = await this.mail.send(syntheticRecipient(thread_id), payload, {
174
+ threadId: existing,
175
+ contextSnapshot: { kind: "writes", checkpoint_id, taskId, checkpoint_ns },
176
+ });
177
+ this.threadCache.set(thread_id, sendResult.threadId);
178
+ }
179
+ // ─────────────────────────────────────────────────────────────────
180
+ // Private helpers
181
+ // ─────────────────────────────────────────────────────────────────
182
+ /**
183
+ * Look up the agentsmcp threadId for a given LangGraph thread_id.
184
+ * Hits the cache first; falls back to a thread listing on first call
185
+ * after a process restart.
186
+ */
187
+ async resolveThread(langgraphThreadId) {
188
+ const cached = this.threadCache.get(langgraphThreadId);
189
+ if (cached)
190
+ return cached;
191
+ const recipient = syntheticRecipient(langgraphThreadId);
192
+ const threads = await this.mail.threads();
193
+ const match = threads.find((t) => t.participants.includes(recipient) ||
194
+ t.silentParticipants.includes(recipient));
195
+ if (match) {
196
+ this.threadCache.set(langgraphThreadId, match.id);
197
+ return match.id;
198
+ }
199
+ return undefined;
200
+ }
201
+ async messageToTuple(checkpointMsg, allMessages, thread_id, checkpoint_ns) {
202
+ if (!isCheckpointPayload(checkpointMsg.payload)) {
203
+ throw new Error("messageToTuple called with non-checkpoint message");
204
+ }
205
+ const cp = checkpointMsg.payload;
206
+ const ctx = checkpointMsg.contextSnapshot;
207
+ const checkpoint = await (0, serializer_1.loadFromBase64)(this.serde, {
208
+ type: ctx._checkpoint_type ?? "json",
209
+ data: cp.checkpoint,
210
+ });
211
+ const metadata = await (0, serializer_1.loadFromBase64)(this.serde, {
212
+ type: ctx._metadata_type ?? "json",
213
+ data: cp.metadata,
214
+ });
215
+ // Merge any writes messages that came AFTER this checkpoint message
216
+ // but before the next checkpoint message on the same ns. Those are
217
+ // this checkpoint's pendingWrites.
218
+ const idx = allMessages.findIndex((m) => m.id === checkpointMsg.id);
219
+ const pendingWrites = [];
220
+ for (let i = idx + 1; i < allMessages.length; i++) {
221
+ const m = allMessages[i];
222
+ if (isCheckpointPayload(m.payload)) {
223
+ if (m.payload.checkpoint_ns === cp.checkpoint_ns)
224
+ break;
225
+ continue;
226
+ }
227
+ if (isWritesPayload(m.payload) &&
228
+ m.payload.checkpoint_id === cp.checkpoint_id &&
229
+ m.payload.checkpoint_ns === cp.checkpoint_ns) {
230
+ for (const w of m.payload.writes) {
231
+ const value = await (0, serializer_1.loadFromBase64)(this.serde, {
232
+ type: w.type,
233
+ data: w.value,
234
+ });
235
+ pendingWrites.push([w.taskId, w.channel, value]);
236
+ }
237
+ }
238
+ }
239
+ const tuple = {
240
+ config: {
241
+ configurable: {
242
+ thread_id,
243
+ checkpoint_ns: cp.checkpoint_ns,
244
+ checkpoint_id: cp.checkpoint_id,
245
+ },
246
+ },
247
+ checkpoint,
248
+ metadata,
249
+ pendingWrites,
250
+ };
251
+ if (cp.parent_checkpoint_id) {
252
+ tuple.parentConfig = {
253
+ configurable: {
254
+ thread_id,
255
+ checkpoint_ns: cp.checkpoint_ns,
256
+ checkpoint_id: cp.parent_checkpoint_id,
257
+ },
258
+ };
259
+ }
260
+ return tuple;
261
+ }
262
+ }
263
+ exports.AgentsmcpSaver = AgentsmcpSaver;
264
+ // ───────────────────────────────────────────────────────────────────
265
+ // Module-private helpers
266
+ // ───────────────────────────────────────────────────────────────────
267
+ function syntheticRecipient(threadId) {
268
+ return `${threadId}@checkpoints`;
269
+ }
270
+ function requireThreadId(config) {
271
+ const id = config.configurable?.thread_id;
272
+ if (typeof id !== "string" || id.length === 0) {
273
+ throw new Error("config.configurable.thread_id is required for AgentsmcpSaver");
274
+ }
275
+ return id;
276
+ }
277
+ function isCheckpointPayload(p) {
278
+ return (typeof p === "object" &&
279
+ p !== null &&
280
+ p.kind === "checkpoint");
281
+ }
282
+ function isWritesPayload(p) {
283
+ return (typeof p === "object" &&
284
+ p !== null &&
285
+ p.kind === "writes");
286
+ }
287
+ //# sourceMappingURL=saver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saver.js","sourceRoot":"","sources":["../src/saver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { SerializerProtocol } from "@langchain/langgraph-checkpoint";
2
+ /**
3
+ * LangGraph's serializer returns `[type: string, bytes: Uint8Array]`.
4
+ * agentsmcp's JSON wire format can't carry binary, so we base64-encode
5
+ * the bytes and keep the type tag alongside.
6
+ */
7
+ export interface SerializedTyped {
8
+ type: string;
9
+ data: string;
10
+ }
11
+ export declare function dumpToBase64(serde: SerializerProtocol, value: unknown): Promise<SerializedTyped>;
12
+ export declare function loadFromBase64<T = unknown>(serde: SerializerProtocol, s: SerializedTyped): Promise<T>;
13
+ //# sourceMappingURL=serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,wBAAsB,cAAc,CAAC,CAAC,GAAG,OAAO,EAC9C,KAAK,EAAE,kBAAkB,EACzB,CAAC,EAAE,eAAe,GACjB,OAAO,CAAC,CAAC,CAAC,CAGZ"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dumpToBase64 = dumpToBase64;
4
+ exports.loadFromBase64 = loadFromBase64;
5
+ async function dumpToBase64(serde, value) {
6
+ const [type, bytes] = await serde.dumpsTyped(value);
7
+ return { type, data: bytesToBase64(bytes) };
8
+ }
9
+ async function loadFromBase64(serde, s) {
10
+ const bytes = base64ToBytes(s.data);
11
+ return (await serde.loadsTyped(s.type, bytes));
12
+ }
13
+ function bytesToBase64(bytes) {
14
+ // Buffer is available everywhere we run (Node 18+).
15
+ return Buffer.from(bytes).toString("base64");
16
+ }
17
+ function base64ToBytes(b64) {
18
+ return new Uint8Array(Buffer.from(b64, "base64"));
19
+ }
20
+ //# sourceMappingURL=serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.js","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":";;AAaA,oCAMC;AAED,wCAMC;AAdM,KAAK,UAAU,YAAY,CAChC,KAAyB,EACzB,KAAc;IAEd,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACpD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9C,CAAC;AAEM,KAAK,UAAU,cAAc,CAClC,KAAyB,EACzB,CAAkB;IAElB,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAM,CAAC;AACtD,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,oDAAoD;IACpD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Wire shapes the checkpointer writes into agentsmcp messages.
3
+ *
4
+ * Two kinds of messages live on the underlying thread:
5
+ * - kind="checkpoint" — a full LangGraph checkpoint snapshot
6
+ * - kind="writes" — intermediate writes (putWrites) that get
7
+ * merged into the next checkpoint's pendingWrites
8
+ *
9
+ * Both are tagged so getTuple/list can filter without ambiguity.
10
+ */
11
+ export interface CheckpointPayload {
12
+ kind: "checkpoint";
13
+ /** base64-encoded bytes from the LangGraph serializer */
14
+ checkpoint: string;
15
+ /** base64-encoded CheckpointMetadata bytes */
16
+ metadata: string;
17
+ /** "" for the root graph, "sub:name" for subgraphs */
18
+ checkpoint_ns: string;
19
+ /** LangGraph's checkpoint id (uuid6) — distinct from agentsmcp message id */
20
+ checkpoint_id: string;
21
+ /** id of the previous checkpoint on this thread/ns; undefined for the first */
22
+ parent_checkpoint_id?: string;
23
+ }
24
+ export interface PendingWriteWire {
25
+ taskId: string;
26
+ channel: string;
27
+ /** base64-encoded value bytes */
28
+ value: string;
29
+ /** LangGraph's value type tag returned by the serializer */
30
+ type: string;
31
+ }
32
+ export interface WritesPayload {
33
+ kind: "writes";
34
+ /** which checkpoint these writes belong to */
35
+ checkpoint_id: string;
36
+ checkpoint_ns: string;
37
+ writes: PendingWriteWire[];
38
+ }
39
+ /** Shape stored in agentsmcp's contextSnapshot for each checkpoint message. */
40
+ export interface CheckpointContext extends Record<string, unknown> {
41
+ checkpoint_id: string;
42
+ checkpoint_ns: string;
43
+ thread_id: string;
44
+ step: number;
45
+ source: string;
46
+ }
47
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAkB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Wire shapes the checkpointer writes into agentsmcp messages.
4
+ *
5
+ * Two kinds of messages live on the underlying thread:
6
+ * - kind="checkpoint" — a full LangGraph checkpoint snapshot
7
+ * - kind="writes" — intermediate writes (putWrites) that get
8
+ * merged into the next checkpoint's pendingWrites
9
+ *
10
+ * Both are tagged so getTuple/list can filter without ambiguity.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "agentsmcp-langgraph",
3
+ "version": "0.1.0",
4
+ "description": "LangGraph BaseCheckpointSaver backed by agentsmcp (AgentMailbox). Drop-in checkpointer for LangGraph.js — your graph state lives in an AgentMailbox thread.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "commonjs",
8
+ "files": [
9
+ "dist/",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "rm -rf dist && tsc",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "prepublishOnly": "npm run build && npm test"
18
+ },
19
+ "keywords": [
20
+ "langgraph",
21
+ "langchain",
22
+ "checkpointer",
23
+ "agents",
24
+ "agentsmcp",
25
+ "agentmailbox"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/RagavRida/agentsmcp.git",
30
+ "directory": "langgraph"
31
+ },
32
+ "homepage": "https://github.com/RagavRida/agentsmcp/tree/main/langgraph",
33
+ "bugs": {
34
+ "url": "https://github.com/RagavRida/agentsmcp/issues"
35
+ },
36
+ "license": "MIT",
37
+ "engines": {
38
+ "node": ">=18"
39
+ },
40
+ "dependencies": {
41
+ "agentsmcp": ">=0.3.5 <0.5.0"
42
+ },
43
+ "peerDependencies": {
44
+ "@langchain/langgraph-checkpoint": ">=0.0.10"
45
+ },
46
+ "devDependencies": {
47
+ "@langchain/langgraph-checkpoint": "^0.0.10",
48
+ "@types/node": "^22.5.0",
49
+ "typescript": "^5.5.4",
50
+ "vitest": "^2.0.0"
51
+ }
52
+ }