@howells/motif-sdk 0.3.0 → 0.3.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.
- package/LICENSE +21 -0
- package/dist/index.cjs +26 -19
- package/dist/index.d.cts +0 -34
- package/dist/index.d.ts +0 -34
- package/dist/index.js +26 -19
- package/package.json +12 -13
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daniel Howells
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -941,6 +941,10 @@ function estimateCost(model, resolution, numImages = 1) {
|
|
|
941
941
|
if ((model === "banana" || model === "gemini3") && resolution === "4K") {
|
|
942
942
|
return configuredPrice * 2 * numImages;
|
|
943
943
|
}
|
|
944
|
+
if (model === "banana2") {
|
|
945
|
+
const multiplier = resolution === "4K" ? 2 : resolution === "2K" ? 1.5 : resolution === "0.5K" ? 0.75 : 1;
|
|
946
|
+
return configuredPrice * multiplier * numImages;
|
|
947
|
+
}
|
|
944
948
|
return configuredPrice * numImages;
|
|
945
949
|
}
|
|
946
950
|
switch (model) {
|
|
@@ -2252,23 +2256,6 @@ var FAL_TOOLS = {
|
|
|
2252
2256
|
output_format: "png"
|
|
2253
2257
|
}
|
|
2254
2258
|
},
|
|
2255
|
-
"sam3-1-image": {
|
|
2256
|
-
name: "SAM 3.1 Image",
|
|
2257
|
-
endpoint: "fal-ai/sam-3-1/image",
|
|
2258
|
-
task: "promptable image segmentation",
|
|
2259
|
-
category: "segmentation",
|
|
2260
|
-
description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.",
|
|
2261
|
-
inputKind: "image",
|
|
2262
|
-
inputField: "image_url",
|
|
2263
|
-
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2264
|
-
pricing: "$0.005/request",
|
|
2265
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image",
|
|
2266
|
-
defaultOptions: {
|
|
2267
|
-
apply_mask: true,
|
|
2268
|
-
max_masks: 3,
|
|
2269
|
-
output_format: "png"
|
|
2270
|
-
}
|
|
2271
|
-
},
|
|
2272
2259
|
"sam3-image-rle": {
|
|
2273
2260
|
name: "SAM 3 Image RLE",
|
|
2274
2261
|
endpoint: "fal-ai/sam-3/image-rle",
|
|
@@ -2452,7 +2439,13 @@ var MotifServer = class {
|
|
|
2452
2439
|
if (config?.useQueue) {
|
|
2453
2440
|
return this.generateQueued(options);
|
|
2454
2441
|
}
|
|
2455
|
-
|
|
2442
|
+
let built;
|
|
2443
|
+
try {
|
|
2444
|
+
built = buildGenerateBody(options);
|
|
2445
|
+
} catch (error) {
|
|
2446
|
+
return (0, import_neverthrow.err)(toMotifError(error));
|
|
2447
|
+
}
|
|
2448
|
+
const { endpoint, body } = built;
|
|
2456
2449
|
const response = await this.request(`${FAL_BASE_URL}/${endpoint}`, {
|
|
2457
2450
|
method: "POST",
|
|
2458
2451
|
body: JSON.stringify(body),
|
|
@@ -2494,7 +2487,13 @@ var MotifServer = class {
|
|
|
2494
2487
|
/** ─── Queue-Based Generation ──────────────────────────────── */
|
|
2495
2488
|
/** Submit a generation to the fal.ai queue (returns immediately). */
|
|
2496
2489
|
async submitGeneration(options) {
|
|
2497
|
-
|
|
2490
|
+
let built;
|
|
2491
|
+
try {
|
|
2492
|
+
built = buildGenerateBody(options);
|
|
2493
|
+
} catch (error) {
|
|
2494
|
+
return (0, import_neverthrow.err)(toMotifError(error));
|
|
2495
|
+
}
|
|
2496
|
+
const { endpoint, body } = built;
|
|
2498
2497
|
const response = await this.request(`${FAL_QUEUE_URL}/${endpoint}`, {
|
|
2499
2498
|
method: "POST",
|
|
2500
2499
|
body: JSON.stringify(body),
|
|
@@ -2894,6 +2893,14 @@ var MotifError = class extends Error {
|
|
|
2894
2893
|
this.code = code;
|
|
2895
2894
|
}
|
|
2896
2895
|
};
|
|
2896
|
+
function toMotifError(error) {
|
|
2897
|
+
if (error instanceof MotifError) {
|
|
2898
|
+
return error;
|
|
2899
|
+
}
|
|
2900
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2901
|
+
const code = error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
2902
|
+
return new MotifError(message, 0, code);
|
|
2903
|
+
}
|
|
2897
2904
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2898
2905
|
0 && (module.exports = {
|
|
2899
2906
|
ASPECT_RATIOS,
|
package/dist/index.d.cts
CHANGED
|
@@ -783,23 +783,6 @@ declare class MotifServer {
|
|
|
783
783
|
readonly output_format: "png";
|
|
784
784
|
};
|
|
785
785
|
};
|
|
786
|
-
readonly "sam3-1-image": {
|
|
787
|
-
readonly name: "SAM 3.1 Image";
|
|
788
|
-
readonly endpoint: "fal-ai/sam-3-1/image";
|
|
789
|
-
readonly task: "promptable image segmentation";
|
|
790
|
-
readonly category: "segmentation";
|
|
791
|
-
readonly description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.";
|
|
792
|
-
readonly inputKind: "image";
|
|
793
|
-
readonly inputField: "image_url";
|
|
794
|
-
readonly outputKeys: ["image", "masks", "metadata", "scores", "boxes"];
|
|
795
|
-
readonly pricing: "$0.005/request";
|
|
796
|
-
readonly sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image";
|
|
797
|
-
readonly defaultOptions: {
|
|
798
|
-
readonly apply_mask: true;
|
|
799
|
-
readonly max_masks: 3;
|
|
800
|
-
readonly output_format: "png";
|
|
801
|
-
};
|
|
802
|
-
};
|
|
803
786
|
readonly "sam3-image-rle": {
|
|
804
787
|
readonly name: "SAM 3 Image RLE";
|
|
805
788
|
readonly endpoint: "fal-ai/sam-3/image-rle";
|
|
@@ -1180,23 +1163,6 @@ declare const FAL_TOOLS: {
|
|
|
1180
1163
|
readonly output_format: "png";
|
|
1181
1164
|
};
|
|
1182
1165
|
};
|
|
1183
|
-
readonly "sam3-1-image": {
|
|
1184
|
-
readonly name: "SAM 3.1 Image";
|
|
1185
|
-
readonly endpoint: "fal-ai/sam-3-1/image";
|
|
1186
|
-
readonly task: "promptable image segmentation";
|
|
1187
|
-
readonly category: "segmentation";
|
|
1188
|
-
readonly description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.";
|
|
1189
|
-
readonly inputKind: "image";
|
|
1190
|
-
readonly inputField: "image_url";
|
|
1191
|
-
readonly outputKeys: ["image", "masks", "metadata", "scores", "boxes"];
|
|
1192
|
-
readonly pricing: "$0.005/request";
|
|
1193
|
-
readonly sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image";
|
|
1194
|
-
readonly defaultOptions: {
|
|
1195
|
-
readonly apply_mask: true;
|
|
1196
|
-
readonly max_masks: 3;
|
|
1197
|
-
readonly output_format: "png";
|
|
1198
|
-
};
|
|
1199
|
-
};
|
|
1200
1166
|
readonly "sam3-image-rle": {
|
|
1201
1167
|
readonly name: "SAM 3 Image RLE";
|
|
1202
1168
|
readonly endpoint: "fal-ai/sam-3/image-rle";
|
package/dist/index.d.ts
CHANGED
|
@@ -783,23 +783,6 @@ declare class MotifServer {
|
|
|
783
783
|
readonly output_format: "png";
|
|
784
784
|
};
|
|
785
785
|
};
|
|
786
|
-
readonly "sam3-1-image": {
|
|
787
|
-
readonly name: "SAM 3.1 Image";
|
|
788
|
-
readonly endpoint: "fal-ai/sam-3-1/image";
|
|
789
|
-
readonly task: "promptable image segmentation";
|
|
790
|
-
readonly category: "segmentation";
|
|
791
|
-
readonly description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.";
|
|
792
|
-
readonly inputKind: "image";
|
|
793
|
-
readonly inputField: "image_url";
|
|
794
|
-
readonly outputKeys: ["image", "masks", "metadata", "scores", "boxes"];
|
|
795
|
-
readonly pricing: "$0.005/request";
|
|
796
|
-
readonly sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image";
|
|
797
|
-
readonly defaultOptions: {
|
|
798
|
-
readonly apply_mask: true;
|
|
799
|
-
readonly max_masks: 3;
|
|
800
|
-
readonly output_format: "png";
|
|
801
|
-
};
|
|
802
|
-
};
|
|
803
786
|
readonly "sam3-image-rle": {
|
|
804
787
|
readonly name: "SAM 3 Image RLE";
|
|
805
788
|
readonly endpoint: "fal-ai/sam-3/image-rle";
|
|
@@ -1180,23 +1163,6 @@ declare const FAL_TOOLS: {
|
|
|
1180
1163
|
readonly output_format: "png";
|
|
1181
1164
|
};
|
|
1182
1165
|
};
|
|
1183
|
-
readonly "sam3-1-image": {
|
|
1184
|
-
readonly name: "SAM 3.1 Image";
|
|
1185
|
-
readonly endpoint: "fal-ai/sam-3-1/image";
|
|
1186
|
-
readonly task: "promptable image segmentation";
|
|
1187
|
-
readonly category: "segmentation";
|
|
1188
|
-
readonly description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.";
|
|
1189
|
-
readonly inputKind: "image";
|
|
1190
|
-
readonly inputField: "image_url";
|
|
1191
|
-
readonly outputKeys: ["image", "masks", "metadata", "scores", "boxes"];
|
|
1192
|
-
readonly pricing: "$0.005/request";
|
|
1193
|
-
readonly sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image";
|
|
1194
|
-
readonly defaultOptions: {
|
|
1195
|
-
readonly apply_mask: true;
|
|
1196
|
-
readonly max_masks: 3;
|
|
1197
|
-
readonly output_format: "png";
|
|
1198
|
-
};
|
|
1199
|
-
};
|
|
1200
1166
|
readonly "sam3-image-rle": {
|
|
1201
1167
|
readonly name: "SAM 3 Image RLE";
|
|
1202
1168
|
readonly endpoint: "fal-ai/sam-3/image-rle";
|
package/dist/index.js
CHANGED
|
@@ -883,6 +883,10 @@ function estimateCost(model, resolution, numImages = 1) {
|
|
|
883
883
|
if ((model === "banana" || model === "gemini3") && resolution === "4K") {
|
|
884
884
|
return configuredPrice * 2 * numImages;
|
|
885
885
|
}
|
|
886
|
+
if (model === "banana2") {
|
|
887
|
+
const multiplier = resolution === "4K" ? 2 : resolution === "2K" ? 1.5 : resolution === "0.5K" ? 0.75 : 1;
|
|
888
|
+
return configuredPrice * multiplier * numImages;
|
|
889
|
+
}
|
|
886
890
|
return configuredPrice * numImages;
|
|
887
891
|
}
|
|
888
892
|
switch (model) {
|
|
@@ -2194,23 +2198,6 @@ var FAL_TOOLS = {
|
|
|
2194
2198
|
output_format: "png"
|
|
2195
2199
|
}
|
|
2196
2200
|
},
|
|
2197
|
-
"sam3-1-image": {
|
|
2198
|
-
name: "SAM 3.1 Image",
|
|
2199
|
-
endpoint: "fal-ai/sam-3-1/image",
|
|
2200
|
-
task: "promptable image segmentation",
|
|
2201
|
-
category: "segmentation",
|
|
2202
|
-
description: "Segment image objects with text, point, or box prompts. SAM 3.1 adds Object Multiplex for faster multi-object tracking.",
|
|
2203
|
-
inputKind: "image",
|
|
2204
|
-
inputField: "image_url",
|
|
2205
|
-
outputKeys: ["image", "masks", "metadata", "scores", "boxes"],
|
|
2206
|
-
pricing: "$0.005/request",
|
|
2207
|
-
sourceUrl: "https://fal.ai/models/fal-ai/sam-3-1/image",
|
|
2208
|
-
defaultOptions: {
|
|
2209
|
-
apply_mask: true,
|
|
2210
|
-
max_masks: 3,
|
|
2211
|
-
output_format: "png"
|
|
2212
|
-
}
|
|
2213
|
-
},
|
|
2214
2201
|
"sam3-image-rle": {
|
|
2215
2202
|
name: "SAM 3 Image RLE",
|
|
2216
2203
|
endpoint: "fal-ai/sam-3/image-rle",
|
|
@@ -2394,7 +2381,13 @@ var MotifServer = class {
|
|
|
2394
2381
|
if (config?.useQueue) {
|
|
2395
2382
|
return this.generateQueued(options);
|
|
2396
2383
|
}
|
|
2397
|
-
|
|
2384
|
+
let built;
|
|
2385
|
+
try {
|
|
2386
|
+
built = buildGenerateBody(options);
|
|
2387
|
+
} catch (error) {
|
|
2388
|
+
return err(toMotifError(error));
|
|
2389
|
+
}
|
|
2390
|
+
const { endpoint, body } = built;
|
|
2398
2391
|
const response = await this.request(`${FAL_BASE_URL}/${endpoint}`, {
|
|
2399
2392
|
method: "POST",
|
|
2400
2393
|
body: JSON.stringify(body),
|
|
@@ -2436,7 +2429,13 @@ var MotifServer = class {
|
|
|
2436
2429
|
/** ─── Queue-Based Generation ──────────────────────────────── */
|
|
2437
2430
|
/** Submit a generation to the fal.ai queue (returns immediately). */
|
|
2438
2431
|
async submitGeneration(options) {
|
|
2439
|
-
|
|
2432
|
+
let built;
|
|
2433
|
+
try {
|
|
2434
|
+
built = buildGenerateBody(options);
|
|
2435
|
+
} catch (error) {
|
|
2436
|
+
return err(toMotifError(error));
|
|
2437
|
+
}
|
|
2438
|
+
const { endpoint, body } = built;
|
|
2440
2439
|
const response = await this.request(`${FAL_QUEUE_URL}/${endpoint}`, {
|
|
2441
2440
|
method: "POST",
|
|
2442
2441
|
body: JSON.stringify(body),
|
|
@@ -2836,6 +2835,14 @@ var MotifError = class extends Error {
|
|
|
2836
2835
|
this.code = code;
|
|
2837
2836
|
}
|
|
2838
2837
|
};
|
|
2838
|
+
function toMotifError(error) {
|
|
2839
|
+
if (error instanceof MotifError) {
|
|
2840
|
+
return error;
|
|
2841
|
+
}
|
|
2842
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2843
|
+
const code = error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
2844
|
+
return new MotifError(message, 0, code);
|
|
2845
|
+
}
|
|
2839
2846
|
export {
|
|
2840
2847
|
ASPECT_RATIOS,
|
|
2841
2848
|
CREATIVE_FIELDS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@howells/motif-sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Public Node SDK for Motif fal.ai generation, editing, utility tools, and model metadata.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Daniel Howells",
|
|
@@ -37,17 +37,6 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"scripts": {
|
|
41
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
42
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
43
|
-
"lint": "howells-lint",
|
|
44
|
-
"format": "howells-format",
|
|
45
|
-
"typecheck": "tsc --noEmit",
|
|
46
|
-
"test": "vitest run",
|
|
47
|
-
"test:watch": "vitest",
|
|
48
|
-
"test:coverage": "vitest run --coverage",
|
|
49
|
-
"prepack": "pnpm build"
|
|
50
|
-
},
|
|
51
40
|
"dependencies": {
|
|
52
41
|
"@howells/envy": "^0.3.7",
|
|
53
42
|
"neverthrow": "^8.2.0",
|
|
@@ -61,5 +50,15 @@
|
|
|
61
50
|
"tsup": "^8.0.0",
|
|
62
51
|
"typescript": "^6.0.3",
|
|
63
52
|
"vitest": "^4.1.5"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
56
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
57
|
+
"lint": "howells-lint",
|
|
58
|
+
"format": "howells-format",
|
|
59
|
+
"typecheck": "tsc --noEmit",
|
|
60
|
+
"test": "vitest run",
|
|
61
|
+
"test:watch": "vitest",
|
|
62
|
+
"test:coverage": "vitest run --coverage"
|
|
64
63
|
}
|
|
65
|
-
}
|
|
64
|
+
}
|