@tanstack/ai-sandbox 0.3.4 → 0.5.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 +26 -0
- package/dist/esm/approvals.js +5 -4
- package/dist/esm/approvals.js.map +1 -1
- package/dist/esm/bridge-events.js +7 -6
- package/dist/esm/bridge-events.js.map +1 -1
- package/dist/esm/checkpoint-store.d.ts +147 -0
- package/dist/esm/checkpoint-store.js +267 -0
- package/dist/esm/checkpoint-store.js.map +1 -0
- package/dist/esm/chunk-identity.d.ts +0 -17
- package/dist/esm/chunk-identity.js +28 -5
- package/dist/esm/chunk-identity.js.map +1 -1
- package/dist/esm/contracts.d.ts +19 -0
- package/dist/esm/index.d.ts +11 -1
- package/dist/esm/index.js +12 -7
- package/dist/esm/memory-snapshot-types.d.ts +129 -0
- package/dist/esm/memory-snapshots.d.ts +6 -0
- package/dist/esm/memory-snapshots.js +490 -0
- package/dist/esm/memory-snapshots.js.map +1 -0
- package/dist/esm/middleware.d.ts +33 -1
- package/dist/esm/middleware.js +339 -94
- package/dist/esm/middleware.js.map +1 -1
- package/dist/esm/ngrok.d.ts +1 -1
- package/dist/esm/sandbox.d.ts +16 -0
- package/dist/esm/sandbox.js +62 -9
- package/dist/esm/sandbox.js.map +1 -1
- package/dist/esm/snapshot-operations.d.ts +65 -0
- package/dist/esm/snapshot-operations.js +317 -0
- package/dist/esm/snapshot-operations.js.map +1 -0
- package/dist/esm/snapshot-tools.d.ts +185 -0
- package/dist/esm/snapshot-tools.js +160 -0
- package/dist/esm/snapshot-tools.js.map +1 -0
- package/dist/esm/snapshots.d.ts +51 -0
- package/dist/esm/snapshots.js +350 -0
- package/dist/esm/snapshots.js.map +1 -0
- package/dist/esm/testkit/checkpoint-conformance.d.ts +2 -0
- package/dist/esm/testkit/checkpoint-conformance.js +453 -0
- package/dist/esm/testkit/checkpoint-conformance.js.map +1 -0
- package/dist/esm/testkit/checkpoint-fork-conformance.d.ts +18 -0
- package/dist/esm/testkit/checkpoint-fork-conformance.js +191 -0
- package/dist/esm/testkit/checkpoint-fork-conformance.js.map +1 -0
- package/dist/esm/testkit/conformance.d.ts +4 -0
- package/dist/esm/testkit/conformance.js +3 -1
- package/dist/esm/testkit/conformance.js.map +1 -1
- package/dist/esm/tool-history.js +4 -5
- package/dist/esm/tool-history.js.map +1 -1
- package/package.json +8 -3
- package/skills/ai-sandbox/SKILL.md +96 -8
- package/src/approvals.ts +13 -12
- package/src/bridge-events.ts +16 -10
- package/src/checkpoint-store.ts +652 -0
- package/src/chunk-identity.ts +36 -5
- package/src/contracts.ts +12 -0
- package/src/index.ts +56 -0
- package/src/memory-snapshot-types.ts +167 -0
- package/src/memory-snapshots.ts +936 -0
- package/src/middleware.ts +610 -160
- package/src/sandbox.ts +107 -6
- package/src/snapshot-operations.ts +540 -0
- package/src/snapshot-tools.ts +208 -0
- package/src/snapshots.ts +711 -0
- package/src/testkit/checkpoint-conformance.ts +472 -0
- package/src/testkit/checkpoint-fork-conformance.ts +299 -0
- package/src/testkit/conformance.ts +7 -0
- package/src/tool-history.ts +9 -13
|
@@ -11,23 +11,6 @@ import { StreamChunk } from '@tanstack/ai';
|
|
|
11
11
|
* seeded fresh for every call to this factory.
|
|
12
12
|
*/
|
|
13
13
|
export declare function createRunScopedIdGen(runId: string): () => string;
|
|
14
|
-
/**
|
|
15
|
-
* A stable, order-independent identity for a chunk, excluding wall-clock
|
|
16
|
-
* fields. Used to recognize the chunks a previous host already appended.
|
|
17
|
-
*
|
|
18
|
-
* - **Key-order independent**: object keys are sorted before stringifying, so
|
|
19
|
-
* a JSON round trip through the journal (which does not preserve key order)
|
|
20
|
-
* cannot spuriously diverge.
|
|
21
|
-
* - **Recurses into nested arrays and objects**: tool-call arguments are
|
|
22
|
-
* nested, and a shallow fingerprint would miss a changed argument.
|
|
23
|
-
* - **Excludes exactly `VOLATILE_FIELDS`** (`timestamp`) — everything else
|
|
24
|
-
* participates, including fields whose value is `undefined`.
|
|
25
|
-
* - **Distinguishes present-but-`undefined` from absent**: `undefined` is
|
|
26
|
-
* encoded as the sentinel string `"__undefined__"` rather than dropped, so
|
|
27
|
-
* `{a: undefined}` and `{}` do not collide. A translator emitting an
|
|
28
|
-
* explicit `undefined` is a different chunk shape and must fingerprint
|
|
29
|
-
* differently.
|
|
30
|
-
*/
|
|
31
14
|
export declare function chunkFingerprint(chunk: StreamChunk): string;
|
|
32
15
|
/**
|
|
33
16
|
* {@link chunkFingerprint} with the chunk's own `threadId` also excluded.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSpecTopLevelKey, tanstackMetadata } from "@tanstack/ai/adapter-internals";
|
|
1
2
|
//#region src/chunk-identity.ts
|
|
2
3
|
/**
|
|
3
4
|
* A deterministic id generator scoped to one run.
|
|
@@ -59,16 +60,36 @@ function stableStringify(value, dropped) {
|
|
|
59
60
|
* cannot spuriously diverge.
|
|
60
61
|
* - **Recurses into nested arrays and objects**: tool-call arguments are
|
|
61
62
|
* nested, and a shallow fingerprint would miss a changed argument.
|
|
62
|
-
* - **Excludes
|
|
63
|
-
*
|
|
63
|
+
* - **Excludes `timestamp` and leftover adapter extras.** Spec keys
|
|
64
|
+
* participate, including `undefined` values. `metadata.tanstack` is dropped
|
|
65
|
+
* so stored spec chunks match live adapter yields.
|
|
64
66
|
* - **Distinguishes present-but-`undefined` from absent**: `undefined` is
|
|
65
67
|
* encoded as the sentinel string `"__undefined__"` rather than dropped, so
|
|
66
68
|
* `{a: undefined}` and `{}` do not collide. A translator emitting an
|
|
67
69
|
* explicit `undefined` is a different chunk shape and must fingerprint
|
|
68
70
|
* differently.
|
|
69
71
|
*/
|
|
72
|
+
function fingerprintableChunk(chunk) {
|
|
73
|
+
const out = {};
|
|
74
|
+
for (const [key, value] of Object.entries(chunk)) {
|
|
75
|
+
if (key === "timestamp") continue;
|
|
76
|
+
if (!isSpecTopLevelKey(chunk.type, key)) continue;
|
|
77
|
+
if (key === "metadata" && value != null && typeof value === "object") {
|
|
78
|
+
const rest = {};
|
|
79
|
+
for (const [metaKey, metaValue] of Object.entries(value)) {
|
|
80
|
+
if (metaKey === "tanstack") continue;
|
|
81
|
+
rest[metaKey] = metaValue;
|
|
82
|
+
}
|
|
83
|
+
if (Object.keys(rest).length === 0) continue;
|
|
84
|
+
out.metadata = rest;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
out[key] = value;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
70
91
|
function chunkFingerprint(chunk) {
|
|
71
|
-
return stableStringify(chunk, VOLATILE_FIELDS);
|
|
92
|
+
return stableStringify(fingerprintableChunk(chunk), VOLATILE_FIELDS);
|
|
72
93
|
}
|
|
73
94
|
/**
|
|
74
95
|
* {@link chunkFingerprint} with the chunk's own `threadId` also excluded.
|
|
@@ -82,7 +103,7 @@ function chunkFingerprint(chunk) {
|
|
|
82
103
|
* `JournalReplayThreadIdMismatchError` in `align.ts`).
|
|
83
104
|
*/
|
|
84
105
|
function chunkFingerprintIgnoringThreadId(chunk) {
|
|
85
|
-
return stableStringify(chunk, VOLATILE_AND_THREAD_ID);
|
|
106
|
+
return stableStringify(fingerprintableChunk(chunk), VOLATILE_AND_THREAD_ID);
|
|
86
107
|
}
|
|
87
108
|
/**
|
|
88
109
|
* A chunk's own `threadId`, or `undefined` when it carries none.
|
|
@@ -94,7 +115,9 @@ function chunkFingerprintIgnoringThreadId(chunk) {
|
|
|
94
115
|
*/
|
|
95
116
|
function chunkThreadId(chunk) {
|
|
96
117
|
const value = chunk[THREAD_ID_FIELD];
|
|
97
|
-
|
|
118
|
+
if (typeof value === "string") return value;
|
|
119
|
+
const nested = tanstackMetadata(chunk)?.threadId;
|
|
120
|
+
return typeof nested === "string" ? nested : void 0;
|
|
98
121
|
}
|
|
99
122
|
//#endregion
|
|
100
123
|
export { chunkFingerprint, chunkFingerprintIgnoringThreadId, chunkThreadId, createRunScopedIdGen };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-identity.js","names":[],"sources":["../../src/chunk-identity.ts"],"sourcesContent":["/**\n * Deterministic chunk identity — the prerequisite that makes journal replay\n * exact.\n *\n * The design premise is that re-translating a journal prefix reproduces the\n * chunks a previous host already delivered, so a successor can recognize and\n * skip them (see `align.ts`, a later task). Two things in the default path\n * break that premise:\n *\n * 1. `ChatAdapter.generateId()` — `packages/ai/src/activities/chat/adapter.ts:227`,\n * read directly for this task — is:\n *\n * ```ts\n * protected generateId(): string {\n * return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n * }\n * ```\n *\n * and every harness translator mints message ids through it (wired as\n * `genId` in the Grok Build, Claude Code, and Codex text adapters). Both\n * `Date.now()` and `Math.random()` are non-reproducible: replaying the same\n * journal bytes through a second `generateId()` call produces a different\n * id every time, so \"same bytes ⇒ same chunks\" is false on the journaled\n * path today. {@link createRunScopedIdGen} replaces it with a run-scoped\n * counter that has neither a clock nor randomness, so two generators built\n * from the same `runId` always produce the same sequence.\n * 2. Chunks also carry `timestamp: Date.now()`, which cannot be reproduced at\n * all, deterministic id or not. {@link chunkFingerprint} therefore excludes\n * exactly that field — nothing downstream keys on a chunk's timestamp, so\n * leaving it wall-clock is safe, but every other field must participate in\n * the comparison or a real divergence would go undetected.\n */\nimport type { StreamChunk } from '@tanstack/ai'\n\n/**\n * A deterministic id generator scoped to one run.\n *\n * Passed as the harness translators' `genId`, so translating the same journal\n * prefix twice mints the same message ids. The counter is per-generator, so a\n * replay must create a fresh one and start from the journal's first byte —\n * which is exactly what the alignment step (a later task) assumes.\n *\n * No clock, no `Math.random`, no crypto: `next` is the only state, and it is\n * seeded fresh for every call to this factory.\n */\nexport function createRunScopedIdGen(runId: string): () => string {\n let next = 0\n return () => {\n const id = `${runId}-${next}`\n next += 1\n return id\n }\n}\n\n/**\n * Fields excluded from a fingerprint because they are wall-clock and therefore\n * unreproducible. Kept as an explicit set so adding one is a deliberate,\n * reviewable act rather than a silent loosening of the comparison.\n */\nconst VOLATILE_FIELDS: ReadonlySet<string> = new Set(['timestamp'])\n\n/**\n * The conversation id every chunk carries. Excluded from\n * {@link chunkFingerprintIgnoringThreadId} — and ONLY from that variant — so\n * alignment can tell an id-only mismatch from a real content divergence.\n */\nconst THREAD_ID_FIELD = 'threadId'\n\nconst VOLATILE_AND_THREAD_ID: ReadonlySet<string> = new Set([\n ...VOLATILE_FIELDS,\n THREAD_ID_FIELD,\n])\n\n/**\n * `dropped` applies at the TOP LEVEL only (nested calls pass `undefined`).\n * A `threadId` nested inside, say, a tool call's arguments is real content and\n * must keep participating in the comparison.\n */\nfunction stableStringify(\n value: unknown,\n dropped: ReadonlySet<string> | undefined,\n): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item, undefined)).join(',')}]`\n }\n if (typeof value === 'object') {\n const record: Record<string, unknown> = value as Record<string, unknown>\n const keys = Object.keys(record)\n .filter((key) => dropped === undefined || !dropped.has(key))\n .sort()\n const parts = keys.map((key) => {\n const entry = record[key]\n const encoded =\n entry === undefined\n ? '\"__undefined__\"'\n : stableStringify(entry, undefined)\n return `${JSON.stringify(key)}:${encoded}`\n })\n return `{${parts.join(',')}}`\n }\n const encoded = JSON.stringify(value)\n return encoded === undefined ? 'null' : encoded\n}\n\n/**\n * A stable, order-independent identity for a chunk, excluding wall-clock\n * fields. Used to recognize the chunks a previous host already appended.\n *\n * - **Key-order independent**: object keys are sorted before stringifying, so\n * a JSON round trip through the journal (which does not preserve key order)\n * cannot spuriously diverge.\n * - **Recurses into nested arrays and objects**: tool-call arguments are\n * nested, and a shallow fingerprint would miss a changed argument.\n * - **Excludes
|
|
1
|
+
{"version":3,"file":"chunk-identity.js","names":[],"sources":["../../src/chunk-identity.ts"],"sourcesContent":["/**\n * Deterministic chunk identity — the prerequisite that makes journal replay\n * exact.\n *\n * The design premise is that re-translating a journal prefix reproduces the\n * chunks a previous host already delivered, so a successor can recognize and\n * skip them (see `align.ts`, a later task). Two things in the default path\n * break that premise:\n *\n * 1. `ChatAdapter.generateId()` — `packages/ai/src/activities/chat/adapter.ts:227`,\n * read directly for this task — is:\n *\n * ```ts\n * protected generateId(): string {\n * return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`\n * }\n * ```\n *\n * and every harness translator mints message ids through it (wired as\n * `genId` in the Grok Build, Claude Code, and Codex text adapters). Both\n * `Date.now()` and `Math.random()` are non-reproducible: replaying the same\n * journal bytes through a second `generateId()` call produces a different\n * id every time, so \"same bytes ⇒ same chunks\" is false on the journaled\n * path today. {@link createRunScopedIdGen} replaces it with a run-scoped\n * counter that has neither a clock nor randomness, so two generators built\n * from the same `runId` always produce the same sequence.\n * 2. Chunks also carry `timestamp: Date.now()`, which cannot be reproduced at\n * all, deterministic id or not. {@link chunkFingerprint} therefore excludes\n * exactly that field — nothing downstream keys on a chunk's timestamp, so\n * leaving it wall-clock is safe, but every other field must participate in\n * the comparison or a real divergence would go undetected.\n * 3. Adapter yields still carry leftover TanStack extras (`content`, `args`,\n * `finishReason`). The durability log stores spec chunks. Fingerprints keep\n * only AG-UI spec keys and drop `metadata.tanstack`, so a live adapter yield\n * matches the stored spec chunk.\n */\nimport type { StreamChunk } from '@tanstack/ai'\nimport {\n isSpecTopLevelKey,\n tanstackMetadata,\n} from '@tanstack/ai/adapter-internals'\n\n/**\n * A deterministic id generator scoped to one run.\n *\n * Passed as the harness translators' `genId`, so translating the same journal\n * prefix twice mints the same message ids. The counter is per-generator, so a\n * replay must create a fresh one and start from the journal's first byte —\n * which is exactly what the alignment step (a later task) assumes.\n *\n * No clock, no `Math.random`, no crypto: `next` is the only state, and it is\n * seeded fresh for every call to this factory.\n */\nexport function createRunScopedIdGen(runId: string): () => string {\n let next = 0\n return () => {\n const id = `${runId}-${next}`\n next += 1\n return id\n }\n}\n\n/**\n * Fields excluded from a fingerprint because they are wall-clock and therefore\n * unreproducible. Kept as an explicit set so adding one is a deliberate,\n * reviewable act rather than a silent loosening of the comparison.\n */\nconst VOLATILE_FIELDS: ReadonlySet<string> = new Set(['timestamp'])\n\n/**\n * The conversation id every chunk carries. Excluded from\n * {@link chunkFingerprintIgnoringThreadId} — and ONLY from that variant — so\n * alignment can tell an id-only mismatch from a real content divergence.\n */\nconst THREAD_ID_FIELD = 'threadId'\n\nconst VOLATILE_AND_THREAD_ID: ReadonlySet<string> = new Set([\n ...VOLATILE_FIELDS,\n THREAD_ID_FIELD,\n])\n\n/**\n * `dropped` applies at the TOP LEVEL only (nested calls pass `undefined`).\n * A `threadId` nested inside, say, a tool call's arguments is real content and\n * must keep participating in the comparison.\n */\nfunction stableStringify(\n value: unknown,\n dropped: ReadonlySet<string> | undefined,\n): string {\n if (value === null) return 'null'\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableStringify(item, undefined)).join(',')}]`\n }\n if (typeof value === 'object') {\n const record: Record<string, unknown> = value as Record<string, unknown>\n const keys = Object.keys(record)\n .filter((key) => dropped === undefined || !dropped.has(key))\n .sort()\n const parts = keys.map((key) => {\n const entry = record[key]\n const encoded =\n entry === undefined\n ? '\"__undefined__\"'\n : stableStringify(entry, undefined)\n return `${JSON.stringify(key)}:${encoded}`\n })\n return `{${parts.join(',')}}`\n }\n const encoded = JSON.stringify(value)\n return encoded === undefined ? 'null' : encoded\n}\n\n/**\n * A stable, order-independent identity for a chunk, excluding wall-clock\n * fields. Used to recognize the chunks a previous host already appended.\n *\n * - **Key-order independent**: object keys are sorted before stringifying, so\n * a JSON round trip through the journal (which does not preserve key order)\n * cannot spuriously diverge.\n * - **Recurses into nested arrays and objects**: tool-call arguments are\n * nested, and a shallow fingerprint would miss a changed argument.\n * - **Excludes `timestamp` and leftover adapter extras.** Spec keys\n * participate, including `undefined` values. `metadata.tanstack` is dropped\n * so stored spec chunks match live adapter yields.\n * - **Distinguishes present-but-`undefined` from absent**: `undefined` is\n * encoded as the sentinel string `\"__undefined__\"` rather than dropped, so\n * `{a: undefined}` and `{}` do not collide. A translator emitting an\n * explicit `undefined` is a different chunk shape and must fingerprint\n * differently.\n */\nfunction fingerprintableChunk(chunk: StreamChunk): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(chunk)) {\n if (key === 'timestamp') continue\n if (!isSpecTopLevelKey(chunk.type, key)) continue\n if (key === 'metadata' && value != null && typeof value === 'object') {\n const rest: Record<string, unknown> = {}\n for (const [metaKey, metaValue] of Object.entries(value)) {\n if (metaKey === 'tanstack') continue\n rest[metaKey] = metaValue\n }\n if (Object.keys(rest).length === 0) continue\n out.metadata = rest\n continue\n }\n out[key] = value\n }\n return out\n}\n\nexport function chunkFingerprint(chunk: StreamChunk): string {\n return stableStringify(fingerprintableChunk(chunk), VOLATILE_FIELDS)\n}\n\n/**\n * {@link chunkFingerprint} with the chunk's own `threadId` also excluded.\n *\n * NOT an alternative identity — never use it to decide that two chunks are the\n * same. Its single purpose is DIAGNOSIS: when a replay diverges from the stored\n * log, comparing both fingerprints answers \"did the agent behave differently, or\n * did only the conversation id move?\". Two chunks that match here but not under\n * {@link chunkFingerprint} differ in `threadId` and nothing else, which is a\n * misconfigured attach route rather than a determinism regression (see\n * `JournalReplayThreadIdMismatchError` in `align.ts`).\n */\nexport function chunkFingerprintIgnoringThreadId(chunk: StreamChunk): string {\n return stableStringify(fingerprintableChunk(chunk), VOLATILE_AND_THREAD_ID)\n}\n\n/**\n * A chunk's own `threadId`, or `undefined` when it carries none.\n *\n * Reads the field structurally rather than narrowing on `chunk.type`: nearly\n * every member of the `StreamChunk` union declares `threadId?: string`, and an\n * exhaustive switch would have to be revisited for each new member while adding\n * nothing — a chunk with no `threadId` is exactly the `undefined` case.\n */\nexport function chunkThreadId(chunk: StreamChunk): string | undefined {\n const record: Record<string, unknown> = chunk as Record<string, unknown>\n const value = record[THREAD_ID_FIELD]\n if (typeof value === 'string') return value\n const nested = tanstackMetadata(chunk)?.threadId\n return typeof nested === 'string' ? nested : undefined\n}\n"],"mappings":";;;;;;;;;;;;;AAqDA,SAAgB,qBAAqB,OAA6B;CAChE,IAAI,OAAO;CACX,aAAa;EACX,MAAM,KAAK,GAAG,MAAM,GAAG;EACvB,QAAQ;EACR,OAAO;CACT;AACF;;;;;;AAOA,IAAM,kCAAuC,IAAI,IAAI,CAAC,WAAW,CAAC;;;;;;AAOlE,IAAM,kBAAkB;AAExB,IAAM,yCAA8C,IAAI,IAAI,CAC1D,GAAG,iBACH,eACF,CAAC;;;;;;AAOD,SAAS,gBACP,OACA,SACQ;CACR,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,IAAI,MAAM,KAAK,SAAS,gBAAgB,MAAM,KAAA,CAAS,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;CAE7E,IAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,SAAkC;EAYxC,OAAO,IAXM,OAAO,KAAK,MAAM,CAAC,CAC7B,QAAQ,QAAQ,YAAY,KAAA,KAAa,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAC3D,KACW,CAAA,CAAK,KAAK,QAAQ;GAC9B,MAAM,QAAQ,OAAO;GACrB,MAAM,UACJ,UAAU,KAAA,IACN,sBACA,gBAAgB,OAAO,KAAA,CAAS;GACtC,OAAO,GAAG,KAAK,UAAU,GAAG,EAAE,GAAG;EACnC,CACW,CAAA,CAAM,KAAK,GAAG,EAAE;CAC7B;CACA,MAAM,UAAU,KAAK,UAAU,KAAK;CACpC,OAAO,YAAY,KAAA,IAAY,SAAS;AAC1C;;;;;;;;;;;;;;;;;;;AAoBA,SAAS,qBAAqB,OAA6C;CACzE,MAAM,MAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,QAAQ,aAAa;EACzB,IAAI,CAAC,kBAAkB,MAAM,MAAM,GAAG,GAAG;EACzC,IAAI,QAAQ,cAAc,SAAS,QAAQ,OAAO,UAAU,UAAU;GACpE,MAAM,OAAgC,CAAC;GACvC,KAAK,MAAM,CAAC,SAAS,cAAc,OAAO,QAAQ,KAAK,GAAG;IACxD,IAAI,YAAY,YAAY;IAC5B,KAAK,WAAW;GAClB;GACA,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,GAAG;GACpC,IAAI,WAAW;GACf;EACF;EACA,IAAI,OAAO;CACb;CACA,OAAO;AACT;AAEA,SAAgB,iBAAiB,OAA4B;CAC3D,OAAO,gBAAgB,qBAAqB,KAAK,GAAG,eAAe;AACrE;;;;;;;;;;;;AAaA,SAAgB,iCAAiC,OAA4B;CAC3E,OAAO,gBAAgB,qBAAqB,KAAK,GAAG,sBAAsB;AAC5E;;;;;;;;;AAUA,SAAgB,cAAc,OAAwC;CAEpE,MAAM,QAAQ,MAAO;CACrB,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,MAAM,SAAS,iBAAiB,KAAK,CAAC,EAAE;CACxC,OAAO,OAAO,WAAW,WAAW,SAAS,KAAA;AAC/C"}
|
package/dist/esm/contracts.d.ts
CHANGED
|
@@ -98,6 +98,11 @@ export interface SandboxFs {
|
|
|
98
98
|
remove: (path: string) => Promise<void>;
|
|
99
99
|
rename: (from: string, to: string) => Promise<void>;
|
|
100
100
|
exists: (path: string) => Promise<boolean>;
|
|
101
|
+
/**
|
|
102
|
+
* Optional metadata lookup. Implementations must not follow symlinks.
|
|
103
|
+
* Returns undefined only for a confirmed missing path. All other errors reject.
|
|
104
|
+
*/
|
|
105
|
+
lstat?: (path: string) => Promise<SandboxFsStat | undefined>;
|
|
101
106
|
/** Optional — present only when `capabilities.fs` providers advertise watch. */
|
|
102
107
|
watch?: (path: string, onEvent: (event: {
|
|
103
108
|
type: string;
|
|
@@ -106,6 +111,20 @@ export interface SandboxFs {
|
|
|
106
111
|
stop: () => Promise<void>;
|
|
107
112
|
}>;
|
|
108
113
|
}
|
|
114
|
+
export type SandboxFsStat = {
|
|
115
|
+
type: 'file';
|
|
116
|
+
mode: number;
|
|
117
|
+
size: number;
|
|
118
|
+
} | {
|
|
119
|
+
type: 'dir';
|
|
120
|
+
mode: number;
|
|
121
|
+
} | {
|
|
122
|
+
type: 'symlink';
|
|
123
|
+
mode: number;
|
|
124
|
+
} | {
|
|
125
|
+
type: 'other';
|
|
126
|
+
mode: number;
|
|
127
|
+
};
|
|
109
128
|
/**
|
|
110
129
|
* Uniform git surface. Implementations either delegate to the provider's
|
|
111
130
|
* native git (when advertised) or desugar to `process.exec("git …")`, so the
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export { SandboxCapability, SandboxPolicyCapability, ToolBridgeProvisionerCapability, getSandbox, provideSandbox, getSandboxPolicy, provideSandboxPolicy, getToolBridgeProvisioner, provideToolBridgeProvisioner, } from './capabilities.js';
|
|
2
2
|
export { SandboxInstanceStoreCapability, getSandboxInstanceStore, provideSandboxInstanceStore, InMemorySandboxInstanceStore, defineSandboxInstanceStore, } from './instance-store.js';
|
|
3
3
|
export type { SandboxInstanceStore, SandboxInstanceRecord, } from './instance-store.js';
|
|
4
|
+
export { SandboxCheckpointError, SandboxCheckpointConflictError, SandboxCheckpointDuplicateIdError, SandboxCheckpointInvalidIdError, SandboxCheckpointInvalidEntryError, SandboxCheckpointParentMismatchError, SandboxCheckpointNotHeadError, SandboxCheckpointWriterConflictError, SandboxCheckpointWriterLostError, isForkCapableSandboxCheckpointStore, InMemorySandboxCheckpointStore, defineSandboxCheckpointStore, } from './checkpoint-store.js';
|
|
5
|
+
export type { SandboxCheckpoint, SandboxCheckpointStore, SandboxSnapshotEntry, SandboxSnapshotFileEntry, SandboxSnapshotDirectoryEntry, SandboxSnapshotArtifact, SandboxCheckpointErrorCode, SandboxCheckpointWriter, SandboxCheckpointWriterLease, SandboxCheckpointStoreOptions, SandboxCheckpointForkInput, SandboxCheckpointForkCapability, ForkCapableSandboxCheckpointStore, } from './checkpoint-store.js';
|
|
6
|
+
export { SandboxSnapshotError, defaultSandboxSnapshotPolicy } from './snapshots.js';
|
|
7
|
+
export type { SandboxSnapshotErrorCode, SandboxSnapshotPolicy, } from './snapshots.js';
|
|
8
|
+
export { memorySandboxSnapshots } from './memory-snapshots.js';
|
|
9
|
+
export type { MemorySandboxSnapshots, MemorySandboxSnapshotsOptions, } from './memory-snapshots.js';
|
|
10
|
+
export { createSandboxSnapshots } from './snapshot-operations.js';
|
|
11
|
+
export type { CreateSandboxSnapshotsInput, ForkSandboxSnapshotInput, ReadSandboxSnapshotArtifactInput, SandboxSnapshots, SaveSandboxSnapshotInput, SnapshotPersistence, } from './snapshot-operations.js';
|
|
12
|
+
export { createSnapshotTools } from './snapshot-tools.js';
|
|
13
|
+
export type { CreateSnapshotToolsOptions } from './snapshot-tools.js';
|
|
4
14
|
export { ProjectionCapability, getWorkspaceProjection, provideWorkspaceProjection, } from './projection.js';
|
|
5
15
|
export type { WorkspaceProjection } from './projection.js';
|
|
6
16
|
export { withSandbox } from './middleware.js';
|
|
@@ -14,7 +24,7 @@ export { createSecrets, bearer, isSecretRef, resolveSecret, resolveBearer, resol
|
|
|
14
24
|
export type { SecretRef, Secrets, BearerRef } from './secrets.js';
|
|
15
25
|
export { defineSandboxPolicy, evaluateCommand, commandAliases } from './policy.js';
|
|
16
26
|
export type { SandboxPolicy, PolicyDecision, CommandRules, CapabilityRules, } from './policy.js';
|
|
17
|
-
export type { SandboxProvider, SandboxHandle, SandboxCapabilities, SandboxFs, SandboxGit, SandboxProcess, SandboxPorts, SandboxEnv, SandboxChannel, SpawnHandle, ExecResult, ProcessOptions, SnapshotRef, SandboxCreateInput, SandboxResumeInput, SandboxRestoreInput, SandboxDestroyInput, } from './contracts.js';
|
|
27
|
+
export type { SandboxProvider, SandboxHandle, SandboxCapabilities, SandboxFs, SandboxFsStat, SandboxGit, SandboxProcess, SandboxPorts, SandboxEnv, SandboxChannel, SpawnHandle, ExecResult, ProcessOptions, SnapshotRef, SandboxCreateInput, SandboxResumeInput, SandboxRestoreInput, SandboxDestroyInput, } from './contracts.js';
|
|
18
28
|
export { bootstrapWorkspace, detectPackageManager, DEFAULT_WORKSPACE_ROOT, } from './bootstrap.js';
|
|
19
29
|
export { resolveHarnessCwd } from './harness-cwd.js';
|
|
20
30
|
export type { BootstrapResult } from './bootstrap.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { SandboxCapability, SandboxPolicyCapability, ToolBridgeProvisionerCapability, getSandbox, getSandboxPolicy, getToolBridgeProvisioner, provideSandbox, provideSandboxPolicy, provideToolBridgeProvisioner } from "./capabilities.js";
|
|
2
2
|
import { InMemorySandboxInstanceStore, SandboxInstanceStoreCapability, defineSandboxInstanceStore, getSandboxInstanceStore, provideSandboxInstanceStore } from "./instance-store.js";
|
|
3
|
+
import { InMemorySandboxCheckpointStore, SandboxCheckpointConflictError, SandboxCheckpointDuplicateIdError, SandboxCheckpointError, SandboxCheckpointInvalidEntryError, SandboxCheckpointInvalidIdError, SandboxCheckpointNotHeadError, SandboxCheckpointParentMismatchError, SandboxCheckpointWriterConflictError, SandboxCheckpointWriterLostError, defineSandboxCheckpointStore, isForkCapableSandboxCheckpointStore } from "./checkpoint-store.js";
|
|
4
|
+
import { SandboxSnapshotError, defaultSandboxSnapshotPolicy } from "./snapshots.js";
|
|
5
|
+
import { bearer, createSecrets, isSecretRef, resolveAllSecrets, resolveBearer, resolveSecret } from "./secrets.js";
|
|
6
|
+
import { computeSandboxKey, computeWorkspaceHash } from "./key.js";
|
|
7
|
+
import { resolveHarnessCwd } from "./harness-cwd.js";
|
|
8
|
+
import { discoverSkillDirs, formatWorkspaceScriptsSection, mergeAgentsContent, resolveGitSkillDir, writeAgentsFile } from "./agents-file.js";
|
|
9
|
+
import { DEFAULT_WORKSPACE_ROOT, bootstrapWorkspace, detectPackageManager } from "./bootstrap.js";
|
|
10
|
+
import { defineSandbox } from "./sandbox.js";
|
|
11
|
+
import { createSandboxSnapshots } from "./snapshot-operations.js";
|
|
12
|
+
import { memorySandboxSnapshots } from "./memory-snapshots.js";
|
|
13
|
+
import { createSnapshotTools } from "./snapshot-tools.js";
|
|
3
14
|
import { ProjectionCapability, getWorkspaceProjection, provideWorkspaceProjection } from "./projection.js";
|
|
4
15
|
import { DEFAULT_JOURNAL_DIR, EXIT_SENTINEL_KEY, EXIT_SENTINEL_NONCE_KEY, decodeJournalRunId, encodeRunId, exitSentinelLine, journalExistsCommand, journalExitProbeCommand, journalFollowCommand, journalListCommand, journalMtimeListCommand, journalPaths, journalReadCommand, journaledCommand, parseExitSentinel, parseJournalExit, parseJournalMtimeListing } from "./journal.js";
|
|
5
16
|
import { chunkFingerprint, chunkFingerprintIgnoringThreadId, chunkThreadId, createRunScopedIdGen } from "./chunk-identity.js";
|
|
6
17
|
import { DEFAULT_MAX_OUT_OF_BAND_SKIP, JournalReplayDivergedError, JournalReplayThreadIdMismatchError, alignToStoredLog, isBridgeCustomChunk } from "./align.js";
|
|
7
18
|
import { DurableAttachNotSupportedError, DurableRunIdRequiredError, DurableThreadIdRequiredError, SandboxDurabilityCapability, alignedIfAttaching, getSandboxDurability, journalOptionsFor, provideSandboxDurability, resolveDurableRunId, resolveDurableThreadId } from "./durability.js";
|
|
8
|
-
import { computeSandboxKey, computeWorkspaceHash } from "./key.js";
|
|
9
|
-
import { bearer, createSecrets, isSecretRef, resolveAllSecrets, resolveBearer, resolveSecret } from "./secrets.js";
|
|
10
19
|
import { isSandboxToolCall } from "./tool-history.js";
|
|
11
|
-
import { resolveHarnessCwd } from "./harness-cwd.js";
|
|
12
|
-
import { discoverSkillDirs, formatWorkspaceScriptsSection, mergeAgentsContent, resolveGitSkillDir, writeAgentsFile } from "./agents-file.js";
|
|
13
|
-
import { DEFAULT_WORKSPACE_ROOT, bootstrapWorkspace, detectPackageManager } from "./bootstrap.js";
|
|
14
20
|
import { diffSnapshots, watchWorkspace } from "./watch.js";
|
|
15
21
|
import { withSandbox } from "./middleware.js";
|
|
16
|
-
import { defineSandbox } from "./sandbox.js";
|
|
17
22
|
import { agentSkill, defineWorkspace, fileSkill, gitSkill, gitSource, githubRepo, localSource, mcpSkill } from "./workspace.js";
|
|
18
23
|
import { commandAliases, defineSandboxPolicy, evaluateCommand } from "./policy.js";
|
|
19
24
|
import { createExecBackedGit } from "./git-exec.js";
|
|
@@ -32,4 +37,4 @@ import { createBridgeEventChannel, mergeChunkStreams } from "./bridge-events.js"
|
|
|
32
37
|
import { executeHostTool, httpRemoteToolExecutor, isToolExecRequest, remoteToolStubs, toolDescriptors } from "./remote-tools.js";
|
|
33
38
|
import { APPROVAL_REQUESTED_EVENT, approvalId, buildApprovalRequestedEvent, resolveApproval } from "./approvals.js";
|
|
34
39
|
import { MissingSandboxError, UnsupportedCapabilityError } from "./errors.js";
|
|
35
|
-
export { APPROVAL_REQUESTED_EVENT, BRIDGED_MCP_SERVER_NAME, DEFAULT_ATTACH_JOURNAL_WAIT_MS, DEFAULT_ATTACH_PROBE_INTERVAL_MS, DEFAULT_EXIT_PROBE_BYTES, DEFAULT_FENCE_QUIET_MS, DEFAULT_JOURNAL_DIR, DEFAULT_JOURNAL_POLL_MS, DEFAULT_MAX_DELETES, DEFAULT_MAX_OUT_OF_BAND_SKIP, DEFAULT_MAX_RUNS, DEFAULT_ORPHAN_TTL_MS, DEFAULT_RUN_BUDGET_MS, DEFAULT_WORKSPACE_ROOT, DurableAttachNotSupportedError, DurableRunIdRequiredError, DurableThreadIdRequiredError, EXIT_SENTINEL_KEY, EXIT_SENTINEL_NONCE_KEY, InMemorySandboxInstanceStore, JournalAttachUnavailableError, JournalReplayDivergedError, JournalReplayThreadIdMismatchError, MissingSandboxError, ProjectionCapability, RunClaimLostError, RunClaimNotAcquiredError, RunController, RunDriverPipeOutsideClaimError, SandboxCapability, SandboxDurabilityCapability, SandboxInstanceStoreCapability, SandboxPolicyCapability, SandboxReclaimFailedError, ToolBridgeProvisionerCapability, UnsupportedCapabilityError, agentSkill, alignToStoredLog, alignedIfAttaching, approvalId, awaitAttachableJournal, bearer, bootstrapWorkspace, buildApprovalRequestedEvent, chunkFingerprint, chunkFingerprintIgnoringThreadId, chunkThreadId, commandAliases, computeSandboxKey, computeWorkspaceHash, createBridgeEventChannel, createExecBackedGit, createRunScopedIdGen, createSecrets, createToolBridgeCore, decodeBase64Stream, decodeJournalRunId, defineSandbox, defineSandboxInstanceStore, defineSandboxPolicy, defineWorkspace, detectPackageManager, diffSnapshots, discoverSkillDirs, encodeRunId, evaluateCommand, executeHostTool, exitSentinelLine, fileSkill, formatWorkspaceScriptsSection, getSandbox, getSandboxDurability, getSandboxInstanceStore, getSandboxPolicy, getToolBridgeProvisioner, getWorkspaceProjection, gitSkill, gitSource, githubRepo, handleBridgeJsonRpc, hostForSandbox, httpRemoteToolExecutor, isBridgeCustomChunk, isSandboxToolCall, isSecretRef, isToolExecRequest, journalExistsCommand, journalExitProbeCommand, journalFollowCommand, journalListCommand, journalMtimeListCommand, journalOptionsFor, journalPaths, journalReadCommand, journalReadStrategy, journaledCommand, localSource, mcpSkill, mergeAgentsContent, mergeChunkStreams, nodeHttpBridgeProvisioner, parseExitSentinel, parseJournalExit, parseJournalMtimeListing, pipeToRunLog, probeRunExit, provideSandbox, provideSandboxDurability, provideSandboxInstanceStore, provideSandboxPolicy, provideToolBridgeProvisioner, provideWorkspaceProjection, pruneJournals, readJournal, readJournalNdjson, reapDetachedRuns, reclaimSandbox, remoteToolStubs, resolveAllSecrets, resolveApproval, resolveBearer, resolveDurableRunId, resolveDurableThreadId, resolveGitSkillDir, resolveHarnessCwd, resolveSecret, sandboxReclaimer, sandboxRunDriver, spawnNdjson, startHostToolBridge, startJournaledAgent, timingSafeBearerEqual, toJournalLines, toLines, toolDescriptors, watchWorkspace, withSandbox, writeAgentsFile };
|
|
40
|
+
export { APPROVAL_REQUESTED_EVENT, BRIDGED_MCP_SERVER_NAME, DEFAULT_ATTACH_JOURNAL_WAIT_MS, DEFAULT_ATTACH_PROBE_INTERVAL_MS, DEFAULT_EXIT_PROBE_BYTES, DEFAULT_FENCE_QUIET_MS, DEFAULT_JOURNAL_DIR, DEFAULT_JOURNAL_POLL_MS, DEFAULT_MAX_DELETES, DEFAULT_MAX_OUT_OF_BAND_SKIP, DEFAULT_MAX_RUNS, DEFAULT_ORPHAN_TTL_MS, DEFAULT_RUN_BUDGET_MS, DEFAULT_WORKSPACE_ROOT, DurableAttachNotSupportedError, DurableRunIdRequiredError, DurableThreadIdRequiredError, EXIT_SENTINEL_KEY, EXIT_SENTINEL_NONCE_KEY, InMemorySandboxCheckpointStore, InMemorySandboxInstanceStore, JournalAttachUnavailableError, JournalReplayDivergedError, JournalReplayThreadIdMismatchError, MissingSandboxError, ProjectionCapability, RunClaimLostError, RunClaimNotAcquiredError, RunController, RunDriverPipeOutsideClaimError, SandboxCapability, SandboxCheckpointConflictError, SandboxCheckpointDuplicateIdError, SandboxCheckpointError, SandboxCheckpointInvalidEntryError, SandboxCheckpointInvalidIdError, SandboxCheckpointNotHeadError, SandboxCheckpointParentMismatchError, SandboxCheckpointWriterConflictError, SandboxCheckpointWriterLostError, SandboxDurabilityCapability, SandboxInstanceStoreCapability, SandboxPolicyCapability, SandboxReclaimFailedError, SandboxSnapshotError, ToolBridgeProvisionerCapability, UnsupportedCapabilityError, agentSkill, alignToStoredLog, alignedIfAttaching, approvalId, awaitAttachableJournal, bearer, bootstrapWorkspace, buildApprovalRequestedEvent, chunkFingerprint, chunkFingerprintIgnoringThreadId, chunkThreadId, commandAliases, computeSandboxKey, computeWorkspaceHash, createBridgeEventChannel, createExecBackedGit, createRunScopedIdGen, createSandboxSnapshots, createSecrets, createSnapshotTools, createToolBridgeCore, decodeBase64Stream, decodeJournalRunId, defaultSandboxSnapshotPolicy, defineSandbox, defineSandboxCheckpointStore, defineSandboxInstanceStore, defineSandboxPolicy, defineWorkspace, detectPackageManager, diffSnapshots, discoverSkillDirs, encodeRunId, evaluateCommand, executeHostTool, exitSentinelLine, fileSkill, formatWorkspaceScriptsSection, getSandbox, getSandboxDurability, getSandboxInstanceStore, getSandboxPolicy, getToolBridgeProvisioner, getWorkspaceProjection, gitSkill, gitSource, githubRepo, handleBridgeJsonRpc, hostForSandbox, httpRemoteToolExecutor, isBridgeCustomChunk, isForkCapableSandboxCheckpointStore, isSandboxToolCall, isSecretRef, isToolExecRequest, journalExistsCommand, journalExitProbeCommand, journalFollowCommand, journalListCommand, journalMtimeListCommand, journalOptionsFor, journalPaths, journalReadCommand, journalReadStrategy, journaledCommand, localSource, mcpSkill, memorySandboxSnapshots, mergeAgentsContent, mergeChunkStreams, nodeHttpBridgeProvisioner, parseExitSentinel, parseJournalExit, parseJournalMtimeListing, pipeToRunLog, probeRunExit, provideSandbox, provideSandboxDurability, provideSandboxInstanceStore, provideSandboxPolicy, provideToolBridgeProvisioner, provideWorkspaceProjection, pruneJournals, readJournal, readJournalNdjson, reapDetachedRuns, reclaimSandbox, remoteToolStubs, resolveAllSecrets, resolveApproval, resolveBearer, resolveDurableRunId, resolveDurableThreadId, resolveGitSkillDir, resolveHarnessCwd, resolveSecret, sandboxReclaimer, sandboxRunDriver, spawnNdjson, startHostToolBridge, startJournaledAgent, timingSafeBearerEqual, toJournalLines, toLines, toolDescriptors, watchWorkspace, withSandbox, writeAgentsFile };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ModelMessage, RunRecord, RunStatus, RunStore, PersistedArtifactRef, TokenUsage } from '@tanstack/ai';
|
|
2
|
+
export interface MemoryMessageStore {
|
|
3
|
+
loadThread: (threadId: string) => Promise<Array<ModelMessage>>;
|
|
4
|
+
saveThread: (threadId: string, messages: Array<ModelMessage>) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export type MemoryRunRecord = RunRecord;
|
|
7
|
+
export type MemoryRunStore = RunStore;
|
|
8
|
+
export interface MemoryGenerationRunRecord {
|
|
9
|
+
runId: string;
|
|
10
|
+
threadId: string;
|
|
11
|
+
activity: string;
|
|
12
|
+
provider: string;
|
|
13
|
+
model: string;
|
|
14
|
+
status: RunStatus;
|
|
15
|
+
startedAt: number;
|
|
16
|
+
finishedAt?: number;
|
|
17
|
+
error?: {
|
|
18
|
+
message: string;
|
|
19
|
+
code?: string;
|
|
20
|
+
};
|
|
21
|
+
result?: unknown;
|
|
22
|
+
artifacts?: Array<PersistedArtifactRef>;
|
|
23
|
+
usage?: TokenUsage;
|
|
24
|
+
}
|
|
25
|
+
export interface MemoryGenerationRunStore {
|
|
26
|
+
createOrResume: (input: Pick<MemoryGenerationRunRecord, 'runId' | 'threadId' | 'activity' | 'provider' | 'model' | 'startedAt'> & {
|
|
27
|
+
status?: RunStatus;
|
|
28
|
+
}) => Promise<MemoryGenerationRunRecord>;
|
|
29
|
+
update: (runId: string, patch: Partial<Pick<MemoryGenerationRunRecord, 'status' | 'finishedAt' | 'error' | 'result' | 'artifacts' | 'usage'>>) => Promise<void>;
|
|
30
|
+
get: (runId: string) => Promise<MemoryGenerationRunRecord | null>;
|
|
31
|
+
findLatestForThread: (threadId: string) => Promise<MemoryGenerationRunRecord | null>;
|
|
32
|
+
}
|
|
33
|
+
export interface MemoryInterruptRecord {
|
|
34
|
+
interruptId: string;
|
|
35
|
+
runId: string;
|
|
36
|
+
threadId: string;
|
|
37
|
+
status: 'pending' | 'resolved' | 'cancelled';
|
|
38
|
+
requestedAt: number;
|
|
39
|
+
resolvedAt?: number;
|
|
40
|
+
payload: Record<string, unknown>;
|
|
41
|
+
response?: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface MemoryInterruptStore {
|
|
44
|
+
create: (record: Omit<MemoryInterruptRecord, 'status' | 'resolvedAt'>) => Promise<void>;
|
|
45
|
+
resolve: (interruptId: string, response?: unknown) => Promise<void>;
|
|
46
|
+
cancel: (interruptId: string) => Promise<void>;
|
|
47
|
+
get: (interruptId: string) => Promise<MemoryInterruptRecord | null>;
|
|
48
|
+
list: (threadId: string) => Promise<Array<MemoryInterruptRecord>>;
|
|
49
|
+
listPending: (threadId: string) => Promise<Array<MemoryInterruptRecord>>;
|
|
50
|
+
listByRun: (runId: string) => Promise<Array<MemoryInterruptRecord>>;
|
|
51
|
+
listPendingByRun: (runId: string) => Promise<Array<MemoryInterruptRecord>>;
|
|
52
|
+
}
|
|
53
|
+
export interface MemoryMetadataStore {
|
|
54
|
+
get: (namespace: string, key: string) => Promise<unknown | null>;
|
|
55
|
+
set: (namespace: string, key: string, value: unknown) => Promise<void>;
|
|
56
|
+
delete: (namespace: string, key: string) => Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
export interface MemoryArtifactRecord {
|
|
59
|
+
artifactId: string;
|
|
60
|
+
runId: string;
|
|
61
|
+
threadId: string;
|
|
62
|
+
blobKey?: string;
|
|
63
|
+
name: string;
|
|
64
|
+
mimeType: string;
|
|
65
|
+
size: number;
|
|
66
|
+
sourceUrl?: string;
|
|
67
|
+
createdAt: number;
|
|
68
|
+
}
|
|
69
|
+
export interface MemoryArtifactStore {
|
|
70
|
+
save: (record: MemoryArtifactRecord) => Promise<void>;
|
|
71
|
+
get: (artifactId: string) => Promise<MemoryArtifactRecord | null>;
|
|
72
|
+
list: (runId: string) => Promise<Array<MemoryArtifactRecord>>;
|
|
73
|
+
listForThread: (threadId: string) => Promise<Array<MemoryArtifactRecord>>;
|
|
74
|
+
delete: (artifactId: string) => Promise<void>;
|
|
75
|
+
deleteForRun: (runId: string) => Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export type MemoryBlobBody = ReadableStream<Uint8Array> | ArrayBuffer | ArrayBufferView | string | Blob;
|
|
78
|
+
export interface MemoryBlobRecord {
|
|
79
|
+
key: string;
|
|
80
|
+
size?: number;
|
|
81
|
+
etag?: string;
|
|
82
|
+
contentType?: string;
|
|
83
|
+
customMetadata?: Record<string, string>;
|
|
84
|
+
createdAt?: number;
|
|
85
|
+
updatedAt?: number;
|
|
86
|
+
}
|
|
87
|
+
export interface MemoryBlobStore {
|
|
88
|
+
put: (key: string, body: MemoryBlobBody, options?: {
|
|
89
|
+
contentType?: string;
|
|
90
|
+
customMetadata?: Record<string, string>;
|
|
91
|
+
expectedLength?: number;
|
|
92
|
+
}) => Promise<MemoryBlobRecord>;
|
|
93
|
+
get: (key: string, options?: {
|
|
94
|
+
range?: {
|
|
95
|
+
offset: number;
|
|
96
|
+
length?: number;
|
|
97
|
+
};
|
|
98
|
+
}) => Promise<(MemoryBlobRecord & {
|
|
99
|
+
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
100
|
+
text: () => Promise<string>;
|
|
101
|
+
body?: ReadableStream<Uint8Array>;
|
|
102
|
+
range?: {
|
|
103
|
+
offset: number;
|
|
104
|
+
length: number;
|
|
105
|
+
};
|
|
106
|
+
}) | null>;
|
|
107
|
+
head: (key: string) => Promise<MemoryBlobRecord | null>;
|
|
108
|
+
delete: (key: string) => Promise<void>;
|
|
109
|
+
list: (options?: {
|
|
110
|
+
prefix?: string;
|
|
111
|
+
cursor?: string;
|
|
112
|
+
limit?: number;
|
|
113
|
+
}) => Promise<{
|
|
114
|
+
objects: Array<MemoryBlobRecord>;
|
|
115
|
+
cursor?: string;
|
|
116
|
+
truncated?: boolean;
|
|
117
|
+
}>;
|
|
118
|
+
}
|
|
119
|
+
export interface MemorySnapshotPersistence {
|
|
120
|
+
stores: {
|
|
121
|
+
messages: MemoryMessageStore;
|
|
122
|
+
runs: MemoryRunStore;
|
|
123
|
+
generationRuns: MemoryGenerationRunStore;
|
|
124
|
+
interrupts: MemoryInterruptStore;
|
|
125
|
+
metadata: MemoryMetadataStore;
|
|
126
|
+
artifacts: MemoryArtifactStore;
|
|
127
|
+
blobs: MemoryBlobStore;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MemorySnapshotPersistence } from './memory-snapshot-types.js';
|
|
2
|
+
import { ForkCapableSandboxCheckpointStore } from './checkpoint-store.js';
|
|
3
|
+
import { CreateSandboxSnapshotsInput, SandboxSnapshots } from './snapshot-operations.js';
|
|
4
|
+
export type MemorySandboxSnapshots = SandboxSnapshots<MemorySnapshotPersistence, ForkCapableSandboxCheckpointStore>;
|
|
5
|
+
export type MemorySandboxSnapshotsOptions = Omit<CreateSandboxSnapshotsInput<MemorySnapshotPersistence, ForkCapableSandboxCheckpointStore>, 'persistence' | 'checkpoints'>;
|
|
6
|
+
export declare function memorySandboxSnapshots(options?: MemorySandboxSnapshotsOptions): Promise<MemorySandboxSnapshots>;
|