@framers/agentos-ext-image-generation 1.1.0 → 2.0.1

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.
@@ -0,0 +1,393 @@
1
+ "use strict";
2
+ // @ts-nocheck
3
+ /**
4
+ * @fileoverview Where the image tools keep image data, and how a saved image
5
+ * comes back as a source.
6
+ *
7
+ * A provider that answers with image data (OpenAI's GPT Image models always
8
+ * do) used to have that data returned to the model as a `data:` URL: megabytes
9
+ * of base64 in the next request. The tools save the bytes to a file and return
10
+ * its `file:` URL, or hand them to the host's own saver. A saved file's URL is
11
+ * accepted as a source by the image-editing tools and by `vision-pipeline`.
12
+ * The image-generation, image-editing and vision-pipeline packs each carry
13
+ * this file, the same in all three, so they agree on the directory.
14
+ *
15
+ * The directory is private to the service's user, and each caller has a
16
+ * subdirectory of its own, which is read by the directory's real path and
17
+ * never through a link. That is the trust boundary: only this user can put a
18
+ * file there, so a file there with the saver's name pattern is one the
19
+ * service wrote, for that caller. It holds only while no other user can
20
+ * change a directory above the images directory: one who could rename an
21
+ * entry there could swap the tree between a check and the write or open
22
+ * that follows it, and Node has no openat to pin a checked directory. So
23
+ * each directory above it must belong to this user or root and be writable
24
+ * by no one else, unless it is sticky, as /tmp is. A Kubernetes emptyDir on
25
+ * disk is 0777 with no sticky bit and is refused as a parent; SKILL.md says
26
+ * which volumes pass.
27
+ */
28
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ var desc = Object.getOwnPropertyDescriptor(m, k);
31
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
32
+ desc = { enumerable: true, get: function() { return m[k]; } };
33
+ }
34
+ Object.defineProperty(o, k2, desc);
35
+ }) : (function(o, m, k, k2) {
36
+ if (k2 === undefined) k2 = k;
37
+ o[k2] = m[k];
38
+ }));
39
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
40
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
41
+ }) : function(o, v) {
42
+ o["default"] = v;
43
+ });
44
+ var __importStar = (this && this.__importStar) || (function () {
45
+ var ownKeys = function(o) {
46
+ ownKeys = Object.getOwnPropertyNames || function (o) {
47
+ var ar = [];
48
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
49
+ return ar;
50
+ };
51
+ return ownKeys(o);
52
+ };
53
+ return function (mod) {
54
+ if (mod && mod.__esModule) return mod;
55
+ var result = {};
56
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
57
+ __setModuleDefault(result, mod);
58
+ return result;
59
+ };
60
+ })();
61
+ Object.defineProperty(exports, "__esModule", { value: true });
62
+ exports.MAX_SOURCE_BYTES = void 0;
63
+ exports.imageDirectory = imageDirectory;
64
+ exports.scopeOf = scopeOf;
65
+ exports.imageKind = imageKind;
66
+ exports.saveImageFile = saveImageFile;
67
+ exports.readSavedImage = readSavedImage;
68
+ exports.checkImageStore = checkImageStore;
69
+ exports.imageStore = imageStore;
70
+ exports.storeImage = storeImage;
71
+ const node_crypto_1 = require("node:crypto");
72
+ const node_fs_1 = require("node:fs");
73
+ const fs = __importStar(require("node:fs/promises"));
74
+ const os = __importStar(require("node:os"));
75
+ const path = __importStar(require("node:path"));
76
+ const node_url_1 = require("node:url");
77
+ /** The most bytes of a saved image the tools read back as a source: 50 MiB. */
78
+ exports.MAX_SOURCE_BYTES = 50 * 1024 * 1024;
79
+ /** The name of a file the saver wrote. */
80
+ const SAVED_NAME = /^agentos-image-[0-9a-f]{32}\.(png|jpg|webp)$/;
81
+ /** The eight bytes every PNG starts with. */
82
+ const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
83
+ /**
84
+ * The images directory: the pack option `imageDir`, else the environment
85
+ * variable `AGENTOS_IMAGE_DIR`, else a folder in the user's temp directory,
86
+ * which the operating system clears (the packs delete nothing). On POSIX the
87
+ * default carries the user id, since `/tmp` is shared. On Windows it is the
88
+ * user's own temp folder whatever `TEMP` says: `os.tmpdir()` reads `TEMP`,
89
+ * which can name a folder every user shares.
90
+ */
91
+ function imageDirectory(option) {
92
+ const named = [option, process.env.AGENTOS_IMAGE_DIR]
93
+ .map((value) => (typeof value === 'string' ? value.trim() : ''))
94
+ .find(Boolean);
95
+ if (named)
96
+ return path.resolve(named);
97
+ if (typeof process.getuid === 'function')
98
+ return path.join(os.tmpdir(), `agentos-images-${process.getuid()}`);
99
+ return path.join(os.homedir(), 'AppData', 'Local', 'Temp', 'agentos-images');
100
+ }
101
+ /**
102
+ * The name of a caller's subdirectory: `u-` and 32 hex characters of the
103
+ * SHA-256 of its user id, or `shared` for a call that carries none. A host
104
+ * with several users gives each call its user (`context.userContext.userId`),
105
+ * so one user's saved image is no source for another.
106
+ */
107
+ function scopeOf(context) {
108
+ const userId = context?.userContext?.userId;
109
+ return typeof userId === 'string' && userId !== ''
110
+ ? `u-${(0, node_crypto_1.createHash)('sha256').update(userId).digest('hex').slice(0, 32)}`
111
+ : 'shared';
112
+ }
113
+ /** The kind of image `bytes` are, by their signature: PNG, JPEG or WebP. */
114
+ function imageKind(bytes) {
115
+ if (bytes.length >= 8 && bytes.subarray(0, 8).equals(PNG_SIGNATURE))
116
+ return { ext: 'png', mimeType: 'image/png' };
117
+ if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff) {
118
+ return { ext: 'jpg', mimeType: 'image/jpeg' };
119
+ }
120
+ if (bytes.length >= 12 && bytes.toString('latin1', 0, 4) === 'RIFF' && bytes.toString('latin1', 8, 12) === 'WEBP') {
121
+ return { ext: 'webp', mimeType: 'image/webp' };
122
+ }
123
+ return undefined;
124
+ }
125
+ /**
126
+ * Whether a directory's `stat` (taken with `bigint: true`) shows it private
127
+ * to this user: a directory this user owns that neither its group nor others
128
+ * can write. Where the platform has no user ids (Windows) only the kind is
129
+ * checked: the default there is inside the user's own profile.
130
+ */
131
+ function isPrivateDirectory(stat) {
132
+ if (!stat.isDirectory())
133
+ return false;
134
+ if (typeof process.getuid !== 'function')
135
+ return true;
136
+ return stat.uid === BigInt(process.getuid()) && (stat.mode & BigInt(0o022)) === BigInt(0);
137
+ }
138
+ /** The error for a directory that is not private to this user. */
139
+ function notPrivate(dir) {
140
+ return new Error(`${dir} is not a directory that this user owns and no one else can write`);
141
+ }
142
+ /**
143
+ * Why another user could change a directory above `dir`, a real path, or
144
+ * `undefined` when none can: each directory above it must belong to this
145
+ * user or root and be writable by no one else, unless it is sticky, where
146
+ * only an entry's owner can rename it. Where the platform has no user ids
147
+ * (Windows) nothing is checked, as in {@link isPrivateDirectory}.
148
+ */
149
+ async function changeableParent(dir) {
150
+ if (typeof process.getuid !== 'function')
151
+ return undefined;
152
+ const uid = BigInt(process.getuid());
153
+ for (let parent = path.dirname(dir);; parent = path.dirname(parent)) {
154
+ const stat = await fs.lstat(parent, { bigint: true });
155
+ const mode = (stat.mode & BigInt(0o7777)).toString(8).padStart(4, '0');
156
+ if (!stat.isDirectory())
157
+ return `${parent}, above it, is not a directory`;
158
+ if (stat.uid !== uid && stat.uid !== BigInt(0))
159
+ return `${parent}, above it, belongs to uid ${stat.uid} (mode ${mode})`;
160
+ if ((stat.mode & BigInt(0o022)) !== BigInt(0) && (stat.mode & BigInt(0o1000)) === BigInt(0)) {
161
+ return `${parent}, above it, can be written by others and is not sticky (owner uid ${stat.uid}, mode ${mode})`;
162
+ }
163
+ if (path.dirname(parent) === parent)
164
+ return undefined;
165
+ }
166
+ }
167
+ /**
168
+ * The caller's subdirectory of `dir`, by `dir`'s real path, with both made
169
+ * when missing, for this user alone.
170
+ *
171
+ * @throws When either cannot be made, or is not a directory this user owns
172
+ * that no one else can write; the caller's directory must not be a link.
173
+ */
174
+ async function callerDirectory(dir, scope) {
175
+ await fs.mkdir(dir, { recursive: true, mode: 0o700 });
176
+ // Written by the real path, so a link swapped in for it later moves nothing.
177
+ const root = await fs.realpath(dir);
178
+ if (!isPrivateDirectory(await fs.stat(root, { bigint: true })))
179
+ throw notPrivate(root);
180
+ const parent = await changeableParent(root);
181
+ if (parent)
182
+ throw new Error(parent);
183
+ const scopeDir = path.join(root, scope);
184
+ await fs.mkdir(scopeDir, { recursive: true, mode: 0o700 });
185
+ // lstat: a caller's directory that is a link to another caller's is refused.
186
+ if (!isPrivateDirectory(await fs.lstat(scopeDir, { bigint: true })))
187
+ throw notPrivate(scopeDir);
188
+ // A directory this user owns can still refuse a new file: its mode (0500),
189
+ // or a file system mounted read-only.
190
+ await fs.access(scopeDir, node_fs_1.constants.W_OK | node_fs_1.constants.X_OK);
191
+ return scopeDir;
192
+ }
193
+ /** The error of a save that cannot use `dir`: it names the directory and the option that sets it. */
194
+ function cannotSave(dir, error) {
195
+ const reason = error instanceof Error ? error.message : String(error);
196
+ return new Error(`The image could not be saved under ${dir}: ${reason}. Set the pack's imageDir option, or AGENTOS_IMAGE_DIR, to a directory that the service's user owns and no one else can write, under directories that no other user can change (a sticky one such as /tmp is fine).`);
197
+ }
198
+ /**
199
+ * Saves image bytes as a new file in the caller's subdirectory of `dir` and
200
+ * returns its `file:` URL. The extension comes from the bytes' signature, and
201
+ * the name is random, so a file is never overwritten.
202
+ *
203
+ * @throws When the bytes are not a PNG, JPEG or WebP image, or when the
204
+ * directory cannot be made, is not private to this user, or cannot be
205
+ * written. The message names the directory and the option that sets it.
206
+ */
207
+ async function saveImageFile(bytes, dir, scope) {
208
+ const kind = imageKind(bytes);
209
+ if (!kind)
210
+ throw new Error('The provider returned data that is not a PNG, JPEG or WebP image.');
211
+ try {
212
+ const scopeDir = await callerDirectory(dir, scope);
213
+ const file = path.join(scopeDir, `agentos-image-${(0, node_crypto_1.randomBytes)(16).toString('hex')}.${kind.ext}`);
214
+ await fs.writeFile(file, bytes, { flag: 'wx', mode: 0o600 });
215
+ return (0, node_url_1.pathToFileURL)(file).href;
216
+ }
217
+ catch (error) {
218
+ throw cannotSave(dir, error);
219
+ }
220
+ }
221
+ /**
222
+ * The bytes of the saved image that `source` names, or `undefined` when
223
+ * `source` is not the `file:` URL of an image the saver wrote for this
224
+ * caller. Every reason gives `undefined`, so the caller's one refusal does
225
+ * not tell which files exist.
226
+ *
227
+ * The file must carry the saver's name pattern and sit directly in the
228
+ * caller's subdirectory of the images directory's real path: the same
229
+ * directory by device and inode, itself a directory and not a link, private
230
+ * to this user, as the images directory is, with no directory above the
231
+ * images directory that another user can change. It must be a regular file with
232
+ * one link and at most {@link MAX_SOURCE_BYTES}, and start with a PNG, JPEG
233
+ * or WebP signature. It is opened once, without following a link, and read
234
+ * from that handle.
235
+ */
236
+ async function readSavedImage(source, dir, scope) {
237
+ let handle;
238
+ try {
239
+ const url = new URL(source);
240
+ if (url.protocol !== 'file:' || url.hostname !== '')
241
+ return undefined;
242
+ const named = (0, node_url_1.fileURLToPath)(url);
243
+ if (!SAVED_NAME.test(path.basename(named)))
244
+ return undefined;
245
+ // fs.promises.realpath asks the operating system. (fs.realpathSync and
246
+ // fs.realpath resolve ".." in the text first, as path.resolve does.)
247
+ const real = await fs.realpath(named);
248
+ if (!SAVED_NAME.test(path.basename(real)))
249
+ return undefined;
250
+ // The images directory as it is now, by its real path, so a directory
251
+ // swapped in for it is read as what it is; and the caller's directory in
252
+ // it by lstat, so a link to another caller's directory is refused.
253
+ const root = await fs.realpath(dir);
254
+ if (await changeableParent(root))
255
+ return undefined;
256
+ // The directories the file is opened through, every one above its own,
257
+ // must be ones no other user can change, as the images directory's are.
258
+ // Checked on the file's path itself, so a path spelled in another case on
259
+ // a file system that ignores case, which realpath can leave as given,
260
+ // reaches the same directories and is read.
261
+ if (await changeableParent(path.dirname(real)))
262
+ return undefined;
263
+ const scopePath = path.join(root, scope);
264
+ const [rootDir, parent, scopeDir] = await Promise.all([
265
+ fs.stat(root, { bigint: true }),
266
+ fs.stat(path.dirname(real), { bigint: true }),
267
+ fs.lstat(scopePath, { bigint: true }),
268
+ ]);
269
+ if (!isPrivateDirectory(rootDir) || !isPrivateDirectory(scopeDir))
270
+ return undefined;
271
+ if (parent.dev !== scopeDir.dev || parent.ino !== scopeDir.ino)
272
+ return undefined;
273
+ // A FIFO would hold an open until a writer came; only a regular file is opened.
274
+ if (!(await fs.lstat(real)).isFile())
275
+ return undefined;
276
+ handle = await fs.open(real, node_fs_1.constants.O_RDONLY | (node_fs_1.constants.O_NOFOLLOW ?? 0) | (node_fs_1.constants.O_NONBLOCK ?? 0));
277
+ const stat = await handle.stat({ bigint: true });
278
+ if (!stat.isFile() || stat.nlink !== BigInt(1) || stat.size > BigInt(exports.MAX_SOURCE_BYTES))
279
+ return undefined;
280
+ // Checked again now that the file is open: the path still reaches the
281
+ // file opened, in the caller's directory.
282
+ const [linked, parentNow] = await Promise.all([
283
+ fs.lstat(real, { bigint: true }),
284
+ fs.stat(path.dirname(real), { bigint: true }),
285
+ ]);
286
+ if (linked.dev !== stat.dev || linked.ino !== stat.ino)
287
+ return undefined;
288
+ if (parentNow.dev !== scopeDir.dev || parentNow.ino !== scopeDir.ino)
289
+ return undefined;
290
+ // One byte more than the size at open: a file that has grown is refused.
291
+ const size = Number(stat.size);
292
+ const buffer = Buffer.alloc(size + 1);
293
+ let length = 0;
294
+ while (length < buffer.length) {
295
+ const { bytesRead } = await handle.read(buffer, length, buffer.length - length, null);
296
+ if (bytesRead === 0)
297
+ break;
298
+ length += bytesRead;
299
+ }
300
+ if (length > size)
301
+ return undefined;
302
+ const bytes = buffer.subarray(0, length);
303
+ return imageKind(bytes) ? bytes : undefined;
304
+ }
305
+ catch {
306
+ return undefined;
307
+ }
308
+ finally {
309
+ await handle?.close().catch(() => { });
310
+ }
311
+ }
312
+ /**
313
+ * Checks, before a provider is called, that the image data it may return can
314
+ * be saved for this caller: with no host `saveImage`, the images directory
315
+ * and the caller's directory in it are made and checked as a save makes and
316
+ * checks them. A provider bills for the image it makes, so a directory the
317
+ * saver would refuse is refused first.
318
+ *
319
+ * @throws The error a save would give, naming the directory and the option.
320
+ */
321
+ async function checkImageStore(store, context) {
322
+ if (store.saveImage)
323
+ return;
324
+ try {
325
+ await callerDirectory(store.dir, scopeOf(context));
326
+ }
327
+ catch (error) {
328
+ throw cannotSave(store.dir, error);
329
+ }
330
+ }
331
+ /** The store for a pack's options: its `imageDir` and its `saveImage`, when that is a function. */
332
+ function imageStore(options) {
333
+ return {
334
+ dir: imageDirectory(options?.imageDir),
335
+ saveImage: typeof options?.saveImage === 'function' ? options.saveImage : undefined,
336
+ };
337
+ }
338
+ /** The longest reference a host's saver may return. */
339
+ const MAX_REFERENCE_LENGTH = 2048;
340
+ /** The bytes of a base64 `data:` URL, the form AgentOS's providers give image data in; `undefined` for anything else. */
341
+ function dataUrlBytes(value) {
342
+ if (typeof value !== 'string' || !/^data:/i.test(value))
343
+ return undefined;
344
+ const comma = value.indexOf(',');
345
+ if (comma === -1 || !/; *base64 *$/i.test(value.slice(0, comma)))
346
+ return undefined;
347
+ return Buffer.from(value.slice(comma + 1), 'base64');
348
+ }
349
+ /** Whether a saver's result is an http(s) URL short enough to hand to the model. */
350
+ function isHttpReference(value) {
351
+ if (typeof value !== 'string' || value.length === 0 || value.length > MAX_REFERENCE_LENGTH)
352
+ return false;
353
+ try {
354
+ const { protocol } = new URL(value);
355
+ return protocol === 'http:' || protocol === 'https:';
356
+ }
357
+ catch {
358
+ return false;
359
+ }
360
+ }
361
+ /**
362
+ * An image a provider returned, as the reference the caller gets: the
363
+ * provider's http(s) URL as it is, or, for image data, the URL under which
364
+ * it was saved. Image data is never returned itself: as a `data:` URL it
365
+ * would go into the model's next request, megabytes of base64. `undefined`
366
+ * when the provider returned neither a URL nor data.
367
+ *
368
+ * @throws When the data is not a PNG, JPEG or WebP image, when it cannot be
369
+ * saved, or when the host's saver throws or returns anything but an
370
+ * http(s) URL of at most 2,048 characters.
371
+ */
372
+ async function storeImage(image, tool, store, context) {
373
+ if (!image)
374
+ return undefined;
375
+ if (typeof image.url === 'string' && /^https?:\/\//i.test(image.url))
376
+ return image.url;
377
+ const bytes = typeof image.base64 === 'string' && image.base64 !== ''
378
+ ? Buffer.from(image.base64, 'base64')
379
+ : (dataUrlBytes(image.dataUrl) ?? dataUrlBytes(image.url));
380
+ if (!bytes || bytes.length === 0)
381
+ return undefined;
382
+ if (!store.saveImage)
383
+ return saveImageFile(bytes, store.dir, scopeOf(context));
384
+ const kind = imageKind(bytes);
385
+ if (!kind)
386
+ throw new Error('The provider returned data that is not a PNG, JPEG or WebP image.');
387
+ const reference = await store.saveImage({ bytes, mimeType: kind.mimeType, tool, context });
388
+ if (!isHttpReference(reference)) {
389
+ throw new Error("The host's saveImage must return an http(s) URL of at most 2,048 characters.");
390
+ }
391
+ return reference;
392
+ }
393
+ //# sourceMappingURL=imageFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageFiles.js","sourceRoot":"","sources":["../src/imageFiles.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,15 @@
1
+ /**
2
+ * @fileoverview Image Generation Extension Pack: the `generate_image` tool on
3
+ * AgentOS's `generateImage`, with OpenAI, OpenRouter, Stability AI and
4
+ * Replicate.
5
+ *
6
+ * Image data a provider returns is saved, never returned: to a file in the
7
+ * images directory (`imageDir`, `AGENTOS_IMAGE_DIR`, or a folder in the
8
+ * user's temp directory), or by the host's `saveImage`.
9
+ */
1
10
  import type { ExtensionPackContext, ExtensionPack } from '@framers/agentos';
11
+ import { type ImageQuality } from './ImageGenerationService.js';
12
+ import type { SaveImage } from './imageFiles.js';
2
13
  export interface ImageGenerationOptions {
3
14
  openaiApiKey?: string;
4
15
  openrouterApiKey?: string;
@@ -7,11 +18,35 @@ export interface ImageGenerationOptions {
7
18
  defaultProvider?: 'openai' | 'openrouter' | 'stability' | 'replicate';
8
19
  defaultModel?: string;
9
20
  defaultSize?: string;
10
- defaultQuality?: 'standard' | 'hd';
21
+ defaultQuality?: ImageQuality;
22
+ /**
23
+ * Where image data a provider returns is saved, each caller in a
24
+ * subdirectory of its own (else `AGENTOS_IMAGE_DIR`, else a folder in the
25
+ * user's temp directory). The directory must belong to the service's user,
26
+ * with no one else able to write it; it is made and checked before a
27
+ * provider is called, so a directory the tools refuse costs no image.
28
+ * Every directory above it must belong to that user or to root and be
29
+ * writable by no one else unless it is sticky, as `/tmp` is, so a disk-backed
30
+ * Kubernetes `emptyDir` (0777, not sticky) is refused as a place for it: make
31
+ * the mount sticky (`chmod 1777` in an init container), give it to the
32
+ * service's user, or pass `saveImage`. The image-editing and
33
+ * vision-pipeline packs take the same option: give all three the same
34
+ * directory, so an image this pack saved is a source for them.
35
+ */
36
+ imageDir?: string;
37
+ /**
38
+ * Stores image data in place of the default saver and returns the http(s)
39
+ * URL under which the host's clients load it. A `file:` URL names a file
40
+ * on the machine that ran the tool, so a host whose clients are elsewhere
41
+ * sets this.
42
+ */
43
+ saveImage?: SaveImage;
11
44
  priority?: number;
12
45
  }
13
46
  export declare function createExtensionPack(context: ExtensionPackContext): ExtensionPack;
14
47
  export { ImageGenerationService } from './ImageGenerationService.js';
48
+ export type { ImageGenerationConfig, GenerateImageOptions, GeneratedImage, ImageQuality } from './ImageGenerationService.js';
49
+ export type { ImageStore, SaveImage } from './imageFiles.js';
15
50
  export { GenerateImageTool } from './tools/generateImage.js';
16
51
  export default createExtensionPack;
17
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EAEd,MAAM,kBAAkB,CAAC;AAK1B,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAsEhF;AAED,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EAEd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAA0B,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACxF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwEhF;AAED,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC7H,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,eAAe,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,9 @@ exports.GenerateImageTool = exports.ImageGenerationService = void 0;
4
4
  exports.createExtensionPack = createExtensionPack;
5
5
  const ImageGenerationService_js_1 = require("./ImageGenerationService.js");
6
6
  const generateImage_js_1 = require("./tools/generateImage.js");
7
+ // This pack compiles to CommonJS, where `require` reads the package's own
8
+ // version: `import.meta` does not exist there.
9
+ const { version } = require('../package.json');
7
10
  function createExtensionPack(context) {
8
11
  const options = (context.options ?? {});
9
12
  const openaiApiKey = options.openaiApiKey ||
@@ -27,11 +30,13 @@ function createExtensionPack(context) {
27
30
  defaultModel: options.defaultModel,
28
31
  defaultSize: options.defaultSize,
29
32
  defaultQuality: options.defaultQuality,
33
+ imageDir: options.imageDir,
34
+ saveImage: options.saveImage,
30
35
  });
31
36
  const tool = new generateImage_js_1.GenerateImageTool(service);
32
37
  return {
33
38
  name: '@framers/agentos-ext-image-generation',
34
- version: '1.0.0',
39
+ version,
35
40
  descriptors: [
36
41
  {
37
42
  id: tool.name,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAsBA,kDAsEC;AArFD,2EAAqE;AACrE,+DAA6D;AAc7D,SAAgB,mBAAmB,CAAC,OAA6B;IAC/D,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAA2B,CAAC;IAElE,MAAM,YAAY,GAChB,OAAO,CAAC,YAAY;QACpB,OAAO,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE7B,MAAM,gBAAgB,GACpB,OAAO,CAAC,gBAAgB;QACxB,OAAO,CAAC,SAAS,EAAE,CAAC,mBAAmB,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAEjC,MAAM,eAAe,GACnB,OAAO,CAAC,eAAe;QACvB,OAAO,CAAC,SAAS,EAAE,CAAC,kBAAkB,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAEhC,MAAM,iBAAiB,GACrB,OAAO,CAAC,iBAAiB;QACzB,OAAO,CAAC,SAAS,EAAE,CAAC,oBAAoB,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAElC,MAAM,OAAO,GAAG,IAAI,kDAAsB,CAAC;QACzC,YAAY;QACZ,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,IAAI,oCAAiB,CAAC,OAAO,CAAC,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,uCAAuC;QAC7C,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE;YACX;gBACE,EAAE,EAAE,IAAI,CAAC,IAAI;gBACb,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;gBAChC,OAAO,EAAE,IAAI;gBACb,eAAe,EAAE;oBACf,EAAE,EAAE,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;oBACvC,EAAE,EAAE,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC3C,EAAE,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC1C,EAAE,EAAE,EAAE,oBAAoB,EAAE,QAAQ,EAAE,IAAI,EAAE;iBAC7C;aACF;SACF;QACD,UAAU,EAAE,KAAK,EAAE,EAA8B,EAAE,EAAE;YACnD,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,SAAS;gBAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChD,IAAI,OAAO,CAAC,aAAa;gBAAE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxD,IAAI,OAAO,CAAC,YAAY;gBAAE,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACzD,IAAI,OAAO,CAAC,YAAY;gBAAE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;gBACjC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;gBACvB,CAAC,CAAC,4GAA4G,CAAC;YACjH,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,0CAA0C,MAAM,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,YAAY,EAAE,KAAK,EAAE,EAA8B,EAAE,EAAE;YACrD,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzB,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAC7D,CAAC;KACF,CAAC;AACJ,CAAC;AAED,yEAAqE;AAA5D,mIAAA,sBAAsB,OAAA;AAC/B,6DAA6D;AAApD,qHAAA,iBAAiB,OAAA;AAC1B,kBAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -6,16 +6,18 @@ import type { ITool, JSONSchemaObject, ToolExecutionContext, ToolExecutionResult
6
6
  import type { ImageGenerationService } from '../ImageGenerationService.js';
7
7
  export interface GenerateImageInput {
8
8
  prompt: string;
9
- size?: '1024x1024' | '1792x1024' | '1024x1792';
9
+ size?: '1024x1024' | '1536x1024' | '1024x1536' | '1792x1024' | '1024x1792';
10
10
  aspectRatio?: string;
11
- quality?: 'standard' | 'hd';
11
+ quality?: 'low' | 'medium' | 'high' | 'auto' | 'standard' | 'hd';
12
12
  style?: 'vivid' | 'natural';
13
13
  provider?: 'openai' | 'openrouter' | 'stability' | 'replicate';
14
+ /** The provider's own model id, without a provider prefix. */
14
15
  model?: string;
15
16
  seed?: number;
16
17
  negativePrompt?: string;
17
18
  }
18
19
  export interface GenerateImageOutput {
20
+ /** The image as a URL: the provider's, or the file: URL of the copy that was saved of the image data it returned. */
19
21
  url: string;
20
22
  revisedPrompt?: string;
21
23
  provider: string;
@@ -26,12 +28,20 @@ export declare class GenerateImageTool implements ITool<GenerateImageInput, Gene
26
28
  readonly id = "tool.generate_image";
27
29
  readonly name = "generate_image";
28
30
  readonly displayName = "Generate Image";
29
- readonly description = "Generate an image from a text prompt using the configured image providers. Returns a URL or data URL to the generated image.";
31
+ readonly description: string;
30
32
  readonly category = "media";
31
33
  readonly hasSideEffects = false;
32
34
  readonly inputSchema: JSONSchemaObject;
33
35
  private service;
34
36
  constructor(service: ImageGenerationService);
35
- execute(args: GenerateImageInput, _context?: ToolExecutionContext): Promise<ToolExecutionResult<GenerateImageOutput>>;
37
+ execute(args: GenerateImageInput, context?: ToolExecutionContext): Promise<ToolExecutionResult<GenerateImageOutput>>;
38
+ /**
39
+ * The service call for a tool call's arguments, or the error for an
40
+ * argument the schema does not allow. Only the schema's own fields are
41
+ * taken: the model writes the arguments, and anything else it adds (`n`,
42
+ * `providerOptions`, whose `extraBody` goes into the provider's request)
43
+ * is not passed on.
44
+ */
45
+ private optionsFrom;
36
46
  }
37
47
  //# sourceMappingURL=generateImage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateImage.d.ts","sourceRoot":"","sources":["../../src/tools/generateImage.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3G,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,8BAA8B,CAAC;AAEjG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,iBAAkB,YAAW,KAAK,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;IACtF,QAAQ,CAAC,EAAE,yBAAyB;IACpC,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,WAAW,oBAAoB;IACxC,QAAQ,CAAC,WAAW,kIAAkI;IACtJ,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,cAAc,SAAS;IAEhC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CA6CpC;IAEF,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,EAAE,sBAAsB;IAIrC,OAAO,CACX,IAAI,EAAE,kBAAkB,EACxB,QAAQ,CAAC,EAAE,oBAAoB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;CA8BrD"}
1
+ {"version":3,"file":"generateImage.d.ts","sourceRoot":"","sources":["../../src/tools/generateImage.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC3G,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,8BAA8B,CAAC;AAEjG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IACjE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;IAC/D,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,qHAAqH;IACrH,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AASD,qBAAa,iBAAkB,YAAW,KAAK,CAAC,kBAAkB,EAAE,mBAAmB,CAAC;IACtF,QAAQ,CAAC,EAAE,yBAAyB;IACpC,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,WAAW,oBAAoB;IACxC,QAAQ,CAAC,WAAW,SAEgH;IACpI,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,cAAc,SAAS;IAEhC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CA6CpC;IAEF,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,EAAE,sBAAsB;IAIrC,OAAO,CACX,IAAI,EAAE,kBAAkB,EACxB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;IAiCpD;;;;;;OAMG;IACH,OAAO,CAAC,WAAW;CAsBpB"}