@superdurable/dex-agents 0.3.0 → 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 +598 -45
- package/dist/src/agent-context-compaction.d.ts +1 -1
- package/dist/src/agent-framework-runner.d.ts +210 -10
- package/dist/src/agent-framework-runner.js +30 -0
- package/dist/src/agent-framework-runner.js.map +1 -1
- package/dist/src/agent-local-directory-media-store.d.ts +111 -0
- package/dist/src/agent-local-directory-media-store.js +417 -0
- package/dist/src/agent-local-directory-media-store.js.map +1 -0
- package/dist/src/agent-media.d.ts +279 -0
- package/dist/src/agent-media.js +457 -0
- package/dist/src/agent-media.js.map +1 -0
- package/dist/src/agent-session-codecs.d.ts +3 -1
- package/dist/src/agent-session-codecs.js +53 -4
- package/dist/src/agent-session-codecs.js.map +1 -1
- package/dist/src/agent-session-failure.d.ts +4 -2
- package/dist/src/agent-session-failure.js +6 -2
- package/dist/src/agent-session-failure.js.map +1 -1
- package/dist/src/agent-session-flow-graph.d.ts +46 -0
- package/dist/src/agent-session-flow-graph.js +51 -0
- package/dist/src/agent-session-flow-graph.js.map +1 -1
- package/dist/src/agent-session-flow-graph.json +98 -81
- package/dist/src/agent-session-flow.d.ts +5 -3
- package/dist/src/agent-session-flow.js +10 -1
- package/dist/src/agent-session-flow.js.map +1 -1
- package/dist/src/agent-session-start.d.ts +1 -1
- package/dist/src/agent-session-start.js +2 -2
- package/dist/src/agent-session-start.js.map +1 -1
- package/dist/src/agent-session-steps.d.ts +9 -0
- package/dist/src/agent-session-steps.js +219 -34
- package/dist/src/agent-session-steps.js.map +1 -1
- package/dist/src/agent-session-tracer.js +1 -1
- package/dist/src/agent-session-tracer.js.map +1 -1
- package/dist/src/agent-session-transitions.d.ts +4 -0
- package/dist/src/agent-session-transitions.js +29 -1
- package/dist/src/agent-session-transitions.js.map +1 -1
- package/dist/src/agent-session-values.d.ts +112 -1
- package/dist/src/agent-session-values.js +6 -0
- package/dist/src/agent-session-values.js.map +1 -1
- package/dist/src/agent-session-wait-steps.js +17 -5
- package/dist/src/agent-session-wait-steps.js.map +1 -1
- package/dist/src/ai-sdk/ai-sdk-model-client.d.ts +15 -3
- package/dist/src/ai-sdk/ai-sdk-model-client.js +36 -7
- package/dist/src/ai-sdk/ai-sdk-model-client.js.map +1 -1
- package/dist/src/ai-sdk/index.d.ts +1 -1
- package/dist/src/ai-sdk/index.js +1 -1
- package/dist/src/ai-sdk/index.js.map +1 -1
- package/dist/src/{stepwise → builtin-loop}/agent-definition.d.ts +120 -5
- package/dist/src/builtin-loop/agent-definition.js.map +1 -0
- package/dist/src/builtin-loop/builtin-agent-session-flow.d.ts +69 -0
- package/dist/src/{stepwise/stepwise-agent-session-flow.js → builtin-loop/builtin-agent-session-flow.js} +15 -9
- package/dist/src/builtin-loop/builtin-agent-session-flow.js.map +1 -0
- package/dist/src/{stepwise/stepwise-agent-runner.d.ts → builtin-loop/builtin-loop-agent-runner.d.ts} +85 -26
- package/dist/src/{stepwise/stepwise-agent-runner.js → builtin-loop/builtin-loop-agent-runner.js} +320 -213
- package/dist/src/builtin-loop/builtin-loop-agent-runner.js.map +1 -0
- package/dist/src/{stepwise/stepwise-input-items.d.ts → builtin-loop/builtin-loop-input-items.d.ts} +7 -3
- package/dist/src/{stepwise/stepwise-input-items.js → builtin-loop/builtin-loop-input-items.js} +57 -10
- package/dist/src/builtin-loop/builtin-loop-input-items.js.map +1 -0
- package/dist/src/builtin-loop/function-tool.d.ts +282 -0
- package/dist/src/{stepwise → builtin-loop}/function-tool.js +63 -3
- package/dist/src/builtin-loop/function-tool.js.map +1 -0
- package/dist/src/builtin-loop/index.d.ts +8 -0
- package/dist/src/builtin-loop/index.js +13 -0
- package/dist/src/builtin-loop/index.js.map +1 -0
- package/dist/src/builtin-loop/json-schema-validation.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/model-client.d.ts +36 -7
- package/dist/src/builtin-loop/model-client.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/scripted-model-client.d.ts +8 -5
- package/dist/src/{stepwise → builtin-loop}/scripted-model-client.js +8 -5
- package/dist/src/builtin-loop/scripted-model-client.js.map +1 -0
- package/dist/src/{stepwise → builtin-loop}/tool-source.d.ts +13 -3
- package/dist/src/builtin-loop/tool-source.js.map +1 -0
- package/dist/src/connectors/connector-input-schema.d.ts +19 -0
- package/dist/src/connectors/connector-input-schema.js +228 -0
- package/dist/src/connectors/connector-input-schema.js.map +1 -0
- package/dist/src/connectors/connector-step-context.d.ts +94 -0
- package/dist/src/connectors/connector-step-context.js +180 -0
- package/dist/src/connectors/connector-step-context.js.map +1 -0
- package/dist/src/connectors/connector-tool-source.d.ts +401 -0
- package/dist/src/connectors/connector-tool-source.js +628 -0
- package/dist/src/connectors/connector-tool-source.js.map +1 -0
- package/dist/src/connectors/index.d.ts +3 -0
- package/dist/src/connectors/index.js +11 -0
- package/dist/src/connectors/index.js.map +1 -0
- package/dist/src/index.d.ts +7 -3
- package/dist/src/index.js +6 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/index.d.ts +1 -0
- package/dist/src/mcp/index.js +1 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/mcp/mcp-dex-conventions.d.ts +57 -0
- package/dist/src/mcp/mcp-dex-conventions.js +90 -0
- package/dist/src/mcp/mcp-dex-conventions.js.map +1 -0
- package/dist/src/mcp/mcp-image-content.d.ts +20 -0
- package/dist/src/mcp/mcp-image-content.js +82 -0
- package/dist/src/mcp/mcp-image-content.js.map +1 -0
- package/dist/src/mcp/mcp-tool-source.d.ts +178 -17
- package/dist/src/mcp/mcp-tool-source.js +237 -34
- package/dist/src/mcp/mcp-tool-source.js.map +1 -1
- package/dist/src/s3/index.d.ts +1 -0
- package/dist/src/s3/index.js +9 -0
- package/dist/src/s3/index.js.map +1 -0
- package/dist/src/s3/s3-media-store.d.ts +138 -0
- package/dist/src/s3/s3-media-store.js +255 -0
- package/dist/src/s3/s3-media-store.js.map +1 -0
- package/dist/src/stepwise/index.d.ts +41 -8
- package/dist/src/stepwise/index.js +35 -5
- package/dist/src/stepwise/index.js.map +1 -1
- package/dist/src/testing/agent-session-test-client.d.ts +6 -3
- package/dist/src/testing/agent-session-test-client.js +10 -3
- package/dist/src/testing/agent-session-test-client.js.map +1 -1
- package/dist/src/testing/scripted-model-client.d.ts +1 -1
- package/dist/src/testing/scripted-model-client.js +2 -2
- package/dist/src/testing/scripted-model-client.js.map +1 -1
- package/dist/src/tool-source-router.d.ts +211 -0
- package/dist/src/tool-source-router.js +380 -0
- package/dist/src/tool-source-router.js.map +1 -0
- package/dist/src/ui-stream/agent-event-json.d.ts +2 -1
- package/dist/src/ui-stream/agent-event-json.js +3 -1
- package/dist/src/ui-stream/agent-event-json.js.map +1 -1
- package/dist/src/ui-stream/agent-ui-messages.d.ts +11 -3
- package/dist/src/ui-stream/agent-ui-messages.js +29 -5
- package/dist/src/ui-stream/agent-ui-messages.js.map +1 -1
- package/package.json +25 -3
- package/dist/src/stepwise/agent-definition.js.map +0 -1
- package/dist/src/stepwise/function-tool.d.ts +0 -130
- package/dist/src/stepwise/function-tool.js.map +0 -1
- package/dist/src/stepwise/json-schema-validation.js.map +0 -1
- package/dist/src/stepwise/model-client.js.map +0 -1
- package/dist/src/stepwise/scripted-model-client.js.map +0 -1
- package/dist/src/stepwise/stepwise-agent-runner.js.map +0 -1
- package/dist/src/stepwise/stepwise-agent-session-flow.d.ts +0 -35
- package/dist/src/stepwise/stepwise-agent-session-flow.js.map +0 -1
- package/dist/src/stepwise/stepwise-input-items.js.map +0 -1
- package/dist/src/stepwise/tool-source.js.map +0 -1
- /package/dist/src/{stepwise → builtin-loop}/agent-definition.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.d.ts +0 -0
- /package/dist/src/{stepwise → builtin-loop}/json-schema-validation.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/model-client.js +0 -0
- /package/dist/src/{stepwise → builtin-loop}/tool-source.js +0 -0
|
@@ -0,0 +1,457 @@
|
|
|
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 { createHash } from "node:crypto";
|
|
9
|
+
/**
|
|
10
|
+
* Largest image a media store accepts, in bytes. Its base64 text is 5,000,000 bytes, which fits the per-image limits
|
|
11
|
+
* of Amazon Bedrock (5 MB of base64) and the Claude API (10 MB of base64).
|
|
12
|
+
* @since 0.5.0
|
|
13
|
+
*/
|
|
14
|
+
export const maxImageBytes = 3_750_000;
|
|
15
|
+
/**
|
|
16
|
+
* Most images one user message or one tool result may carry.
|
|
17
|
+
* @since 0.5.0
|
|
18
|
+
*/
|
|
19
|
+
export const maxImagesPerMessage = 20;
|
|
20
|
+
/**
|
|
21
|
+
* Image types a media store accepts, detected from the bytes.
|
|
22
|
+
* @since 0.5.0
|
|
23
|
+
*/
|
|
24
|
+
export const supportedImageMimeTypes = ["image/png", "image/jpeg", "image/gif", "image/webp"];
|
|
25
|
+
/**
|
|
26
|
+
* Longest {@link AgentImageReference.uri} in bytes as UTF-8, the same unit in every core; S3 object keys are at most
|
|
27
|
+
* 1024 bytes.
|
|
28
|
+
* @since 0.5.0
|
|
29
|
+
*/
|
|
30
|
+
export const maxImageUriLength = 1024;
|
|
31
|
+
const sha256Pattern = /^[0-9a-f]{64}$/;
|
|
32
|
+
const imageUriPattern = /^[a-z][a-z0-9+.-]*:\/\/\S+\/sha256\/[0-9a-f]{64}$/;
|
|
33
|
+
const pngSignature = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];
|
|
34
|
+
const pngHeaderChunk = [0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52];
|
|
35
|
+
const webpChunkTypes = ["VP8 ", "VP8L", "VP8X"];
|
|
36
|
+
const formatNames = {
|
|
37
|
+
"image/png": "PNG",
|
|
38
|
+
"image/jpeg": "JPEG",
|
|
39
|
+
"image/gif": "GIF",
|
|
40
|
+
"image/webp": "WebP",
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Image bytes or an image reference that Dex agents refuse.
|
|
44
|
+
*
|
|
45
|
+
* `putImage` throws it for bytes that are empty, larger than {@link maxImageBytes}, or not PNG, JPEG, GIF, or WebP.
|
|
46
|
+
* {@link validateImageReference} and {@link validateImageReferences} throw it for a reference whose fields are
|
|
47
|
+
* invalid. The message says what is wrong.
|
|
48
|
+
* @since 0.5.0
|
|
49
|
+
*/
|
|
50
|
+
export class ImageValidationError extends Error {
|
|
51
|
+
/**
|
|
52
|
+
* @param message - What is wrong with the image or reference.
|
|
53
|
+
*/
|
|
54
|
+
constructor(message) {
|
|
55
|
+
super(message);
|
|
56
|
+
this.name = "ImageValidationError";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A media store cannot return the bytes of a valid reference.
|
|
61
|
+
*
|
|
62
|
+
* `getImage` throws it when the reference belongs to another store, when the store has no object for it, or when the
|
|
63
|
+
* stored bytes do not match the reference's SHA-256, size, and type.
|
|
64
|
+
* @since 0.5.0
|
|
65
|
+
*/
|
|
66
|
+
export class MediaStoreError extends Error {
|
|
67
|
+
/**
|
|
68
|
+
* @param message - Which image could not be read, and why.
|
|
69
|
+
* @param options - Standard error options, such as the `cause` from the storage service.
|
|
70
|
+
*/
|
|
71
|
+
constructor(message, options) {
|
|
72
|
+
super(message, options);
|
|
73
|
+
this.name = "MediaStoreError";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Keeps images in this process, for tests and single-process tools.
|
|
78
|
+
*
|
|
79
|
+
* References use the `memory://<name>` location. Two stores with the same name accept each other's references, but
|
|
80
|
+
* each holds only what was put into it, so a Worker in another process cannot read them.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const store = new InMemoryMediaStore();
|
|
85
|
+
* const reference = await store.putImage(pngBytes);
|
|
86
|
+
* assert.deepEqual(await store.getImage(reference), pngBytes);
|
|
87
|
+
* ```
|
|
88
|
+
* @since 0.5.0
|
|
89
|
+
*/
|
|
90
|
+
export class InMemoryMediaStore {
|
|
91
|
+
/** The location that every reference of this store starts with: `"memory://<name>"`. */
|
|
92
|
+
storeUri;
|
|
93
|
+
images = new Map();
|
|
94
|
+
/**
|
|
95
|
+
* Creates an empty store.
|
|
96
|
+
*
|
|
97
|
+
* @param name - The location name in `memory://<name>`, `"default"` when omitted. It must be non-empty and contain
|
|
98
|
+
* no `/` or whitespace.
|
|
99
|
+
* @throws {TypeError} When `name` is empty or contains `/` or whitespace.
|
|
100
|
+
* @throws {RangeError} When `name` makes image URIs longer than {@link maxImageUriLength}.
|
|
101
|
+
*/
|
|
102
|
+
constructor(name = "default") {
|
|
103
|
+
if (name === "" || name.includes("/") || /\s/.test(name)) {
|
|
104
|
+
throw new TypeError("InMemoryMediaStore name must be non-empty, without / or whitespace");
|
|
105
|
+
}
|
|
106
|
+
this.storeUri = `memory://${name}`;
|
|
107
|
+
requireShortImageUris(this.storeUri);
|
|
108
|
+
}
|
|
109
|
+
/** How many distinct images the store holds; uploading the same bytes twice counts once. */
|
|
110
|
+
get imageCount() {
|
|
111
|
+
return this.images.size;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Stores one image and returns its reference. See {@link MediaStore.putImage}.
|
|
115
|
+
*
|
|
116
|
+
* @param data - PNG, JPEG, GIF, or WebP bytes, at most {@link maxImageBytes}.
|
|
117
|
+
* @returns The reference.
|
|
118
|
+
* @throws {ImageValidationError} When the bytes are empty, too large, or of another type.
|
|
119
|
+
*/
|
|
120
|
+
async putImage(data) {
|
|
121
|
+
const reference = buildImageReference(data, this.storeUri);
|
|
122
|
+
if (!this.images.has(reference.sha256)) {
|
|
123
|
+
this.images.set(reference.sha256, Uint8Array.from(data));
|
|
124
|
+
}
|
|
125
|
+
return reference;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Returns the bytes of one image. See {@link MediaStore.getImage}.
|
|
129
|
+
*
|
|
130
|
+
* @param reference - A reference that this store's `putImage` returned.
|
|
131
|
+
* @returns A copy of the exact bytes; changing it leaves the stored image as it was.
|
|
132
|
+
* @throws {ImageValidationError} When the reference's fields are invalid.
|
|
133
|
+
* @throws {MediaStoreError} When the reference belongs to another store, the store does not hold the image, or its
|
|
134
|
+
* bytes do not match.
|
|
135
|
+
*/
|
|
136
|
+
async getImage(reference) {
|
|
137
|
+
requireStoreImageReference(reference, this.storeUri);
|
|
138
|
+
const data = this.images.get(reference.sha256);
|
|
139
|
+
if (data === undefined) {
|
|
140
|
+
throw new MediaStoreError(`image ${reference.uri} is not in the media store`);
|
|
141
|
+
}
|
|
142
|
+
return verifyImageBytes(reference, Uint8Array.from(data));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns the MIME type of image bytes, read from their structure.
|
|
147
|
+
*
|
|
148
|
+
* The signature picks the type, then a cheap structural check must hold; it does not decode the image. PNG needs its
|
|
149
|
+
* signature followed by the `IHDR` chunk. JPEG needs SOI, a marker right after it, and EOI as the last two bytes. GIF
|
|
150
|
+
* needs a `GIF87a` or `GIF89a` header and the logical screen descriptor. WebP needs a RIFF size equal to the byte count
|
|
151
|
+
* minus 8 and a first chunk of `VP8 `, `VP8L`, or `VP8X`.
|
|
152
|
+
*
|
|
153
|
+
* @param data - Image bytes.
|
|
154
|
+
* @returns `"image/png"`, `"image/jpeg"`, `"image/gif"`, or `"image/webp"`.
|
|
155
|
+
* @throws {ImageValidationError} When the bytes are empty, start with no supported signature, or fail the structural
|
|
156
|
+
* check of their type.
|
|
157
|
+
* @since 0.5.0
|
|
158
|
+
*/
|
|
159
|
+
export function detectImageMimeType(data) {
|
|
160
|
+
if (data.length === 0) {
|
|
161
|
+
throw new ImageValidationError("image is empty");
|
|
162
|
+
}
|
|
163
|
+
const mimeType = signatureMimeType(data);
|
|
164
|
+
if (mimeType === undefined) {
|
|
165
|
+
throw new ImageValidationError("image is not PNG, JPEG, GIF, or WebP");
|
|
166
|
+
}
|
|
167
|
+
if (!isWellFormed(mimeType, data)) {
|
|
168
|
+
throw new ImageValidationError(`image is not a well-formed ${formatNames[mimeType]}`);
|
|
169
|
+
}
|
|
170
|
+
return mimeType;
|
|
171
|
+
}
|
|
172
|
+
function signatureMimeType(data) {
|
|
173
|
+
if (startsWithBytes(data, pngSignature)) {
|
|
174
|
+
return "image/png";
|
|
175
|
+
}
|
|
176
|
+
if (startsWithBytes(data, [0xff, 0xd8, 0xff])) {
|
|
177
|
+
return "image/jpeg";
|
|
178
|
+
}
|
|
179
|
+
if (startsWithText(data, 0, "GIF87a") || startsWithText(data, 0, "GIF89a")) {
|
|
180
|
+
return "image/gif";
|
|
181
|
+
}
|
|
182
|
+
if (startsWithText(data, 0, "RIFF") && startsWithText(data, 8, "WEBP")) {
|
|
183
|
+
return "image/webp";
|
|
184
|
+
}
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
function isWellFormed(mimeType, data) {
|
|
188
|
+
switch (mimeType) {
|
|
189
|
+
case "image/png":
|
|
190
|
+
return data.length >= 33 && startsWithBytes(data.subarray(8), pngHeaderChunk);
|
|
191
|
+
case "image/jpeg": {
|
|
192
|
+
const marker = data[3] ?? 0;
|
|
193
|
+
return data.length >= 6 && marker >= 0xc0 && marker <= 0xfe && data.at(-2) === 0xff && data.at(-1) === 0xd9;
|
|
194
|
+
}
|
|
195
|
+
case "image/gif":
|
|
196
|
+
return data.length >= 13;
|
|
197
|
+
default: {
|
|
198
|
+
if (data.length < 20) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
const riffSize = new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(4, true);
|
|
202
|
+
const chunkType = String.fromCharCode(...data.subarray(12, 16));
|
|
203
|
+
return riffSize + 8 === data.length && webpChunkTypes.includes(chunkType);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Checks image bytes and returns the reference a store keeps them under.
|
|
209
|
+
*
|
|
210
|
+
* A {@link MediaStore} implementation calls it before it uploads: the reference names the object,
|
|
211
|
+
* `imageUri(storeUri, sha256)`.
|
|
212
|
+
*
|
|
213
|
+
* @param data - Image bytes.
|
|
214
|
+
* @param storeUri - The store's location, such as `"s3://media/agents"`.
|
|
215
|
+
* @returns The reference, with the detected MIME type, SHA-256, and size.
|
|
216
|
+
* @throws {ImageValidationError} When the bytes are empty, larger than {@link maxImageBytes}, or not a well-formed
|
|
217
|
+
* PNG, JPEG, GIF, or WebP, or when {@link validateImageReference} refuses the reference, such as for a URI longer than
|
|
218
|
+
* {@link maxImageUriLength}.
|
|
219
|
+
* @since 0.5.0
|
|
220
|
+
*/
|
|
221
|
+
export function buildImageReference(data, storeUri) {
|
|
222
|
+
if (data.length > maxImageBytes) {
|
|
223
|
+
throw new ImageValidationError(`image is ${data.length} bytes; the limit is ${maxImageBytes} bytes`);
|
|
224
|
+
}
|
|
225
|
+
const mimeType = detectImageMimeType(data);
|
|
226
|
+
const sha256 = createHash("sha256").update(data).digest("hex");
|
|
227
|
+
const reference = {
|
|
228
|
+
type: "image",
|
|
229
|
+
uri: imageUri(storeUri, sha256),
|
|
230
|
+
mimeType,
|
|
231
|
+
sha256,
|
|
232
|
+
sizeBytes: data.length,
|
|
233
|
+
};
|
|
234
|
+
validateImageReference(reference);
|
|
235
|
+
return reference;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Returns the URI of the image with this SHA-256 in a store.
|
|
239
|
+
*
|
|
240
|
+
* @param storeUri - The store's location; trailing `/` characters are dropped.
|
|
241
|
+
* @param sha256 - SHA-256 of the bytes as 64 lowercase hex digits.
|
|
242
|
+
* @returns `"<storeUri>/sha256/<sha256>"`.
|
|
243
|
+
* @since 0.5.0
|
|
244
|
+
*/
|
|
245
|
+
export function imageUri(storeUri, sha256) {
|
|
246
|
+
return `${storeUri.replace(/\/+$/, "")}/sha256/${sha256}`;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Checks that every image URI of a store fits {@link maxImageUriLength}.
|
|
250
|
+
*
|
|
251
|
+
* A {@link MediaStore} implementation calls it in its constructor, so a long location fails at once instead of on the
|
|
252
|
+
* first upload.
|
|
253
|
+
*
|
|
254
|
+
* @param storeUri - The store's location.
|
|
255
|
+
* @throws {RangeError} When `imageUri(storeUri, sha256)` is longer than {@link maxImageUriLength} bytes as UTF-8.
|
|
256
|
+
* @since 0.5.0
|
|
257
|
+
*/
|
|
258
|
+
export function requireShortImageUris(storeUri) {
|
|
259
|
+
if (Buffer.byteLength(imageUri(storeUri, "0".repeat(64)), "utf8") > maxImageUriLength) {
|
|
260
|
+
throw new RangeError(`media store location ${storeUri} makes image URIs longer than ${maxImageUriLength} bytes as UTF-8`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Checks the fields of one image reference.
|
|
265
|
+
*
|
|
266
|
+
* The checks run in order, and the first failure is thrown: `type` is `"image"`; `mimeType` is supported; `sha256` is
|
|
267
|
+
* 64 lowercase hex digits; `sizeBytes` is from 1 to {@link maxImageBytes}; `uri` is at most
|
|
268
|
+
* {@link maxImageUriLength} bytes as UTF-8, looks like `<scheme>://<location>/sha256/<sha256>`, and ends with the
|
|
269
|
+
* reference's own `sha256`. It does not read the store.
|
|
270
|
+
*
|
|
271
|
+
* @param reference - The reference, such as one decoded from a request.
|
|
272
|
+
* @throws {ImageValidationError} When a field is invalid.
|
|
273
|
+
* @since 0.5.0
|
|
274
|
+
*/
|
|
275
|
+
export function validateImageReference(reference) {
|
|
276
|
+
if (reference.type !== "image") {
|
|
277
|
+
throw new ImageValidationError('image reference type must be "image"');
|
|
278
|
+
}
|
|
279
|
+
if (!supportedImageMimeTypes.includes(reference.mimeType)) {
|
|
280
|
+
throw new ImageValidationError(`image reference mime_type must be one of ${supportedImageMimeTypes.join(", ")}`);
|
|
281
|
+
}
|
|
282
|
+
if (typeof reference.sha256 !== "string" || !sha256Pattern.test(reference.sha256)) {
|
|
283
|
+
throw new ImageValidationError("image reference sha256 must be 64 lowercase hex digits");
|
|
284
|
+
}
|
|
285
|
+
const size = reference.sizeBytes;
|
|
286
|
+
if (!Number.isSafeInteger(size) || size < 1 || size > maxImageBytes) {
|
|
287
|
+
throw new ImageValidationError(`image reference size_bytes must be from 1 to ${maxImageBytes}`);
|
|
288
|
+
}
|
|
289
|
+
const uri = reference.uri;
|
|
290
|
+
if (typeof uri !== "string" || Buffer.byteLength(uri, "utf8") > maxImageUriLength) {
|
|
291
|
+
throw new ImageValidationError(`image reference uri must be at most ${maxImageUriLength} bytes as UTF-8`);
|
|
292
|
+
}
|
|
293
|
+
if (!imageUriPattern.test(uri)) {
|
|
294
|
+
throw new ImageValidationError("image reference uri must look like <scheme>://<location>/sha256/<sha256>");
|
|
295
|
+
}
|
|
296
|
+
if (!uri.endsWith(`/${reference.sha256}`)) {
|
|
297
|
+
throw new ImageValidationError("image reference uri must end with its own sha256");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Checks the images of one user message or one tool result.
|
|
302
|
+
*
|
|
303
|
+
* @param references - The images, at most {@link maxImagesPerMessage}.
|
|
304
|
+
* @throws {ImageValidationError} When there are too many images, or with `"images[<index>]: "` before the reason
|
|
305
|
+
* when one is invalid.
|
|
306
|
+
* @since 0.5.0
|
|
307
|
+
*/
|
|
308
|
+
export function validateImageReferences(references) {
|
|
309
|
+
if (references.length > maxImagesPerMessage) {
|
|
310
|
+
throw new ImageValidationError(`a message may carry at most ${maxImagesPerMessage} images, got ${references.length}`);
|
|
311
|
+
}
|
|
312
|
+
references.forEach((reference, index) => {
|
|
313
|
+
try {
|
|
314
|
+
validateImageReference(reference);
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (error instanceof ImageValidationError) {
|
|
318
|
+
throw new ImageValidationError(`images[${index}]: ${error.message}`);
|
|
319
|
+
}
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Checks that a valid reference names an image of the store at `storeUri`.
|
|
326
|
+
*
|
|
327
|
+
* A {@link MediaStore} implementation calls it first in `getImage`, so a request cannot make the Worker read outside
|
|
328
|
+
* the store's location.
|
|
329
|
+
*
|
|
330
|
+
* @param reference - The reference to read.
|
|
331
|
+
* @param storeUri - The store's location.
|
|
332
|
+
* @throws {ImageValidationError} When the reference's fields are invalid.
|
|
333
|
+
* @throws {MediaStoreError} When its `uri` is not `imageUri(storeUri, sha256)`.
|
|
334
|
+
* @since 0.5.0
|
|
335
|
+
*/
|
|
336
|
+
export function requireStoreImageReference(reference, storeUri) {
|
|
337
|
+
validateImageReference(reference);
|
|
338
|
+
if (reference.uri !== imageUri(storeUri, reference.sha256)) {
|
|
339
|
+
throw new MediaStoreError(`image ${reference.uri} is not in the media store ${storeUri}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Checks bytes read from a store against their reference.
|
|
344
|
+
*
|
|
345
|
+
* The SHA-256 binds the bytes, and {@link detectImageMimeType} must find the reference's `mimeType` in them, so a
|
|
346
|
+
* reference whose type was changed after upload fails here.
|
|
347
|
+
*
|
|
348
|
+
* @param reference - The reference that was read.
|
|
349
|
+
* @param data - The bytes the store returned.
|
|
350
|
+
* @returns `data`, unchanged.
|
|
351
|
+
* @throws {MediaStoreError} When the size or the SHA-256 differs, or when the bytes are not a well-formed image of
|
|
352
|
+
* `mimeType`.
|
|
353
|
+
* @since 0.5.0
|
|
354
|
+
*/
|
|
355
|
+
export function verifyImageBytes(reference, data) {
|
|
356
|
+
if (data.length !== reference.sizeBytes || createHash("sha256").update(data).digest("hex") !== reference.sha256) {
|
|
357
|
+
throw new MediaStoreError(`image ${reference.uri} does not match its sha256 and size`);
|
|
358
|
+
}
|
|
359
|
+
let detected;
|
|
360
|
+
try {
|
|
361
|
+
detected = detectImageMimeType(data);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
if (!(error instanceof ImageValidationError)) {
|
|
365
|
+
throw error;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (detected !== reference.mimeType) {
|
|
369
|
+
throw new MediaStoreError(`image ${reference.uri} does not hold a well-formed ${reference.mimeType}`);
|
|
370
|
+
}
|
|
371
|
+
return data;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Reads the bytes of several images, each distinct image once.
|
|
375
|
+
*
|
|
376
|
+
* A runner calls it while building model input, with the references it chose from {@link collectTurnImages} or from
|
|
377
|
+
* its own replayed items. The reads run concurrently.
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```ts
|
|
381
|
+
* const images = await loadImages(store, collectTurnImages(turn));
|
|
382
|
+
* const parts = (message.images ?? []).map((reference) => imagePart(reference.mimeType, images.get(reference.sha256)!));
|
|
383
|
+
* ```
|
|
384
|
+
* @param store - The store that holds the images.
|
|
385
|
+
* @param references - The images to read, in any order, with repeats allowed.
|
|
386
|
+
* @returns The bytes of each image, keyed by {@link AgentImageReference.sha256}.
|
|
387
|
+
* @throws {ImageValidationError} When a reference's fields are invalid.
|
|
388
|
+
* @throws {MediaStoreError} When the store cannot return an image's exact bytes.
|
|
389
|
+
* @throws The store's own error when a read fails.
|
|
390
|
+
* @since 0.5.0
|
|
391
|
+
*/
|
|
392
|
+
export async function loadImages(store, references) {
|
|
393
|
+
const distinct = new Map();
|
|
394
|
+
for (const reference of references) {
|
|
395
|
+
distinct.set(reference.sha256, reference);
|
|
396
|
+
}
|
|
397
|
+
const contents = await Promise.all([...distinct.values()].map((reference) => store.getImage(reference)));
|
|
398
|
+
return new Map([...distinct.keys()].map((sha256, index) => [sha256, contents[index]]));
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Returns every image a model call of this turn may show, each once.
|
|
402
|
+
*
|
|
403
|
+
* It collects `AgentMessage.images` of `turn.messages` in sequence order, then `AgentToolCall.images` of the turn's
|
|
404
|
+
* records in deferral order, keeping the first reference to each SHA-256. Whether a model call shows earlier turns'
|
|
405
|
+
* images is the runner's choice; pass only the references it needs to {@link loadImages}.
|
|
406
|
+
*
|
|
407
|
+
* @param turn - The context of one `runModelStep` call.
|
|
408
|
+
* @returns The references, without repeats.
|
|
409
|
+
* @since 0.5.0
|
|
410
|
+
*/
|
|
411
|
+
export function collectTurnImages(turn) {
|
|
412
|
+
const collected = new Map();
|
|
413
|
+
const keepFirst = (reference) => {
|
|
414
|
+
if (!collected.has(reference.sha256)) {
|
|
415
|
+
collected.set(reference.sha256, reference);
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
for (const message of turn.messages) {
|
|
419
|
+
(message.images ?? []).forEach(keepFirst);
|
|
420
|
+
}
|
|
421
|
+
const records = [...turn.toolCalls].sort((left, right) => left.deferralOrder - right.deferralOrder);
|
|
422
|
+
for (const record of records) {
|
|
423
|
+
(record.images ?? []).forEach(keepFirst);
|
|
424
|
+
}
|
|
425
|
+
return [...collected.values()];
|
|
426
|
+
}
|
|
427
|
+
/** Reports whether {@link validateImageReferences} accepts the images; the RPCs answer `false` instead of throwing. */
|
|
428
|
+
export function areValidImageReferences(references) {
|
|
429
|
+
try {
|
|
430
|
+
validateImageReferences(references);
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
if (error instanceof ImageValidationError) {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
throw error;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Returns the `images` field of a succeeded record from a tool's result. An invalid reference throws
|
|
442
|
+
* {@link ImageValidationError}, which fails the tool Step attempt.
|
|
443
|
+
*/
|
|
444
|
+
export function toolResultImages(references) {
|
|
445
|
+
if (references === undefined || references.length === 0) {
|
|
446
|
+
return {};
|
|
447
|
+
}
|
|
448
|
+
validateImageReferences(references);
|
|
449
|
+
return { images: [...references] };
|
|
450
|
+
}
|
|
451
|
+
function startsWithBytes(data, signature) {
|
|
452
|
+
return data.length >= signature.length && signature.every((byte, index) => data[index] === byte);
|
|
453
|
+
}
|
|
454
|
+
function startsWithText(data, offset, text) {
|
|
455
|
+
return startsWithBytes(data.subarray(offset), [...text].map((character) => character.charCodeAt(0)));
|
|
456
|
+
}
|
|
457
|
+
//# sourceMappingURL=agent-media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-media.js","sourceRoot":"","sources":["../../src/agent-media.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Codec } from "@superdurable/dex";
|
|
2
|
-
import type { AgentEvent, AgentInterrupt, AgentInterruptResolution, AgentMessage, AgentMessageChunk, AgentMessageChunkRange, AgentMessageIndex, AgentMessagesPage, AgentPlan, AgentPlanTask, AgentSessionStartInput, AgentSnapshot, AgentState, AgentToolCallRecord, AgentUsage, AgentUserMessage, AnswerQuestionRequest, CancelTurnRequest, DeleteQueuedMessageRequest, ExecutePlanRequest, CompactContextInput, ContextSummary, ListAgentMessagesInput, PendingUserMessage, PlanExecutionRequest, QuestionAnswer, ResolveInterruptInput, SteerUserMessageRequest, ToolCallCancellation, ToolCallCompleted, TurnCancellationRequest, TurnControlRequest, SessionSettings, TurnReplySequence, TurnSessionSettings, UpdateSessionSettingsRequest } from "./agent-session-values.js";
|
|
2
|
+
import type { AgentEvent, AgentImageReference, AgentInterrupt, AgentInterruptResolution, AgentMessage, AgentMessageChunk, AgentMessageChunkRange, AgentMessageIndex, AgentMessagesPage, AgentPlan, AgentPlanTask, AgentSessionStartInput, AgentSnapshot, AgentState, AgentToolCallRecord, AgentUsage, AgentUserMessage, AnswerQuestionRequest, CancelTurnRequest, DeleteQueuedMessageRequest, ExecutePlanRequest, CompactContextInput, ContextSummary, ListAgentMessagesInput, PendingUserMessage, PlanExecutionRequest, QuestionAnswer, ResolveInterruptInput, SteerUserMessageRequest, ToolCallCancellation, ToolCallCompleted, TurnCancellationRequest, TurnControlRequest, SessionSettings, TurnReplySequence, TurnSessionSettings, UpdateSessionSettingsRequest } from "./agent-session-values.js";
|
|
3
3
|
export declare function encodeAgentSessionStartInput(value: AgentSessionStartInput): unknown;
|
|
4
4
|
export declare function decodeAgentSessionStartInput(value: unknown): AgentSessionStartInput;
|
|
5
5
|
export declare function encodeSessionSettings(value: SessionSettings): unknown;
|
|
@@ -10,6 +10,8 @@ export declare function encodeTurnSessionSettings(value: TurnSessionSettings): u
|
|
|
10
10
|
export declare function decodeTurnSessionSettings(value: unknown): TurnSessionSettings;
|
|
11
11
|
export declare function encodeAgentState(value: AgentState): unknown;
|
|
12
12
|
export declare function decodeAgentState(value: unknown): AgentState;
|
|
13
|
+
export declare function encodeAgentImageReference(value: AgentImageReference): unknown;
|
|
14
|
+
export declare function decodeAgentImageReference(value: unknown): AgentImageReference;
|
|
13
15
|
export declare function encodeAgentMessage(value: AgentMessage): unknown;
|
|
14
16
|
export declare function decodeAgentMessage(value: unknown): AgentMessage;
|
|
15
17
|
export declare function encodeAgentToolCall(value: AgentToolCallRecord): unknown;
|
|
@@ -136,18 +136,25 @@ class WireRecordReader {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
export function encodeAgentSessionStartInput(value) {
|
|
139
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
initial_message: value.initialMessage,
|
|
141
|
+
session_settings: value.sessionSettings ?? null,
|
|
142
|
+
start_environment: value.startEnvironment ?? null,
|
|
143
|
+
};
|
|
140
144
|
}
|
|
141
145
|
export function decodeAgentSessionStartInput(value) {
|
|
142
146
|
if (value === null || value === undefined) {
|
|
143
|
-
return { initialMessage: null, sessionSettings: null };
|
|
147
|
+
return { initialMessage: null, sessionSettings: null, startEnvironment: null };
|
|
144
148
|
}
|
|
145
149
|
const reader = new WireRecordReader(value, "AgentSessionStartInput");
|
|
146
150
|
const sessionSettings = reader.readObject("session_settings");
|
|
151
|
+
const startEnvironment = reader.readObject("start_environment");
|
|
147
152
|
return {
|
|
148
153
|
initialMessage: reader.readNullableString("initial_message"),
|
|
149
154
|
// Kept as sent: StartAgentSession refuses a value that is not an object, failing the session at once.
|
|
150
155
|
sessionSettings: sessionSettings == null ? null : sessionSettings,
|
|
156
|
+
// Kept as sent: the session never reads it.
|
|
157
|
+
startEnvironment: startEnvironment == null ? null : startEnvironment,
|
|
151
158
|
};
|
|
152
159
|
}
|
|
153
160
|
export function encodeSessionSettings(value) {
|
|
@@ -204,6 +211,34 @@ export function decodeAgentState(value) {
|
|
|
204
211
|
...(acceptsTurnControl ? { acceptsTurnControl } : {}),
|
|
205
212
|
};
|
|
206
213
|
}
|
|
214
|
+
export function encodeAgentImageReference(value) {
|
|
215
|
+
return {
|
|
216
|
+
type: value.type,
|
|
217
|
+
uri: value.uri,
|
|
218
|
+
mime_type: value.mimeType,
|
|
219
|
+
sha256: value.sha256,
|
|
220
|
+
size_bytes: value.sizeBytes,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
export function decodeAgentImageReference(value) {
|
|
224
|
+
const reader = new WireRecordReader(value, "AgentImageReference");
|
|
225
|
+
return {
|
|
226
|
+
// Another type decodes as it is, so validateImageReference refuses it as Python does.
|
|
227
|
+
type: (reader.readNullableString("type") ?? "image"),
|
|
228
|
+
uri: reader.readString("uri"),
|
|
229
|
+
mimeType: reader.readString("mime_type"),
|
|
230
|
+
sha256: reader.readString("sha256"),
|
|
231
|
+
sizeBytes: reader.readInteger("size_bytes"),
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
function encodeImages(images) {
|
|
235
|
+
return (images ?? []).map(encodeAgentImageReference);
|
|
236
|
+
}
|
|
237
|
+
/** Decodes an `images` field; decoded values omit it when there are none, as they do `planMode`. */
|
|
238
|
+
function decodeImages(reader) {
|
|
239
|
+
const images = reader.readArrayOrEmpty("images").map(decodeAgentImageReference);
|
|
240
|
+
return images.length === 0 ? {} : { images };
|
|
241
|
+
}
|
|
207
242
|
export function encodeAgentMessage(value) {
|
|
208
243
|
return {
|
|
209
244
|
sequence: value.sequence,
|
|
@@ -216,6 +251,7 @@ export function encodeAgentMessage(value) {
|
|
|
216
251
|
tool_output: value.toolOutput,
|
|
217
252
|
framework_item: value.frameworkItem,
|
|
218
253
|
created_at: value.createdAt,
|
|
254
|
+
images: encodeImages(value.images),
|
|
219
255
|
};
|
|
220
256
|
}
|
|
221
257
|
export function decodeAgentMessage(value) {
|
|
@@ -231,6 +267,7 @@ export function decodeAgentMessage(value) {
|
|
|
231
267
|
toolOutput: reader.readNullableString("tool_output"),
|
|
232
268
|
frameworkItem: reader.readString("framework_item"),
|
|
233
269
|
createdAt: reader.readString("created_at"),
|
|
270
|
+
...decodeImages(reader),
|
|
234
271
|
};
|
|
235
272
|
}
|
|
236
273
|
export function encodeAgentToolCall(value) {
|
|
@@ -258,6 +295,12 @@ export function encodeAgentToolCall(value) {
|
|
|
258
295
|
task_id: value.taskId ?? null,
|
|
259
296
|
task_poll_interval_seconds: value.taskPollIntervalSeconds ?? null,
|
|
260
297
|
task_answer_pending: value.taskAnswerPending ?? false,
|
|
298
|
+
ordered_write: value.orderedWrite ?? false,
|
|
299
|
+
write_queued: value.writeQueued ?? false,
|
|
300
|
+
skipped: value.skipped ?? false,
|
|
301
|
+
truncated_output_bytes: value.truncatedOutputBytes ?? null,
|
|
302
|
+
images: encodeImages(value.images),
|
|
303
|
+
runner_tool_state: value.runnerToolState ?? null,
|
|
261
304
|
};
|
|
262
305
|
}
|
|
263
306
|
export function decodeAgentToolCall(value) {
|
|
@@ -285,7 +328,13 @@ export function decodeAgentToolCall(value) {
|
|
|
285
328
|
taskId: reader.readNullableString("task_id"),
|
|
286
329
|
taskPollIntervalSeconds: reader.readNullableInteger("task_poll_interval_seconds"),
|
|
287
330
|
taskAnswerPending: reader.readBooleanOrDefault("task_answer_pending", false),
|
|
331
|
+
orderedWrite: reader.readBooleanOrDefault("ordered_write", false),
|
|
332
|
+
writeQueued: reader.readBooleanOrDefault("write_queued", false),
|
|
333
|
+
skipped: reader.readBooleanOrDefault("skipped", false),
|
|
334
|
+
truncatedOutputBytes: reader.readNullableInteger("truncated_output_bytes"),
|
|
335
|
+
runnerToolState: reader.readNullableString("runner_tool_state"),
|
|
288
336
|
...(traceContext === null ? {} : { traceContext }),
|
|
337
|
+
...decodeImages(reader),
|
|
289
338
|
};
|
|
290
339
|
const toolSourceReference = reader.readNullableString("tool_source_reference");
|
|
291
340
|
return toolSourceReference === null ? toolCall : { ...toolCall, toolSourceReference };
|
|
@@ -374,12 +423,12 @@ export function decodeAgentUsage(value) {
|
|
|
374
423
|
};
|
|
375
424
|
}
|
|
376
425
|
export function encodeAgentUserMessage(value) {
|
|
377
|
-
return { text: value.text, plan_mode: value.planMode ?? false };
|
|
426
|
+
return { text: value.text, plan_mode: value.planMode ?? false, images: encodeImages(value.images) };
|
|
378
427
|
}
|
|
379
428
|
export function decodeAgentUserMessage(value) {
|
|
380
429
|
const reader = new WireRecordReader(value, "AgentUserMessage");
|
|
381
430
|
const planMode = reader.readBooleanOrDefault("plan_mode", false);
|
|
382
|
-
return { text: reader.readString("text"), ...(planMode ? { planMode } : {}) };
|
|
431
|
+
return { text: reader.readString("text"), ...(planMode ? { planMode } : {}), ...decodeImages(reader) };
|
|
383
432
|
}
|
|
384
433
|
export function encodeAgentPlan(value) {
|
|
385
434
|
return {
|