@superdurable/dex-agents 0.4.0 → 0.6.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.
Files changed (144) hide show
  1. package/README.md +616 -55
  2. package/dist/src/agent-approval-display.d.ts +135 -0
  3. package/dist/src/agent-approval-display.js +536 -0
  4. package/dist/src/agent-approval-display.js.map +1 -0
  5. package/dist/src/agent-context-compaction.d.ts +1 -1
  6. package/dist/src/agent-framework-runner.d.ts +160 -12
  7. package/dist/src/agent-framework-runner.js +4 -0
  8. package/dist/src/agent-framework-runner.js.map +1 -1
  9. package/dist/src/agent-local-directory-media-store.d.ts +111 -0
  10. package/dist/src/agent-local-directory-media-store.js +417 -0
  11. package/dist/src/agent-local-directory-media-store.js.map +1 -0
  12. package/dist/src/agent-media.d.ts +279 -0
  13. package/dist/src/agent-media.js +457 -0
  14. package/dist/src/agent-media.js.map +1 -0
  15. package/dist/src/agent-session-codecs.d.ts +5 -1
  16. package/dist/src/agent-session-codecs.js +76 -4
  17. package/dist/src/agent-session-codecs.js.map +1 -1
  18. package/dist/src/agent-session-failure.d.ts +4 -2
  19. package/dist/src/agent-session-failure.js +6 -2
  20. package/dist/src/agent-session-failure.js.map +1 -1
  21. package/dist/src/agent-session-flow-graph.d.ts +46 -0
  22. package/dist/src/agent-session-flow-graph.js +51 -0
  23. package/dist/src/agent-session-flow-graph.js.map +1 -1
  24. package/dist/src/agent-session-flow.d.ts +28 -3
  25. package/dist/src/agent-session-flow.js +21 -1
  26. package/dist/src/agent-session-flow.js.map +1 -1
  27. package/dist/src/agent-session-persistence.d.ts +33 -0
  28. package/dist/src/agent-session-persistence.js +22 -1
  29. package/dist/src/agent-session-persistence.js.map +1 -1
  30. package/dist/src/agent-session-start.d.ts +1 -1
  31. package/dist/src/agent-session-start.js +2 -2
  32. package/dist/src/agent-session-start.js.map +1 -1
  33. package/dist/src/agent-session-steps.d.ts +2 -0
  34. package/dist/src/agent-session-steps.js +74 -5
  35. package/dist/src/agent-session-steps.js.map +1 -1
  36. package/dist/src/agent-session-summary.d.ts +138 -0
  37. package/dist/src/agent-session-summary.js +151 -0
  38. package/dist/src/agent-session-summary.js.map +1 -0
  39. package/dist/src/agent-session-tracer.js +1 -1
  40. package/dist/src/agent-session-tracer.js.map +1 -1
  41. package/dist/src/agent-session-transitions.d.ts +11 -3
  42. package/dist/src/agent-session-transitions.js +58 -6
  43. package/dist/src/agent-session-transitions.js.map +1 -1
  44. package/dist/src/agent-session-values.d.ts +179 -2
  45. package/dist/src/agent-session-values.js.map +1 -1
  46. package/dist/src/agent-session-wait-steps.js +14 -2
  47. package/dist/src/agent-session-wait-steps.js.map +1 -1
  48. package/dist/src/ai-sdk/ai-sdk-model-client.d.ts +15 -3
  49. package/dist/src/ai-sdk/ai-sdk-model-client.js +36 -7
  50. package/dist/src/ai-sdk/ai-sdk-model-client.js.map +1 -1
  51. package/dist/src/ai-sdk/index.d.ts +1 -1
  52. package/dist/src/ai-sdk/index.js +1 -1
  53. package/dist/src/ai-sdk/index.js.map +1 -1
  54. package/dist/src/{stepwise → builtin-loop}/agent-definition.d.ts +120 -5
  55. package/dist/src/builtin-loop/agent-definition.js.map +1 -0
  56. package/dist/src/builtin-loop/builtin-agent-session-flow.d.ts +77 -0
  57. package/dist/src/{stepwise/stepwise-agent-session-flow.js → builtin-loop/builtin-agent-session-flow.js} +19 -9
  58. package/dist/src/builtin-loop/builtin-agent-session-flow.js.map +1 -0
  59. package/dist/src/{stepwise/stepwise-agent-runner.d.ts → builtin-loop/builtin-loop-agent-runner.d.ts} +72 -14
  60. package/dist/src/{stepwise/stepwise-agent-runner.js → builtin-loop/builtin-loop-agent-runner.js} +284 -41
  61. package/dist/src/builtin-loop/builtin-loop-agent-runner.js.map +1 -0
  62. package/dist/src/{stepwise/stepwise-input-items.d.ts → builtin-loop/builtin-loop-input-items.d.ts} +7 -3
  63. package/dist/src/{stepwise/stepwise-input-items.js → builtin-loop/builtin-loop-input-items.js} +57 -10
  64. package/dist/src/builtin-loop/builtin-loop-input-items.js.map +1 -0
  65. package/dist/src/builtin-loop/function-tool.d.ts +282 -0
  66. package/dist/src/{stepwise → builtin-loop}/function-tool.js +63 -3
  67. package/dist/src/builtin-loop/function-tool.js.map +1 -0
  68. package/dist/src/builtin-loop/index.d.ts +8 -0
  69. package/dist/src/builtin-loop/index.js +13 -0
  70. package/dist/src/builtin-loop/index.js.map +1 -0
  71. package/dist/src/builtin-loop/json-schema-validation.js.map +1 -0
  72. package/dist/src/{stepwise → builtin-loop}/model-client.d.ts +36 -7
  73. package/dist/src/builtin-loop/model-client.js.map +1 -0
  74. package/dist/src/{stepwise → builtin-loop}/scripted-model-client.d.ts +8 -5
  75. package/dist/src/{stepwise → builtin-loop}/scripted-model-client.js +8 -5
  76. package/dist/src/builtin-loop/scripted-model-client.js.map +1 -0
  77. package/dist/src/{stepwise → builtin-loop}/tool-source.d.ts +2 -2
  78. package/dist/src/builtin-loop/tool-source.js.map +1 -0
  79. package/dist/src/connectors/connector-input-schema.js +1 -1
  80. package/dist/src/connectors/connector-input-schema.js.map +1 -1
  81. package/dist/src/connectors/connector-step-context.d.ts +19 -2
  82. package/dist/src/connectors/connector-step-context.js +61 -5
  83. package/dist/src/connectors/connector-step-context.js.map +1 -1
  84. package/dist/src/connectors/connector-tool-source.d.ts +63 -14
  85. package/dist/src/connectors/connector-tool-source.js +124 -25
  86. package/dist/src/connectors/connector-tool-source.js.map +1 -1
  87. package/dist/src/index.d.ts +8 -4
  88. package/dist/src/index.js +5 -1
  89. package/dist/src/index.js.map +1 -1
  90. package/dist/src/mcp/index.d.ts +1 -0
  91. package/dist/src/mcp/index.js +1 -0
  92. package/dist/src/mcp/index.js.map +1 -1
  93. package/dist/src/mcp/mcp-dex-conventions.d.ts +57 -0
  94. package/dist/src/mcp/mcp-dex-conventions.js +90 -0
  95. package/dist/src/mcp/mcp-dex-conventions.js.map +1 -0
  96. package/dist/src/mcp/mcp-image-content.d.ts +20 -0
  97. package/dist/src/mcp/mcp-image-content.js +82 -0
  98. package/dist/src/mcp/mcp-image-content.js.map +1 -0
  99. package/dist/src/mcp/mcp-tool-source.d.ts +205 -18
  100. package/dist/src/mcp/mcp-tool-source.js +289 -47
  101. package/dist/src/mcp/mcp-tool-source.js.map +1 -1
  102. package/dist/src/s3/index.d.ts +1 -0
  103. package/dist/src/s3/index.js +9 -0
  104. package/dist/src/s3/index.js.map +1 -0
  105. package/dist/src/s3/s3-media-store.d.ts +138 -0
  106. package/dist/src/s3/s3-media-store.js +255 -0
  107. package/dist/src/s3/s3-media-store.js.map +1 -0
  108. package/dist/src/stepwise/index.d.ts +41 -8
  109. package/dist/src/stepwise/index.js +35 -5
  110. package/dist/src/stepwise/index.js.map +1 -1
  111. package/dist/src/testing/agent-session-test-client.d.ts +6 -3
  112. package/dist/src/testing/agent-session-test-client.js +10 -3
  113. package/dist/src/testing/agent-session-test-client.js.map +1 -1
  114. package/dist/src/testing/private-dex-engine.d.ts +8 -0
  115. package/dist/src/testing/private-dex-engine.js +17 -1
  116. package/dist/src/testing/private-dex-engine.js.map +1 -1
  117. package/dist/src/testing/scripted-model-client.d.ts +1 -1
  118. package/dist/src/testing/scripted-model-client.js +2 -2
  119. package/dist/src/testing/scripted-model-client.js.map +1 -1
  120. package/dist/src/tool-source-router.d.ts +3 -3
  121. package/dist/src/tool-source-router.js +2 -2
  122. package/dist/src/ui-stream/agent-event-json.d.ts +2 -1
  123. package/dist/src/ui-stream/agent-event-json.js +3 -1
  124. package/dist/src/ui-stream/agent-event-json.js.map +1 -1
  125. package/dist/src/ui-stream/agent-ui-messages.d.ts +11 -3
  126. package/dist/src/ui-stream/agent-ui-messages.js +29 -5
  127. package/dist/src/ui-stream/agent-ui-messages.js.map +1 -1
  128. package/package.json +17 -4
  129. package/dist/src/stepwise/agent-definition.js.map +0 -1
  130. package/dist/src/stepwise/function-tool.d.ts +0 -130
  131. package/dist/src/stepwise/function-tool.js.map +0 -1
  132. package/dist/src/stepwise/json-schema-validation.js.map +0 -1
  133. package/dist/src/stepwise/model-client.js.map +0 -1
  134. package/dist/src/stepwise/scripted-model-client.js.map +0 -1
  135. package/dist/src/stepwise/stepwise-agent-runner.js.map +0 -1
  136. package/dist/src/stepwise/stepwise-agent-session-flow.d.ts +0 -35
  137. package/dist/src/stepwise/stepwise-agent-session-flow.js.map +0 -1
  138. package/dist/src/stepwise/stepwise-input-items.js.map +0 -1
  139. package/dist/src/stepwise/tool-source.js.map +0 -1
  140. /package/dist/src/{stepwise → builtin-loop}/agent-definition.js +0 -0
  141. /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.d.ts +0 -0
  142. /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.js +0 -0
  143. /package/dist/src/{stepwise → builtin-loop}/model-client.js +0 -0
  144. /package/dist/src/{stepwise → builtin-loop}/tool-source.js +0 -0
