@skein-js/server-kit 0.11.2 → 0.12.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/dist/dev.js ADDED
@@ -0,0 +1,303 @@
1
+ import {
2
+ hydrateCheckpointer,
3
+ snapshotCheckpointer
4
+ } from "./chunk-JUBBCC7R.js";
5
+
6
+ // src/langgraph-import.ts
7
+ import { readFile } from "fs/promises";
8
+ import path from "path";
9
+ import {
10
+ MemorySaver
11
+ } from "@langchain/langgraph";
12
+ import {
13
+ isTerminalRunStatus
14
+ } from "@skein-js/core";
15
+ import { SuperJSON } from "superjson";
16
+ import { z } from "zod";
17
+ var OPS_FILE = ".langgraphjs_ops.json";
18
+ var STORE_FILE = ".langgraphjs_api.store.json";
19
+ var CHECKPOINTER_FILE = ".langgraphjs_api.checkpointer.json";
20
+ var langgraphSuperjson = new SuperJSON();
21
+ langgraphSuperjson.registerCustom(
22
+ {
23
+ isApplicable: (value) => value instanceof Uint8Array,
24
+ serialize: (value) => Buffer.from(value).toString("base64"),
25
+ deserialize: (value) => new Uint8Array(Buffer.from(value, "base64"))
26
+ },
27
+ "Uint8Array"
28
+ );
29
+ var timestamp = z.union([z.date(), z.string()]).optional();
30
+ var jsonObject = z.record(z.unknown());
31
+ var langgraphAssistantSchema = z.object({
32
+ assistant_id: z.string(),
33
+ graph_id: z.string(),
34
+ name: z.string().optional(),
35
+ description: z.string().nullish(),
36
+ config: jsonObject.optional(),
37
+ context: z.unknown().optional(),
38
+ metadata: jsonObject.optional(),
39
+ version: z.number().optional(),
40
+ created_at: timestamp,
41
+ updated_at: timestamp
42
+ }).passthrough();
43
+ var langgraphAssistantVersionSchema = z.object({
44
+ assistant_id: z.string(),
45
+ version: z.number(),
46
+ graph_id: z.string(),
47
+ name: z.string().optional(),
48
+ description: z.string().nullish(),
49
+ config: jsonObject.optional(),
50
+ context: z.unknown().optional(),
51
+ metadata: jsonObject.optional(),
52
+ created_at: timestamp
53
+ }).passthrough();
54
+ var langgraphThreadSchema = z.object({
55
+ thread_id: z.string(),
56
+ status: z.string().optional(),
57
+ metadata: jsonObject.optional(),
58
+ values: jsonObject.optional(),
59
+ interrupts: jsonObject.optional(),
60
+ created_at: timestamp,
61
+ updated_at: timestamp
62
+ }).passthrough();
63
+ var langgraphRunSchema = z.object({
64
+ run_id: z.string(),
65
+ thread_id: z.string(),
66
+ assistant_id: z.string(),
67
+ status: z.string().optional(),
68
+ metadata: jsonObject.optional(),
69
+ multitask_strategy: z.string().nullish(),
70
+ kwargs: jsonObject.optional(),
71
+ created_at: timestamp,
72
+ updated_at: timestamp
73
+ }).passthrough();
74
+ var langgraphOpsSchema = z.object({
75
+ assistants: z.record(langgraphAssistantSchema).optional(),
76
+ assistant_versions: z.array(langgraphAssistantVersionSchema).optional(),
77
+ threads: z.record(langgraphThreadSchema).optional(),
78
+ runs: z.record(langgraphRunSchema).optional()
79
+ }).passthrough();
80
+ var langgraphStoreItemSchema = z.object({
81
+ namespace: z.array(z.string()),
82
+ key: z.string(),
83
+ value: jsonObject,
84
+ createdAt: timestamp,
85
+ updatedAt: timestamp
86
+ }).passthrough();
87
+ var langgraphStoreFileSchema = z.object({ data: z.map(z.string(), z.map(z.string(), langgraphStoreItemSchema)).optional() }).passthrough();
88
+ var langgraphCheckpointerSchema = z.object({ storage: jsonObject, writes: jsonObject }).passthrough();
89
+ async function readSuperjsonFile(filepath) {
90
+ let text;
91
+ try {
92
+ text = await readFile(filepath, "utf8");
93
+ } catch {
94
+ return null;
95
+ }
96
+ try {
97
+ return langgraphSuperjson.parse(text) ?? null;
98
+ } catch (error) {
99
+ throw new Error(
100
+ `Could not parse LangGraph state file "${filepath}": ${error instanceof Error ? error.message : String(error)}`
101
+ );
102
+ }
103
+ }
104
+ function validateShape(schema, value, label) {
105
+ const result = schema.safeParse(value);
106
+ if (!result.success) {
107
+ const detail = result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
108
+ throw new Error(`Invalid LangGraph ${label}: ${detail}`);
109
+ }
110
+ return result.data;
111
+ }
112
+ function toIso(value, fallback) {
113
+ if (value instanceof Date) return value.toISOString();
114
+ if (typeof value === "string") return value;
115
+ return fallback;
116
+ }
117
+ function toAssistant(row, now) {
118
+ return {
119
+ assistant_id: row.assistant_id,
120
+ graph_id: row.graph_id,
121
+ name: row.name ?? row.graph_id,
122
+ description: row.description ?? void 0,
123
+ config: row.config ?? {},
124
+ context: row.context ?? {},
125
+ metadata: row.metadata ?? {},
126
+ version: row.version ?? 1,
127
+ created_at: toIso(row.created_at, now),
128
+ updated_at: toIso(row.updated_at, now)
129
+ };
130
+ }
131
+ function toAssistantVersion(row, now) {
132
+ return {
133
+ assistant_id: row.assistant_id,
134
+ version: row.version,
135
+ graph_id: row.graph_id,
136
+ name: row.name ?? row.graph_id,
137
+ description: row.description ?? void 0,
138
+ config: row.config ?? {},
139
+ context: row.context ?? {},
140
+ metadata: row.metadata ?? {},
141
+ created_at: toIso(row.created_at, now)
142
+ };
143
+ }
144
+ function toThread(row, now) {
145
+ const createdAt = toIso(row.created_at, now);
146
+ const updatedAt = toIso(row.updated_at, createdAt);
147
+ return {
148
+ thread_id: row.thread_id,
149
+ status: row.status ?? "idle",
150
+ metadata: row.metadata ?? {},
151
+ values: row.values ?? {},
152
+ interrupts: row.interrupts ?? {},
153
+ created_at: createdAt,
154
+ updated_at: updatedAt,
155
+ state_updated_at: updatedAt
156
+ };
157
+ }
158
+ function toRun(row, now) {
159
+ const createdAt = toIso(row.created_at, now);
160
+ const status = row.status ?? "success";
161
+ return {
162
+ run_id: row.run_id,
163
+ thread_id: row.thread_id,
164
+ assistant_id: row.assistant_id,
165
+ status: isTerminalRunStatus(status) ? status : "error",
166
+ metadata: row.metadata ?? {},
167
+ multitask_strategy: row.multitask_strategy ?? null,
168
+ created_at: createdAt,
169
+ updated_at: toIso(row.updated_at, createdAt)
170
+ };
171
+ }
172
+ function toRunKwargs(kwargs) {
173
+ if (!kwargs) return {};
174
+ const {
175
+ input,
176
+ command,
177
+ config,
178
+ context,
179
+ stream_mode,
180
+ interrupt_before,
181
+ interrupt_after,
182
+ webhook
183
+ } = kwargs;
184
+ return {
185
+ input,
186
+ command,
187
+ config,
188
+ context,
189
+ stream_mode,
190
+ interrupt_before,
191
+ interrupt_after,
192
+ ...typeof webhook === "string" ? { webhook } : {}
193
+ };
194
+ }
195
+ async function readLanggraphDevState(langgraphApiDir) {
196
+ const now = (/* @__PURE__ */ new Date()).toISOString();
197
+ const [opsRaw, storeRaw, checkpointerRaw] = await Promise.all([
198
+ readSuperjsonFile(path.join(langgraphApiDir, OPS_FILE)),
199
+ readSuperjsonFile(path.join(langgraphApiDir, STORE_FILE)),
200
+ readSuperjsonFile(path.join(langgraphApiDir, CHECKPOINTER_FILE))
201
+ ]);
202
+ if (!opsRaw && !storeRaw && !checkpointerRaw) return null;
203
+ const ops = opsRaw ? validateShape(langgraphOpsSchema, opsRaw, OPS_FILE) : null;
204
+ const storeFile = storeRaw ? validateShape(langgraphStoreFileSchema, storeRaw, STORE_FILE) : null;
205
+ const checkpointerFile = checkpointerRaw ? validateShape(langgraphCheckpointerSchema, checkpointerRaw, CHECKPOINTER_FILE) : null;
206
+ const runEntries = Object.entries(ops?.runs ?? {});
207
+ const items = [];
208
+ if (storeFile?.data) {
209
+ for (const namespaceItems of storeFile.data.values()) {
210
+ for (const stored of namespaceItems.values()) {
211
+ const item = {
212
+ namespace: stored.namespace,
213
+ key: stored.key,
214
+ value: stored.value,
215
+ createdAt: toIso(stored.createdAt, now),
216
+ updatedAt: toIso(stored.updatedAt, now)
217
+ };
218
+ items.push([JSON.stringify([stored.namespace, stored.key]), item]);
219
+ }
220
+ }
221
+ }
222
+ const store = {
223
+ assistants: Object.entries(ops?.assistants ?? {}).map(([id, row]) => [
224
+ id,
225
+ toAssistant(row, now)
226
+ ]),
227
+ assistantVersions: (ops?.assistant_versions ?? []).map((row) => [
228
+ JSON.stringify([row.assistant_id, row.version]),
229
+ toAssistantVersion(row, now)
230
+ ]),
231
+ threads: Object.entries(ops?.threads ?? {}).map(([id, row]) => [id, toThread(row, now)]),
232
+ runs: runEntries.map(([id, row]) => [id, toRun(row, now)]),
233
+ runKwargs: runEntries.map(([id, row]) => [id, toRunKwargs(row.kwargs)]),
234
+ items
235
+ };
236
+ let checkpoints = { storage: {}, writes: {} };
237
+ if (checkpointerFile) {
238
+ const saver = new MemorySaver();
239
+ saver.storage = checkpointerFile.storage;
240
+ saver.writes = checkpointerFile.writes;
241
+ checkpoints = snapshotCheckpointer(saver);
242
+ }
243
+ return { version: 1, store, checkpoints };
244
+ }
245
+ function describeSnapshot(snapshot) {
246
+ return {
247
+ assistants: snapshot.store.assistants.length,
248
+ threads: snapshot.store.threads.length,
249
+ runs: snapshot.store.runs.length,
250
+ items: snapshot.store.items.length,
251
+ checkpointedThreads: Object.keys(snapshot.checkpoints.storage).length
252
+ };
253
+ }
254
+ function supportsRestore(store) {
255
+ return typeof store.restore === "function";
256
+ }
257
+ async function copyCheckpoints(snapshot, target) {
258
+ const source = new MemorySaver();
259
+ hydrateCheckpointer(source, snapshot);
260
+ const tuples = [];
261
+ for await (const tuple of source.list({})) tuples.push(tuple);
262
+ tuples.reverse();
263
+ for (const tuple of tuples) {
264
+ const configurable = tuple.config.configurable ?? {};
265
+ const putConfig = {
266
+ configurable: {
267
+ thread_id: configurable.thread_id,
268
+ checkpoint_ns: configurable.checkpoint_ns ?? "",
269
+ // `put` reads `checkpoint_id` as the PARENT pointer; the child's own id is `checkpoint.id`.
270
+ checkpoint_id: tuple.parentConfig?.configurable?.checkpoint_id
271
+ }
272
+ };
273
+ const stored = await target.put(
274
+ putConfig,
275
+ tuple.checkpoint,
276
+ tuple.metadata ?? {},
277
+ tuple.checkpoint.channel_versions ?? {}
278
+ );
279
+ const writesByTask = /* @__PURE__ */ new Map();
280
+ for (const [taskId, channel, value] of tuple.pendingWrites ?? []) {
281
+ const writes = writesByTask.get(taskId) ?? [];
282
+ writes.push([channel, value]);
283
+ writesByTask.set(taskId, writes);
284
+ }
285
+ for (const [taskId, writes] of writesByTask) {
286
+ await target.putWrites(stored, writes, taskId);
287
+ }
288
+ }
289
+ }
290
+ async function loadSnapshotIntoStore(snapshot, store, checkpointer) {
291
+ if (!supportsRestore(store)) {
292
+ throw new Error(
293
+ "Target store does not support bulk import (no restore() method). Use the in-memory or Postgres driver, or implement restore() on your SkeinStore."
294
+ );
295
+ }
296
+ await store.restore(snapshot.store);
297
+ await copyCheckpoints(snapshot.checkpoints, checkpointer);
298
+ }
299
+ export {
300
+ describeSnapshot,
301
+ loadSnapshotIntoStore,
302
+ readLanggraphDevState
303
+ };
@@ -0,0 +1,9 @@
1
+ import {
2
+ loadInMemoryRuntime,
3
+ loadReloadableInMemoryRuntime
4
+ } from "./chunk-QOHYARHD.js";
5
+ import "./chunk-JUBBCC7R.js";
6
+ export {
7
+ loadInMemoryRuntime,
8
+ loadReloadableInMemoryRuntime
9
+ };