@@ -0,0 +1,417 @@
1
+ // Copyright (c) 2026 Super Durable, Inc.
2
+ //
3
+ // Licensed under the Sustainable Use License 1.0.
4
+ // You may not use this file except in compliance with the License.
5
+ // See the LICENSE file in the repository root.
6
+ //
7
+ // SPDX-License-Identifier: LicenseRef-Sustainable-Use-1.0
8
+ import { randomBytes } from "node:crypto";
9
+ import { constants } from "node:fs";
10
+ import { lstat, mkdir, open, realpath, rename, stat, unlink } from "node:fs/promises";
11
+ import { posix } from "node:path";
12
+ import { setTimeout as delay } from "node:timers/promises";
13
+ import { MediaStoreError, buildImageReference, requireShortImageUris, requireStoreImageReference, verifyImageBytes, } from "./agent-media.js";
14
+ const imageDirectoryName = "sha256";
15
+ const directoryMode = 0o700;
16
+ const fileMode = 0o600;
17
+ // Errors of an O_NOFOLLOW | O_NONBLOCK open that name a symbolic link or a non-regular file.
18
+ const notRegularFileErrorCodes = new Set(["ELOOP", "EISDIR", "ENXIO", "EOPNOTSUPP"]);
19
+ // Opens to try, and milliseconds between them, while concurrent putImage calls replace the file.
20
+ const openAttempts = 10;
21
+ const openRetryDelayMs = 5;
22
+ /**
23
+ * Keeps image bytes in a local directory, one file per distinct image.
24
+ *
25
+ * Use it when every client and Worker of a session runs on one machine, such as a command-line tool in local mode;
26
+ * use `S3MediaStore` from `@superdurable/dex-agents/s3` when they run on different machines.
27
+ *
28
+ * The file of an image is `<root>/sha256/<sha256>`, and a reference's `uri` is `file://<root>/sha256/<sha256>`, where
29
+ * `<root>` is the absolute root with every UTF-8 byte other than ASCII letters, digits, `-`, `.`, `_`, `~`, and `/`
30
+ * written as `%XX` in uppercase hex. The root is made absolute as text: `.` and `..` segments and repeated or trailing
31
+ * `/` characters are resolved without reading the file system, symbolic links are not resolved, and Unicode is not
32
+ * normalized. A client and a Worker that pass the same root therefore build the same references, in every core.
33
+ *
34
+ * `putImage` copies the bytes into a temporary file in the same directory, syncs it, and renames it into place, so a
35
+ * reader never sees a partial image. An existing file with the same bytes is success, so retried and concurrent uploads
36
+ * of the same bytes leave one file; an existing file with other bytes is replaced. Directories the store creates get
37
+ * mode `0700` and image files mode `0600`, narrowed further by the process umask. When `putImage` writes the image, it
38
+ * syncs the file before the rename. Before every `putImage` returns, including when an identical file already exists
39
+ * and nothing is written, it syncs the `sha256` directory, the root, and the root's parent. It also syncs the parent of
40
+ * each directory it creates. Directories above the root's parent must already be durable: a concurrent creator of a
41
+ * deeper missing ancestor is out of scope.
42
+ *
43
+ * The store refuses a `sha256` directory or an image file that is a symbolic link or not a regular file, and an image
44
+ * file with more than one hard link, with `MediaStoreError`, on both upload and read. The root itself may be a symbolic
45
+ * link. Node.js has no `openat`, so this store opens files by path and checks before and after each operation: it
46
+ * checks the `sha256` directory with `lstat` and opens the file with `O_NOFOLLOW`, then confirms that the real path of
47
+ * the `sha256` directory is still the root's and that the path still names the opened or written file. A read that
48
+ * fails the check returns nothing, and a write that fails it removes the file it wrote when it can still find it. A
49
+ * process of the same user that can write the `0700` root can still race a directory swap between these checks; the
50
+ * Python core opens every path relative to an open directory and has no such window. `getImage` reads only
51
+ * references under this store's root, refuses a file whose size differs from the reference before reading it, reads at
52
+ * most one byte more than `sizeBytes`, and checks the bytes with `verifyImageBytes`. It needs a POSIX file system; on
53
+ * Windows the constructor throws.
54
+ *
55
+ * Session deletion does not delete files. A runner reads a session's images again whenever a model call replays them,
56
+ * so keep every file at least as long as any session that references it can still run a turn or replay its history. A
57
+ * missing file makes those turns fail with `MediaStoreError`.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * import { LocalDirectoryMediaStore } from "@superdurable/dex-agents";
62
+ *
63
+ * const store = new LocalDirectoryMediaStore("/var/lib/my-agent/media");
64
+ * const reference = await store.putImage(screenshotPng);
65
+ * // reference.uri === "file:///var/lib/my-agent/media/sha256/9f2c..."
66
+ * ```
67
+ * @since 0.5.0
68
+ */
69
+ export class LocalDirectoryMediaStore {
70
+ /** The absolute root directory, made absolute as text, without a trailing `/`. */
71
+ root;
72
+ /** The location that every reference of this store starts with: `"file://<root>"`, with the root percent-encoded. */
73
+ storeUri;
74
+ /**
75
+ * Creates a store; it touches no file until the first upload or read.
76
+ *
77
+ * @param root - Absolute path of the directory that holds the images, such as `"/var/lib/my-agent/media"`. The first
78
+ * upload creates it and any missing parent directory with mode `0700`.
79
+ * @throws {TypeError} When `root` is not absolute, is not well-formed Unicode, contains NUL, or is the file system
80
+ * root.
81
+ * @throws {RangeError} When `root` makes image URIs longer than `maxImageUriLength`.
82
+ * @throws {Error} On a system without POSIX file access, such as Windows.
83
+ */
84
+ constructor(root) {
85
+ if (process.platform === "win32" || constants.O_NOFOLLOW === undefined) {
86
+ throw new Error("LocalDirectoryMediaStore needs a POSIX file system");
87
+ }
88
+ this.root = absoluteRoot(root);
89
+ this.storeUri = `file://${percentEncodePath(this.root)}`;
90
+ requireShortImageUris(this.storeUri);
91
+ }
92
+ /**
93
+ * Returns the path of the file of the image with this SHA-256.
94
+ *
95
+ * @param sha256 - SHA-256 of the bytes as 64 lowercase hex digits.
96
+ * @returns `"<root>/sha256/<sha256>"`.
97
+ */
98
+ imagePath(sha256) {
99
+ return `${this.imageDirectory()}/${sha256}`;
100
+ }
101
+ /**
102
+ * Stores one image unless the directory already has it, and returns its reference.
103
+ *
104
+ * @param data - PNG, JPEG, GIF, or WebP bytes, at most `maxImageBytes`.
105
+ * @returns The reference.
106
+ * @throws {ImageValidationError} When the bytes are not a valid image for `buildImageReference`. Nothing is written.
107
+ * @throws {MediaStoreError} When the `sha256` directory or the image's file is a symbolic link or not a directory or
108
+ * regular file, the image's file has more than one hard link, or the `sha256` directory changed during the write.
109
+ * @throws A Node.js system error (`NodeJS.ErrnoException`) when the file system refuses a write, such as for missing
110
+ * permissions or a full disk. Retrying is safe.
111
+ */
112
+ async putImage(data) {
113
+ const reference = buildImageReference(data, this.storeUri);
114
+ const copy = Uint8Array.from(data);
115
+ await this.makeRoot();
116
+ try {
117
+ await this.requireImageDirectory();
118
+ }
119
+ catch (error) {
120
+ if (!isSystemError(error, "ENOENT")) {
121
+ throw error;
122
+ }
123
+ await makeDirectory(this.imageDirectory());
124
+ await this.requireImageDirectory();
125
+ }
126
+ if (!(await this.hasImageFile(reference, copy))) {
127
+ await this.replaceImageFile(reference, copy);
128
+ }
129
+ // Every put syncs its directory chain: a concurrent creator may not have yet.
130
+ await syncDirectory(this.imageDirectory());
131
+ await syncDirectory(this.root);
132
+ await syncDirectory(posix.dirname(this.root));
133
+ return reference;
134
+ }
135
+ /**
136
+ * Returns the bytes of one image in this store.
137
+ *
138
+ * @param reference - A reference under this store's root.
139
+ * @returns The exact bytes, checked with `verifyImageBytes`.
140
+ * @throws {ImageValidationError} When the reference's fields are invalid.
141
+ * @throws {MediaStoreError} When the reference is outside this store's root, the file is missing, is a symbolic link
142
+ * or not a regular file, has more than one hard link, moved during the read, or its bytes do not match.
143
+ * @throws A Node.js system error (`NodeJS.ErrnoException`) when the file system refuses the read for another reason.
144
+ */
145
+ async getImage(reference) {
146
+ requireStoreImageReference(reference, this.storeUri);
147
+ const missing = (cause) => new MediaStoreError(`image ${reference.uri} is not in the media store`, { cause });
148
+ const mismatch = () => new MediaStoreError(`image ${reference.uri} does not match its sha256 and size`);
149
+ let handle;
150
+ try {
151
+ await this.requireImageDirectory();
152
+ handle = await this.openImageFile(reference);
153
+ }
154
+ catch (error) {
155
+ throw isSystemError(error, "ENOENT") ? missing(error) : error;
156
+ }
157
+ let data;
158
+ try {
159
+ if ((await handle.stat()).size !== reference.sizeBytes) {
160
+ throw mismatch();
161
+ }
162
+ // One byte more than expected tells a file that grew apart without reading all of it.
163
+ data = await readAtMost(handle, reference.sizeBytes + 1);
164
+ }
165
+ finally {
166
+ await handle.close();
167
+ }
168
+ if (data.length !== reference.sizeBytes) {
169
+ throw mismatch();
170
+ }
171
+ return verifyImageBytes(reference, data);
172
+ }
173
+ imageDirectory() {
174
+ return `${this.root}/${imageDirectoryName}`;
175
+ }
176
+ /** Creates the root and its missing parents with mode `0700`, syncing the parent of each. */
177
+ async makeRoot() {
178
+ const missing = [];
179
+ let path = this.root;
180
+ while (!(await isDirectory(path))) {
181
+ missing.push(path);
182
+ path = posix.dirname(path);
183
+ }
184
+ for (const directory of missing.reverse()) {
185
+ await makeDirectory(directory);
186
+ await syncDirectory(posix.dirname(directory));
187
+ }
188
+ }
189
+ /** Throws `MediaStoreError` unless the `sha256` directory is a real directory, not a symbolic link. */
190
+ async requireImageDirectory() {
191
+ const stats = await lstat(this.imageDirectory());
192
+ if (!stats.isDirectory()) {
193
+ throw new MediaStoreError(`media store directory ${this.imageDirectory()} is a symbolic link or not a directory`);
194
+ }
195
+ }
196
+ /** Returns whether the image's file exists and holds exactly `data`. */
197
+ async hasImageFile(reference, data) {
198
+ let handle;
199
+ try {
200
+ handle = await this.openImageFile(reference);
201
+ }
202
+ catch (error) {
203
+ if (isSystemError(error, "ENOENT")) {
204
+ return false;
205
+ }
206
+ throw error;
207
+ }
208
+ try {
209
+ if ((await handle.stat()).size !== data.length) {
210
+ return false;
211
+ }
212
+ return Buffer.from(await readAtMost(handle, data.length + 1)).equals(data);
213
+ }
214
+ finally {
215
+ await handle.close();
216
+ }
217
+ }
218
+ /** Opens the reference's image file, refusing symbolic links, special files, hard links, and moved files. */
219
+ async openImageFile(reference) {
220
+ for (let attempt = 0; attempt < openAttempts; attempt += 1) {
221
+ const handle = await this.openImageFileOnce(reference);
222
+ if (handle !== undefined) {
223
+ return handle;
224
+ }
225
+ await delay(openRetryDelayMs * (attempt + 1));
226
+ }
227
+ throw new MediaStoreError(`image ${reference.uri} was replaced while the media store opened it`);
228
+ }
229
+ /** Returns the open file, or `undefined` when a rename replaced it after the open. */
230
+ async openImageFileOnce(reference) {
231
+ const notRegularFile = (cause) => new MediaStoreError(`image ${reference.uri} is a symbolic link or not a regular file in the media store`, {
232
+ cause,
233
+ });
234
+ let handle;
235
+ try {
236
+ // O_NONBLOCK keeps a planted FIFO from blocking the open.
237
+ handle = await open(this.imagePath(reference.sha256), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
238
+ }
239
+ catch (error) {
240
+ if (isSystemError(error, ...notRegularFileErrorCodes)) {
241
+ throw notRegularFile(error);
242
+ }
243
+ throw error;
244
+ }
245
+ const stats = await handle.stat();
246
+ if (!stats.isFile()) {
247
+ await handle.close();
248
+ throw notRegularFile();
249
+ }
250
+ if (stats.nlink === 0) {
251
+ await handle.close();
252
+ return undefined;
253
+ }
254
+ if (stats.nlink !== 1) {
255
+ await handle.close();
256
+ // Another name for the inode may lie outside the root.
257
+ throw new MediaStoreError(`image ${reference.uri} has more than one hard link in the media store`);
258
+ }
259
+ if (!(await this.isImageDirectoryInStore())) {
260
+ await handle.close();
261
+ throw this.directoryChanged(reference);
262
+ }
263
+ if (!(await isSameFile(this.imagePath(reference.sha256), stats))) {
264
+ // A concurrent rename replaced the file after the open; the caller opens it again.
265
+ await handle.close();
266
+ return undefined;
267
+ }
268
+ return handle;
269
+ }
270
+ /** Returns whether the `sha256` directory is a real directory whose real path is the root's. */
271
+ async isImageDirectoryInStore() {
272
+ try {
273
+ if (!(await lstat(this.imageDirectory())).isDirectory()) {
274
+ return false;
275
+ }
276
+ const expectedDirectory = posix.join(await realpath(this.root), imageDirectoryName);
277
+ return (await realpath(this.imageDirectory())) === expectedDirectory;
278
+ }
279
+ catch (error) {
280
+ if (isSystemError(error, "ENOENT", "ENOTDIR", "ELOOP")) {
281
+ return false;
282
+ }
283
+ throw error;
284
+ }
285
+ }
286
+ directoryChanged(reference) {
287
+ return new MediaStoreError(`media store directory ${this.imageDirectory()} changed while image ${reference.uri} was read or written`);
288
+ }
289
+ async replaceImageFile(reference, data) {
290
+ const directory = this.imageDirectory();
291
+ const imagePath = this.imagePath(reference.sha256);
292
+ const temporaryPath = `${directory}/.${reference.sha256}.${randomBytes(8).toString("hex")}.tmp`;
293
+ const handle = await open(temporaryPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, fileMode);
294
+ let written;
295
+ try {
296
+ try {
297
+ await handle.writeFile(data);
298
+ await handle.sync();
299
+ written = await handle.stat();
300
+ }
301
+ finally {
302
+ await handle.close();
303
+ }
304
+ // rename replaces the entry itself, never a link's target, and is atomic.
305
+ await rename(temporaryPath, imagePath);
306
+ }
307
+ catch (error) {
308
+ // The original error matters more than a temporary file left behind.
309
+ await unlink(temporaryPath).catch(() => undefined);
310
+ throw error;
311
+ }
312
+ if (!(await this.isImageDirectoryInStore())) {
313
+ await removeIfSameFile(imagePath, written);
314
+ throw this.directoryChanged(reference);
315
+ }
316
+ // A concurrent putImage may have renamed its own copy over ours; accept it only when it holds these bytes.
317
+ if (!(await isSameFile(imagePath, written)) && !(await this.hasImageFile(reference, data))) {
318
+ throw this.directoryChanged(reference);
319
+ }
320
+ }
321
+ }
322
+ async function isSameFile(path, file) {
323
+ try {
324
+ const placed = await lstat(path);
325
+ return placed.dev === file.dev && placed.ino === file.ino;
326
+ }
327
+ catch (error) {
328
+ if (isSystemError(error, "ENOENT", "ENOTDIR", "ELOOP")) {
329
+ return false;
330
+ }
331
+ throw error;
332
+ }
333
+ }
334
+ async function isDirectory(path) {
335
+ try {
336
+ return (await stat(path)).isDirectory();
337
+ }
338
+ catch {
339
+ // Any failure means "create it"; mkdir then reports the real error.
340
+ return false;
341
+ }
342
+ }
343
+ async function makeDirectory(path) {
344
+ try {
345
+ await mkdir(path, { mode: directoryMode });
346
+ }
347
+ catch (error) {
348
+ if (!isSystemError(error, "EEXIST")) {
349
+ throw error;
350
+ }
351
+ }
352
+ }
353
+ async function syncDirectory(path) {
354
+ const handle = await open(path, constants.O_RDONLY);
355
+ try {
356
+ await handle.sync();
357
+ }
358
+ finally {
359
+ await handle.close();
360
+ }
361
+ }
362
+ /** Removes the file at `path` when it is still `file`, wherever the path now leads. */
363
+ async function removeIfSameFile(path, file) {
364
+ try {
365
+ const placed = await lstat(path);
366
+ if (placed.dev === file.dev && placed.ino === file.ino) {
367
+ await unlink(path);
368
+ }
369
+ }
370
+ catch {
371
+ // Best effort: the caller already throws, and the file may be gone.
372
+ }
373
+ }
374
+ function absoluteRoot(root) {
375
+ if (!root.startsWith("/")) {
376
+ throw new TypeError("LocalDirectoryMediaStore root must be an absolute path");
377
+ }
378
+ // In a u-mode pattern, only a lone surrogate matches this range.
379
+ if (/[\uD800-\uDFFF]/u.test(root)) {
380
+ throw new TypeError("LocalDirectoryMediaStore root must be well-formed Unicode");
381
+ }
382
+ if (root.includes("\0")) {
383
+ throw new TypeError("LocalDirectoryMediaStore root must not contain NUL");
384
+ }
385
+ const absolute = posix.resolve(root);
386
+ if (absolute === "/") {
387
+ throw new TypeError("LocalDirectoryMediaStore root must not be the file system root");
388
+ }
389
+ return absolute;
390
+ }
391
+ /** Writes every UTF-8 byte other than ASCII letters, digits, `-._~` and `/` as `%XX`, as Python's `quote` does. */
392
+ function percentEncodePath(path) {
393
+ let encoded = "";
394
+ for (const byte of Buffer.from(path, "utf8")) {
395
+ const character = String.fromCharCode(byte);
396
+ encoded += /^[A-Za-z0-9\-._~\/]$/.test(character)
397
+ ? character
398
+ : `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
399
+ }
400
+ return encoded;
401
+ }
402
+ async function readAtMost(handle, limit) {
403
+ const buffer = Buffer.alloc(limit);
404
+ let total = 0;
405
+ while (total < limit) {
406
+ const { bytesRead } = await handle.read(buffer, total, limit - total, null);
407
+ if (bytesRead === 0) {
408
+ break;
409
+ }
410
+ total += bytesRead;
411
+ }
412
+ return new Uint8Array(buffer.buffer, buffer.byteOffset, total);
413
+ }
414
+ function isSystemError(error, ...codes) {
415
+ return error instanceof Error && codes.includes(error.code ?? "");
416
+ }
417
+ //# sourceMappingURL=agent-local-directory-media-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-local-directory-media-store.js","sourceRoot":"","sources":["../../src/agent-local-directory-media-store.ts"],"names":[],"mappings":"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"}