@howells/motif-sdk 7.0.0 → 7.1.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 +1 -1
- package/dist/image.d.ts +17 -22
- package/dist/image.js +17 -34
- package/dist/index.cjs +39 -64
- package/dist/index.d.cts +17 -26
- package/dist/index.d.ts +17 -26
- package/dist/index.js +39 -64
- package/dist/registry.d.ts +5 -12
- package/dist/registry.js +9 -18
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Motif SDK: task-first image work over fal.ai.
|
|
3
|
+
*
|
|
4
|
+
* Callers name a task and a tier; Motif picks the model. The per-model registry
|
|
5
|
+
* and the fal client stay internal.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createMotif } from "@howells/motif-sdk";
|
|
10
|
+
*
|
|
11
|
+
* const motif = createMotif();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
1
14
|
import { Result, Result as Result$1, ResultAsync, err, ok } from "neverthrow";
|
|
2
15
|
import { z } from "zod";
|
|
3
|
-
//#region src/creative.d.ts
|
|
4
16
|
/**
|
|
5
17
|
* Creative direction fields applied to prompts in Motif's canonical order.
|
|
6
18
|
*
|
|
@@ -241,8 +253,6 @@ export declare function validateCreativeDirection(creative: CreativeDirection |
|
|
|
241
253
|
* are joined with `". "` and closed with a period. With no clauses the sanitized prompt is returned unchanged.
|
|
242
254
|
*/
|
|
243
255
|
export declare function enrichPrompt(options: EnrichPromptOptions): CreativePromptResult;
|
|
244
|
-
//#endregion
|
|
245
|
-
//#region src/types.d.ts
|
|
246
256
|
/** ─── Model Types ─────────────────────────────────────────────── */
|
|
247
257
|
type AspectRatio = "auto" | "8:1" | "4:1" | "21:9" | "16:9" | "3:2" | "4:3" | "5:4" | "1:1" | "4:5" | "3:4" | "2:3" | "9:16" | "1:4" | "1:8";
|
|
248
258
|
type Resolution = "0.5K" | "1K" | "2K" | "4K";
|
|
@@ -275,8 +285,6 @@ interface JobStatus {
|
|
|
275
285
|
/** ─── Configuration ──────────────────────────────────────────── */
|
|
276
286
|
/** The network seam: a `fetch`-shaped function. */
|
|
277
287
|
type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
278
|
-
//#endregion
|
|
279
|
-
//#region src/aspects.d.ts
|
|
280
288
|
/** Ordered by popularity: square first, then common ratios */
|
|
281
289
|
export declare const ASPECT_RATIOS: AspectRatio[];
|
|
282
290
|
export declare const RESOLUTIONS: Resolution[];
|
|
@@ -296,8 +304,6 @@ export declare const FORMAT_PRESETS: Record<string, {
|
|
|
296
304
|
aspect: AspectRatio;
|
|
297
305
|
resolution?: Resolution;
|
|
298
306
|
}>;
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region src/errors.d.ts
|
|
301
307
|
/**
|
|
302
308
|
* `MotifError` and its coercion helper.
|
|
303
309
|
*
|
|
@@ -325,8 +331,6 @@ export declare const ACCOUNT_LOCKED = "ACCOUNT_LOCKED";
|
|
|
325
331
|
* account has run out of credit. Retrying cannot help, and the key is valid.
|
|
326
332
|
*/
|
|
327
333
|
export declare function isFalAccountLocked(status: number, body: string): boolean;
|
|
328
|
-
//#endregion
|
|
329
|
-
//#region src/image-benchmarks.d.ts
|
|
330
334
|
/**
|
|
331
335
|
* Arena image scores captured for MOT-72 on October 29, 2026. Flare and
|
|
332
336
|
* Sunburst route to GPT Image 2.6 but keep 2.5's scores until 2.6 is
|
|
@@ -340,6 +344,8 @@ interface ArenaScore {
|
|
|
340
344
|
readonly uncertainty: number;
|
|
341
345
|
/** Exact leaderboard label, including a setting where one was reported. */
|
|
342
346
|
readonly evaluatedModel: string;
|
|
347
|
+
/** Set when the score was measured on a different version than Motif runs. */
|
|
348
|
+
readonly note?: string;
|
|
343
349
|
readonly preliminary?: true;
|
|
344
350
|
readonly votes?: number;
|
|
345
351
|
}
|
|
@@ -349,8 +355,6 @@ interface ImageModelBenchmark extends ArenaScore {
|
|
|
349
355
|
readonly snapshotDate: string;
|
|
350
356
|
readonly task: ImageBenchmarkTask;
|
|
351
357
|
}
|
|
352
|
-
//#endregion
|
|
353
|
-
//#region src/tasks.d.ts
|
|
354
358
|
export declare const TIERS: readonly ["fast", "balanced", "quality"];
|
|
355
359
|
/** How far a Task trades cost and speed for quality. */
|
|
356
360
|
type Tier = (typeof TIERS)[number];
|
|
@@ -958,8 +962,6 @@ export declare const TASKS: {
|
|
|
958
962
|
type TaskId = keyof typeof TASKS;
|
|
959
963
|
export declare const TASK_IDS: readonly TaskId[];
|
|
960
964
|
export declare function isTaskId(value: string): value is TaskId;
|
|
961
|
-
//#endregion
|
|
962
|
-
//#region src/resolve.d.ts
|
|
963
965
|
/** What the request needs. Only the fields that narrow the choice. */
|
|
964
966
|
interface TaskRequest {
|
|
965
967
|
/** Explicit Model id, e.g. from `--model`. Overrides everything. */
|
|
@@ -1029,6 +1031,8 @@ interface TaskUnresolved {
|
|
|
1029
1031
|
}
|
|
1030
1032
|
type TaskResolution = TaskResolved | TaskUnresolved;
|
|
1031
1033
|
interface ModelProfile {
|
|
1034
|
+
/** The Model's display name, e.g. "GPT Image 2.6 Sunburst". */
|
|
1035
|
+
readonly name: string;
|
|
1032
1036
|
readonly capabilities: ReadonlySet<Capability>;
|
|
1033
1037
|
/** Key variables the Model needs for any request. */
|
|
1034
1038
|
readonly keys: readonly string[];
|
|
@@ -1059,8 +1063,6 @@ export declare function resolveTask(task: TaskId, request: TaskRequest, environm
|
|
|
1059
1063
|
* nothing there.
|
|
1060
1064
|
*/
|
|
1061
1065
|
export declare function tierChangesChoice(task: TaskId, request: Omit<TaskRequest, "tier">, environment: TaskEnvironment): boolean;
|
|
1062
|
-
//#endregion
|
|
1063
|
-
//#region src/task-stream.d.ts
|
|
1064
1066
|
interface TaskStreamOptions {
|
|
1065
1067
|
signal?: AbortSignal;
|
|
1066
1068
|
/** Overall deadline covering connection and consumption, in milliseconds. */
|
|
@@ -1091,8 +1093,6 @@ interface TaskStream {
|
|
|
1091
1093
|
/** Stops local consumption; does not guarantee provider cancellation or refund. */
|
|
1092
1094
|
abort: () => void;
|
|
1093
1095
|
}
|
|
1094
|
-
//#endregion
|
|
1095
|
-
//#region src/tool-cost.d.ts
|
|
1096
1096
|
/** Pixel dimensions of one file an endpoint returned. */
|
|
1097
1097
|
interface OutputDimensions {
|
|
1098
1098
|
height?: number;
|
|
@@ -1133,8 +1133,6 @@ export declare function sumCosts(costs: readonly (number | null)[]): {
|
|
|
1133
1133
|
known: number;
|
|
1134
1134
|
unknown: number;
|
|
1135
1135
|
};
|
|
1136
|
-
//#endregion
|
|
1137
|
-
//#region src/task-client.d.ts
|
|
1138
1136
|
interface MotifClientConfig {
|
|
1139
1137
|
/** Falls back to FAL_KEY. */
|
|
1140
1138
|
falKey?: string;
|
|
@@ -1309,11 +1307,7 @@ interface MotifClient {
|
|
|
1309
1307
|
}
|
|
1310
1308
|
/** Create the Task client. The key falls back to FAL_KEY. */
|
|
1311
1309
|
export declare function createMotif(config?: MotifClientConfig): MotifClient;
|
|
1312
|
-
//#endregion
|
|
1313
|
-
//#region src/task-plan-shared.d.ts
|
|
1314
1310
|
export declare const INVALID_OPTION = "INVALID_OPTION";
|
|
1315
|
-
//#endregion
|
|
1316
|
-
//#region src/prompt-warnings.d.ts
|
|
1317
1311
|
/**
|
|
1318
1312
|
* Advisory checks on a user-written prompt.
|
|
1319
1313
|
*
|
|
@@ -1348,8 +1342,6 @@ interface PromptWarning {
|
|
|
1348
1342
|
export declare function promptWarnings(prompt: string, context?: {
|
|
1349
1343
|
editing?: boolean;
|
|
1350
1344
|
}): PromptWarning[];
|
|
1351
|
-
//#endregion
|
|
1352
|
-
//#region src/env.d.ts
|
|
1353
1345
|
export declare const motifEnvSchema: import("@howells/envy").EnvSchema<{
|
|
1354
1346
|
readonly optional: {
|
|
1355
1347
|
FAL_KEY: z.ZodString;
|
|
@@ -1358,5 +1350,4 @@ export declare const motifEnvSchema: import("@howells/envy").EnvSchema<{
|
|
|
1358
1350
|
type MotifEnv = ReturnType<typeof motifEnvSchema.parse>;
|
|
1359
1351
|
export declare function parseMotifEnv(input?: Record<string, unknown>): MotifEnv;
|
|
1360
1352
|
export declare function getFalKeyFromEnv(input?: Record<string, unknown>): string | undefined;
|
|
1361
|
-
//#endregion
|
|
1362
1353
|
export { type AspectRatio, type Blocker, type Capability, type ChosenBy, type CreativeDirection, type CreativeField, type CreativeOption, type CreativeOptionErrorDetails, type CreativePromptResult, type CustomImageSize, type EnrichPromptOptions, type FalFetch, type ImageSizeBounds, type LookId, type LookOption, type ModelProfile, type MoodId, type MotifClient, type MotifClientConfig, type MotifEnv, type OutputDimensions, type PlanOptions, type PromptWarning, type PromptWarningRule, type RankedFrom, type RankedModel, type Resolution, type ResolvedCost, type Result, type ResultAsync, type TaskDefinition, type TaskEnvironment, type TaskFile, type TaskFunction, type TaskId, type TaskInput, type TaskMode, type TaskOutput, type TaskPlan, type TaskRequest, type TaskResolution, type TaskResolved, type TaskStream, type TaskStreamEvent, type TaskStreamOptions, type TaskUnresolved, type Tier, type Unblocker, err, ok };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Motif SDK: task-first image work over fal.ai.
|
|
3
|
+
*
|
|
4
|
+
* Callers name a task and a tier; Motif picks the model. The per-model registry
|
|
5
|
+
* and the fal client stay internal.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createMotif } from "@howells/motif-sdk";
|
|
10
|
+
*
|
|
11
|
+
* const motif = createMotif();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
1
14
|
import { Result, Result as Result$1, ResultAsync, err, ok } from "neverthrow";
|
|
2
15
|
import { z } from "zod";
|
|
3
|
-
//#region src/creative.d.ts
|
|
4
16
|
/**
|
|
5
17
|
* Creative direction fields applied to prompts in Motif's canonical order.
|
|
6
18
|
*
|
|
@@ -241,8 +253,6 @@ export declare function validateCreativeDirection(creative: CreativeDirection |
|
|
|
241
253
|
* are joined with `". "` and closed with a period. With no clauses the sanitized prompt is returned unchanged.
|
|
242
254
|
*/
|
|
243
255
|
export declare function enrichPrompt(options: EnrichPromptOptions): CreativePromptResult;
|
|
244
|
-
//#endregion
|
|
245
|
-
//#region src/types.d.ts
|
|
246
256
|
/** ─── Model Types ─────────────────────────────────────────────── */
|
|
247
257
|
type AspectRatio = "auto" | "8:1" | "4:1" | "21:9" | "16:9" | "3:2" | "4:3" | "5:4" | "1:1" | "4:5" | "3:4" | "2:3" | "9:16" | "1:4" | "1:8";
|
|
248
258
|
type Resolution = "0.5K" | "1K" | "2K" | "4K";
|
|
@@ -275,8 +285,6 @@ interface JobStatus {
|
|
|
275
285
|
/** ─── Configuration ──────────────────────────────────────────── */
|
|
276
286
|
/** The network seam: a `fetch`-shaped function. */
|
|
277
287
|
type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
278
|
-
//#endregion
|
|
279
|
-
//#region src/aspects.d.ts
|
|
280
288
|
/** Ordered by popularity: square first, then common ratios */
|
|
281
289
|
export declare const ASPECT_RATIOS: AspectRatio[];
|
|
282
290
|
export declare const RESOLUTIONS: Resolution[];
|
|
@@ -296,8 +304,6 @@ export declare const FORMAT_PRESETS: Record<string, {
|
|
|
296
304
|
aspect: AspectRatio;
|
|
297
305
|
resolution?: Resolution;
|
|
298
306
|
}>;
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region src/errors.d.ts
|
|
301
307
|
/**
|
|
302
308
|
* `MotifError` and its coercion helper.
|
|
303
309
|
*
|
|
@@ -325,8 +331,6 @@ export declare const ACCOUNT_LOCKED = "ACCOUNT_LOCKED";
|
|
|
325
331
|
* account has run out of credit. Retrying cannot help, and the key is valid.
|
|
326
332
|
*/
|
|
327
333
|
export declare function isFalAccountLocked(status: number, body: string): boolean;
|
|
328
|
-
//#endregion
|
|
329
|
-
//#region src/image-benchmarks.d.ts
|
|
330
334
|
/**
|
|
331
335
|
* Arena image scores captured for MOT-72 on October 29, 2026. Flare and
|
|
332
336
|
* Sunburst route to GPT Image 2.6 but keep 2.5's scores until 2.6 is
|
|
@@ -340,6 +344,8 @@ interface ArenaScore {
|
|
|
340
344
|
readonly uncertainty: number;
|
|
341
345
|
/** Exact leaderboard label, including a setting where one was reported. */
|
|
342
346
|
readonly evaluatedModel: string;
|
|
347
|
+
/** Set when the score was measured on a different version than Motif runs. */
|
|
348
|
+
readonly note?: string;
|
|
343
349
|
readonly preliminary?: true;
|
|
344
350
|
readonly votes?: number;
|
|
345
351
|
}
|
|
@@ -349,8 +355,6 @@ interface ImageModelBenchmark extends ArenaScore {
|
|
|
349
355
|
readonly snapshotDate: string;
|
|
350
356
|
readonly task: ImageBenchmarkTask;
|
|
351
357
|
}
|
|
352
|
-
//#endregion
|
|
353
|
-
//#region src/tasks.d.ts
|
|
354
358
|
export declare const TIERS: readonly ["fast", "balanced", "quality"];
|
|
355
359
|
/** How far a Task trades cost and speed for quality. */
|
|
356
360
|
type Tier = (typeof TIERS)[number];
|
|
@@ -958,8 +962,6 @@ export declare const TASKS: {
|
|
|
958
962
|
type TaskId = keyof typeof TASKS;
|
|
959
963
|
export declare const TASK_IDS: readonly TaskId[];
|
|
960
964
|
export declare function isTaskId(value: string): value is TaskId;
|
|
961
|
-
//#endregion
|
|
962
|
-
//#region src/resolve.d.ts
|
|
963
965
|
/** What the request needs. Only the fields that narrow the choice. */
|
|
964
966
|
interface TaskRequest {
|
|
965
967
|
/** Explicit Model id, e.g. from `--model`. Overrides everything. */
|
|
@@ -1029,6 +1031,8 @@ interface TaskUnresolved {
|
|
|
1029
1031
|
}
|
|
1030
1032
|
type TaskResolution = TaskResolved | TaskUnresolved;
|
|
1031
1033
|
interface ModelProfile {
|
|
1034
|
+
/** The Model's display name, e.g. "GPT Image 2.6 Sunburst". */
|
|
1035
|
+
readonly name: string;
|
|
1032
1036
|
readonly capabilities: ReadonlySet<Capability>;
|
|
1033
1037
|
/** Key variables the Model needs for any request. */
|
|
1034
1038
|
readonly keys: readonly string[];
|
|
@@ -1059,8 +1063,6 @@ export declare function resolveTask(task: TaskId, request: TaskRequest, environm
|
|
|
1059
1063
|
* nothing there.
|
|
1060
1064
|
*/
|
|
1061
1065
|
export declare function tierChangesChoice(task: TaskId, request: Omit<TaskRequest, "tier">, environment: TaskEnvironment): boolean;
|
|
1062
|
-
//#endregion
|
|
1063
|
-
//#region src/task-stream.d.ts
|
|
1064
1066
|
interface TaskStreamOptions {
|
|
1065
1067
|
signal?: AbortSignal;
|
|
1066
1068
|
/** Overall deadline covering connection and consumption, in milliseconds. */
|
|
@@ -1091,8 +1093,6 @@ interface TaskStream {
|
|
|
1091
1093
|
/** Stops local consumption; does not guarantee provider cancellation or refund. */
|
|
1092
1094
|
abort: () => void;
|
|
1093
1095
|
}
|
|
1094
|
-
//#endregion
|
|
1095
|
-
//#region src/tool-cost.d.ts
|
|
1096
1096
|
/** Pixel dimensions of one file an endpoint returned. */
|
|
1097
1097
|
interface OutputDimensions {
|
|
1098
1098
|
height?: number;
|
|
@@ -1133,8 +1133,6 @@ export declare function sumCosts(costs: readonly (number | null)[]): {
|
|
|
1133
1133
|
known: number;
|
|
1134
1134
|
unknown: number;
|
|
1135
1135
|
};
|
|
1136
|
-
//#endregion
|
|
1137
|
-
//#region src/task-client.d.ts
|
|
1138
1136
|
interface MotifClientConfig {
|
|
1139
1137
|
/** Falls back to FAL_KEY. */
|
|
1140
1138
|
falKey?: string;
|
|
@@ -1309,11 +1307,7 @@ interface MotifClient {
|
|
|
1309
1307
|
}
|
|
1310
1308
|
/** Create the Task client. The key falls back to FAL_KEY. */
|
|
1311
1309
|
export declare function createMotif(config?: MotifClientConfig): MotifClient;
|
|
1312
|
-
//#endregion
|
|
1313
|
-
//#region src/task-plan-shared.d.ts
|
|
1314
1310
|
export declare const INVALID_OPTION = "INVALID_OPTION";
|
|
1315
|
-
//#endregion
|
|
1316
|
-
//#region src/prompt-warnings.d.ts
|
|
1317
1311
|
/**
|
|
1318
1312
|
* Advisory checks on a user-written prompt.
|
|
1319
1313
|
*
|
|
@@ -1348,8 +1342,6 @@ interface PromptWarning {
|
|
|
1348
1342
|
export declare function promptWarnings(prompt: string, context?: {
|
|
1349
1343
|
editing?: boolean;
|
|
1350
1344
|
}): PromptWarning[];
|
|
1351
|
-
//#endregion
|
|
1352
|
-
//#region src/env.d.ts
|
|
1353
1345
|
export declare const motifEnvSchema: import("@howells/envy").EnvSchema<{
|
|
1354
1346
|
readonly optional: {
|
|
1355
1347
|
FAL_KEY: z.ZodString;
|
|
@@ -1358,5 +1350,4 @@ export declare const motifEnvSchema: import("@howells/envy").EnvSchema<{
|
|
|
1358
1350
|
type MotifEnv = ReturnType<typeof motifEnvSchema.parse>;
|
|
1359
1351
|
export declare function parseMotifEnv(input?: Record<string, unknown>): MotifEnv;
|
|
1360
1352
|
export declare function getFalKeyFromEnv(input?: Record<string, unknown>): string | undefined;
|
|
1361
|
-
//#endregion
|
|
1362
1353
|
export { type AspectRatio, type Blocker, type Capability, type ChosenBy, type CreativeDirection, type CreativeField, type CreativeOption, type CreativeOptionErrorDetails, type CreativePromptResult, type CustomImageSize, type EnrichPromptOptions, type FalFetch, type ImageSizeBounds, type LookId, type LookOption, type ModelProfile, type MoodId, type MotifClient, type MotifClientConfig, type MotifEnv, type OutputDimensions, type PlanOptions, type PromptWarning, type PromptWarningRule, type RankedFrom, type RankedModel, type Resolution, type ResolvedCost, type Result, type ResultAsync, type TaskDefinition, type TaskEnvironment, type TaskFile, type TaskFunction, type TaskId, type TaskInput, type TaskMode, type TaskOutput, type TaskPlan, type TaskRequest, type TaskResolution, type TaskResolved, type TaskStream, type TaskStreamEvent, type TaskStreamOptions, type TaskUnresolved, type Tier, type Unblocker, err, ok };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { err, err as err$1, ok, ok as ok$1 } from "neverthrow";
|
|
2
2
|
import { defineEnv } from "@howells/envy";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
|
|
4
|
+
// src/aspects.ts
|
|
5
5
|
/** Ordered by popularity: square first, then common ratios */
|
|
6
6
|
const ASPECT_RATIOS = [
|
|
7
7
|
"auto",
|
|
@@ -236,8 +236,7 @@ const FORMAT_PRESETS = {
|
|
|
236
236
|
label: "Wide"
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
|
-
|
|
240
|
-
//#region src/creative.ts
|
|
239
|
+
// src/creative.ts
|
|
241
240
|
const CONTROL_CHAR_REGEX = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
|
|
242
241
|
const TRAILING_PERIODS_REGEX = /\.+$/;
|
|
243
242
|
/**
|
|
@@ -479,8 +478,7 @@ function enrichPrompt(options) {
|
|
|
479
478
|
prompt: clauses.length ? joinSentences([basePrompt, ...clauses].filter((part) => part !== "")) : basePrompt
|
|
480
479
|
};
|
|
481
480
|
}
|
|
482
|
-
|
|
483
|
-
//#region src/errors.ts
|
|
481
|
+
// src/errors.ts
|
|
484
482
|
/**
|
|
485
483
|
* `MotifError` and its coercion helper.
|
|
486
484
|
*
|
|
@@ -537,8 +535,7 @@ function toMotifError(error) {
|
|
|
537
535
|
if (error instanceof MotifError) return error;
|
|
538
536
|
return new MotifError(error instanceof Error ? error.message : String(error), 0, error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0);
|
|
539
537
|
}
|
|
540
|
-
|
|
541
|
-
//#region src/task-plan-shared.ts
|
|
538
|
+
// src/task-plan-shared.ts
|
|
542
539
|
/**
|
|
543
540
|
* Helpers every request builder in the Task planner shares: refusing fields a
|
|
544
541
|
* Model can't carry, and merging `params` without letting them replace what
|
|
@@ -618,8 +615,7 @@ function mergeParams(body, params, owned) {
|
|
|
618
615
|
...params
|
|
619
616
|
});
|
|
620
617
|
}
|
|
621
|
-
|
|
622
|
-
//#region src/prompt-warnings.ts
|
|
618
|
+
// src/prompt-warnings.ts
|
|
623
619
|
const EDIT_VERB_REGEX = /^\s*(remove|erase|extend|outpaint)\b/i;
|
|
624
620
|
/** The CLI verb that does each edit directly, keyed by the prompt's first word. */
|
|
625
621
|
const EDIT_VERBS = {
|
|
@@ -685,8 +681,7 @@ function promptWarnings(prompt, context = {}) {
|
|
|
685
681
|
});
|
|
686
682
|
return warnings;
|
|
687
683
|
}
|
|
688
|
-
|
|
689
|
-
//#region src/env.ts
|
|
684
|
+
// src/env.ts
|
|
690
685
|
const motifEnvSchema = defineEnv({ optional: { FAL_KEY: z.string().min(1) } });
|
|
691
686
|
function parseMotifEnv(input = process.env) {
|
|
692
687
|
return motifEnvSchema.parse(input);
|
|
@@ -694,8 +689,7 @@ function parseMotifEnv(input = process.env) {
|
|
|
694
689
|
function getFalKeyFromEnv(input = process.env) {
|
|
695
690
|
return parseMotifEnv(input).FAL_KEY;
|
|
696
691
|
}
|
|
697
|
-
|
|
698
|
-
//#region src/models.ts
|
|
692
|
+
// src/models.ts
|
|
699
693
|
const AA_IMAGE_LEADERBOARD_SNAPSHOT = "2026-10-07";
|
|
700
694
|
const AA_IMAGE_SOURCES = ["https://artificialanalysis.ai/image/leaderboard/text-to-image", "https://artificialanalysis.ai/image/leaderboard/editing"];
|
|
701
695
|
const FAL_PRICING_CHECKED_AT = "2026-05-12";
|
|
@@ -1866,8 +1860,7 @@ const GENERATION_MODELS = [
|
|
|
1866
1860
|
"recraft41"
|
|
1867
1861
|
];
|
|
1868
1862
|
GENERATION_MODELS.filter((id) => MODELS[id]?.supportsEdit === true);
|
|
1869
|
-
|
|
1870
|
-
//#region src/cost.ts
|
|
1863
|
+
// src/cost.ts
|
|
1871
1864
|
/**
|
|
1872
1865
|
* Estimate cost based on model and settings. `editImages` is the number of
|
|
1873
1866
|
* input images on an edit, for Models whose edits cost more than generation.
|
|
@@ -1897,8 +1890,7 @@ function estimateVideoCost(durationSeconds = 5, generateAudio = true, model = "k
|
|
|
1897
1890
|
if (model === "kling-turbo") return .14 * durationSeconds;
|
|
1898
1891
|
return (generateAudio ? .168 : .112) * durationSeconds;
|
|
1899
1892
|
}
|
|
1900
|
-
|
|
1901
|
-
//#region src/fal-parse.ts
|
|
1893
|
+
// src/fal-parse.ts
|
|
1902
1894
|
/**
|
|
1903
1895
|
* Boundary parsing for fal.ai HTTP responses.
|
|
1904
1896
|
*
|
|
@@ -2003,8 +1995,7 @@ function requestIdFromBody(text) {
|
|
|
2003
1995
|
if (!isRecord$1(parsed)) return;
|
|
2004
1996
|
return asString(parsed.request_id) ?? asString(parsed.requestId) ?? asString(parsed.trace_id);
|
|
2005
1997
|
}
|
|
2006
|
-
|
|
2007
|
-
//#region src/capabilities.ts
|
|
1998
|
+
// src/capabilities.ts
|
|
2008
1999
|
/**
|
|
2009
2000
|
* Which generation options each model accepts, derived from the registry.
|
|
2010
2001
|
*
|
|
@@ -2094,8 +2085,7 @@ var UnsupportedOptionError = class extends Error {
|
|
|
2094
2085
|
this.supportedOptions = supported;
|
|
2095
2086
|
}
|
|
2096
2087
|
};
|
|
2097
|
-
|
|
2098
|
-
//#region src/generate.ts
|
|
2088
|
+
// src/generate.ts
|
|
2099
2089
|
const GPT_IMAGE_SIZES = [
|
|
2100
2090
|
"auto",
|
|
2101
2091
|
"1024x1024",
|
|
@@ -2290,8 +2280,7 @@ function buildGenerateBody(options) {
|
|
|
2290
2280
|
endpoint
|
|
2291
2281
|
};
|
|
2292
2282
|
}
|
|
2293
|
-
|
|
2294
|
-
//#region src/tool-registry/analysis.ts
|
|
2283
|
+
// src/tool-registry/analysis.ts
|
|
2295
2284
|
const ANALYSIS_TOOLS = {
|
|
2296
2285
|
"got-ocr": {
|
|
2297
2286
|
category: "analysis",
|
|
@@ -2405,8 +2394,7 @@ const ANALYSIS_TOOLS = {
|
|
|
2405
2394
|
task: "vision moderation"
|
|
2406
2395
|
}
|
|
2407
2396
|
};
|
|
2408
|
-
|
|
2409
|
-
//#region src/tool-registry/assets.ts
|
|
2397
|
+
// src/tool-registry/assets.ts
|
|
2410
2398
|
const ASSET_TOOLS = {
|
|
2411
2399
|
"hunyuan3d-v3": {
|
|
2412
2400
|
category: "3d",
|
|
@@ -2724,8 +2712,7 @@ const ASSET_TOOLS = {
|
|
|
2724
2712
|
task: "single-image 3D reconstruction"
|
|
2725
2713
|
}
|
|
2726
2714
|
};
|
|
2727
|
-
|
|
2728
|
-
//#region src/tool-registry/background.ts
|
|
2715
|
+
// src/tool-registry/background.ts
|
|
2729
2716
|
const BACKGROUND_TOOLS = {
|
|
2730
2717
|
"ben-v2": {
|
|
2731
2718
|
category: "background",
|
|
@@ -3100,8 +3087,7 @@ const BACKGROUND_TOOLS = {
|
|
|
3100
3087
|
task: "video enhancement"
|
|
3101
3088
|
}
|
|
3102
3089
|
};
|
|
3103
|
-
|
|
3104
|
-
//#region src/tool-registry/editing.ts
|
|
3090
|
+
// src/tool-registry/editing.ts
|
|
3105
3091
|
const EDITING_TOOLS = {
|
|
3106
3092
|
"bria-eraser": {
|
|
3107
3093
|
category: "erase",
|
|
@@ -3372,8 +3358,7 @@ const EDITING_TOOLS = {
|
|
|
3372
3358
|
task: "virtual garment try-on"
|
|
3373
3359
|
}
|
|
3374
3360
|
};
|
|
3375
|
-
|
|
3376
|
-
//#region src/tool-registry/structure.ts
|
|
3361
|
+
// src/tool-registry/structure.ts
|
|
3377
3362
|
const STRUCTURE_TOOLS = {
|
|
3378
3363
|
"depth-anything": {
|
|
3379
3364
|
category: "preprocess",
|
|
@@ -3765,8 +3750,7 @@ const STRUCTURE_TOOLS = {
|
|
|
3765
3750
|
task: "depth preprocessing"
|
|
3766
3751
|
}
|
|
3767
3752
|
};
|
|
3768
|
-
|
|
3769
|
-
//#region src/tools.ts
|
|
3753
|
+
// src/tools.ts
|
|
3770
3754
|
const FAL_TOOLS = {
|
|
3771
3755
|
...ANALYSIS_TOOLS,
|
|
3772
3756
|
...ASSET_TOOLS,
|
|
@@ -3794,8 +3778,7 @@ function buildFalToolRequest(options) {
|
|
|
3794
3778
|
tool
|
|
3795
3779
|
};
|
|
3796
3780
|
}
|
|
3797
|
-
|
|
3798
|
-
//#region src/server-tools.ts
|
|
3781
|
+
// src/server-tools.ts
|
|
3799
3782
|
/**
|
|
3800
3783
|
* Tool execution bodies for `FalClient`, both synchronous and queued.
|
|
3801
3784
|
*
|
|
@@ -3925,8 +3908,7 @@ async function runToolQueued(exec, options, onProgress) {
|
|
|
3925
3908
|
if (request.isErr()) return err$1(request.error);
|
|
3926
3909
|
return (await runRequestQueued(exec, request.value, onProgress)).map(({ data }) => data);
|
|
3927
3910
|
}
|
|
3928
|
-
|
|
3929
|
-
//#region src/server.ts
|
|
3911
|
+
// src/server.ts
|
|
3930
3912
|
const FAL_BASE_URL = "https://fal.run";
|
|
3931
3913
|
const FAL_QUEUE_URL = "https://queue.fal.run";
|
|
3932
3914
|
const FAL_API_URL = "https://api.fal.ai";
|
|
@@ -4243,8 +4225,7 @@ var FalClient = class {
|
|
|
4243
4225
|
});
|
|
4244
4226
|
}
|
|
4245
4227
|
};
|
|
4246
|
-
|
|
4247
|
-
//#region src/source-size.ts
|
|
4228
|
+
// src/source-size.ts
|
|
4248
4229
|
const DATA_URL_REGEX = /^data:[^;,]*;base64,(.*)$/s;
|
|
4249
4230
|
function decodeBase64(data) {
|
|
4250
4231
|
try {
|
|
@@ -4342,8 +4323,7 @@ function dataUrlImageSize(url) {
|
|
|
4342
4323
|
const size = pngSize(bytes) ?? jpegSize(bytes) ?? webpSize(bytes);
|
|
4343
4324
|
return size !== void 0 && size.width > 0 && size.height > 0 ? size : void 0;
|
|
4344
4325
|
}
|
|
4345
|
-
|
|
4346
|
-
//#region src/tool-cost.ts
|
|
4326
|
+
// src/tool-cost.ts
|
|
4347
4327
|
/**
|
|
4348
4328
|
* What a tool run costs, before it happens and after.
|
|
4349
4329
|
*
|
|
@@ -4527,8 +4507,8 @@ function sumCosts(costs) {
|
|
|
4527
4507
|
unknown
|
|
4528
4508
|
};
|
|
4529
4509
|
}
|
|
4530
|
-
|
|
4531
|
-
|
|
4510
|
+
// src/image-benchmarks.ts
|
|
4511
|
+
const MEASURED_ON_2_5 = "Measured on GPT Image 2.5. Motif runs GPT Image 2.6, which Arena has not scored yet.";
|
|
4532
4512
|
const BOARDS = {
|
|
4533
4513
|
"text-to-image": {
|
|
4534
4514
|
sunburst: {
|
|
@@ -4536,6 +4516,7 @@ const BOARDS = {
|
|
|
4536
4516
|
rank: 1,
|
|
4537
4517
|
uncertainty: 5,
|
|
4538
4518
|
evaluatedModel: "GPT-Image-2.5 Sunburst",
|
|
4519
|
+
note: MEASURED_ON_2_5,
|
|
4539
4520
|
preliminary: true,
|
|
4540
4521
|
votes: 40323
|
|
4541
4522
|
},
|
|
@@ -4544,6 +4525,7 @@ const BOARDS = {
|
|
|
4544
4525
|
rank: 2,
|
|
4545
4526
|
uncertainty: 5,
|
|
4546
4527
|
evaluatedModel: "GPT-Image-2.5 Flare",
|
|
4528
|
+
note: MEASURED_ON_2_5,
|
|
4547
4529
|
preliminary: true,
|
|
4548
4530
|
votes: 39218
|
|
4549
4531
|
},
|
|
@@ -4633,6 +4615,7 @@ const BOARDS = {
|
|
|
4633
4615
|
rank: 1,
|
|
4634
4616
|
uncertainty: 5,
|
|
4635
4617
|
evaluatedModel: "GPT-Image-2.5 Sunburst",
|
|
4618
|
+
note: MEASURED_ON_2_5,
|
|
4636
4619
|
preliminary: true
|
|
4637
4620
|
},
|
|
4638
4621
|
flare: {
|
|
@@ -4640,6 +4623,7 @@ const BOARDS = {
|
|
|
4640
4623
|
rank: 2,
|
|
4641
4624
|
uncertainty: 5,
|
|
4642
4625
|
evaluatedModel: "GPT-Image-2.5 Flare",
|
|
4626
|
+
note: MEASURED_ON_2_5,
|
|
4643
4627
|
preliminary: true
|
|
4644
4628
|
},
|
|
4645
4629
|
"grok-image-2": {
|
|
@@ -4709,8 +4693,7 @@ function imageModelBenchmark(model, task) {
|
|
|
4709
4693
|
task
|
|
4710
4694
|
};
|
|
4711
4695
|
}
|
|
4712
|
-
|
|
4713
|
-
//#region src/tasks.ts
|
|
4696
|
+
// src/tasks.ts
|
|
4714
4697
|
/**
|
|
4715
4698
|
* The Task registry: every job Motif does, with the Models that can do it
|
|
4716
4699
|
* ranked best-first and tagged with the Tier each belongs to.
|
|
@@ -5587,8 +5570,7 @@ const TASK_IDS = Object.keys(TASKS).filter(isTaskId);
|
|
|
5587
5570
|
function isTaskId(value) {
|
|
5588
5571
|
return Object.hasOwn(TASKS, value);
|
|
5589
5572
|
}
|
|
5590
|
-
|
|
5591
|
-
//#region src/tool-parameters.generated.ts
|
|
5573
|
+
// src/tool-parameters.generated.ts
|
|
5592
5574
|
const FAL_TOOL_PARAMETERS = {
|
|
5593
5575
|
"ben-v2": [{
|
|
5594
5576
|
key: "seed",
|
|
@@ -7745,8 +7727,7 @@ const FAL_TOOL_PARAMETERS = {
|
|
|
7745
7727
|
function falToolParameters(tool) {
|
|
7746
7728
|
return FAL_TOOL_PARAMETERS[tool] ?? [];
|
|
7747
7729
|
}
|
|
7748
|
-
|
|
7749
|
-
//#region src/resolve.ts
|
|
7730
|
+
// src/resolve.ts
|
|
7750
7731
|
/**
|
|
7751
7732
|
* Model choice: the one place a Model is chosen, for the CLI and the SDK.
|
|
7752
7733
|
*
|
|
@@ -7781,6 +7762,7 @@ function generationProfile(config) {
|
|
|
7781
7762
|
if (config.supportsNegativePrompt === true) capabilities.add("negativePrompt");
|
|
7782
7763
|
if (config.supportsOutputFormat === true) capabilities.add("outputFormat");
|
|
7783
7764
|
return {
|
|
7765
|
+
name: config.name,
|
|
7784
7766
|
aspects: config.supportedAspects,
|
|
7785
7767
|
capabilities,
|
|
7786
7768
|
keys: [FAL_KEY],
|
|
@@ -7814,6 +7796,7 @@ function toolProfile(tool) {
|
|
|
7814
7796
|
const takesReference = "referenceField" in config;
|
|
7815
7797
|
if (takesReference) capabilities.add("references");
|
|
7816
7798
|
return {
|
|
7799
|
+
name: config.name,
|
|
7817
7800
|
capabilities,
|
|
7818
7801
|
keys: [FAL_KEY],
|
|
7819
7802
|
maxReferences: takesReference ? 1 : 0
|
|
@@ -8054,8 +8037,7 @@ function tierChangesChoice(task, request, environment) {
|
|
|
8054
8037
|
}
|
|
8055
8038
|
return chosen.size > 1;
|
|
8056
8039
|
}
|
|
8057
|
-
|
|
8058
|
-
//#region src/task-output.ts
|
|
8040
|
+
// src/task-output.ts
|
|
8059
8041
|
function isPlainRecord(value) {
|
|
8060
8042
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8061
8043
|
}
|
|
@@ -8180,8 +8162,7 @@ function labelUrls(urls, labels) {
|
|
|
8180
8162
|
return names !== void 0 && names.length === totals.get(key) ? names[occurrence] : void 0;
|
|
8181
8163
|
});
|
|
8182
8164
|
}
|
|
8183
|
-
|
|
8184
|
-
//#region src/task-plan-pricing.ts
|
|
8165
|
+
// src/task-plan-pricing.ts
|
|
8185
8166
|
/**
|
|
8186
8167
|
* What a generation request bills and which body keys the caller owns. Both
|
|
8187
8168
|
* read the body as sent, `params` included, because fal bills that body.
|
|
@@ -8260,8 +8241,7 @@ function checkParamsImageSize(config, model, task, params) {
|
|
|
8260
8241
|
task
|
|
8261
8242
|
});
|
|
8262
8243
|
}
|
|
8263
|
-
|
|
8264
|
-
//#region src/task-plan-tools.ts
|
|
8244
|
+
// src/task-plan-tools.ts
|
|
8265
8245
|
/**
|
|
8266
8246
|
* Request bodies for fal tool Models: map each TaskInput field onto the key
|
|
8267
8247
|
* the tool's generated parameter list names, refuse what it doesn't list, and
|
|
@@ -8610,8 +8590,7 @@ function toolPlan(task, model, input) {
|
|
|
8610
8590
|
queued: "queued" in tool
|
|
8611
8591
|
});
|
|
8612
8592
|
}
|
|
8613
|
-
|
|
8614
|
-
//#region src/task-plan-video.ts
|
|
8593
|
+
// src/task-plan-video.ts
|
|
8615
8594
|
/**
|
|
8616
8595
|
* Request bodies for video Models: Kling v3 Pro and Kling v3 Turbo Pro, which
|
|
8617
8596
|
* take the start frame under different keys and bill by the second.
|
|
@@ -8692,8 +8671,7 @@ function turboVideoPlan(task, endpoint, input) {
|
|
|
8692
8671
|
queued: true
|
|
8693
8672
|
});
|
|
8694
8673
|
}
|
|
8695
|
-
|
|
8696
|
-
//#region src/task-plan.ts
|
|
8674
|
+
// src/task-plan.ts
|
|
8697
8675
|
/**
|
|
8698
8676
|
* `plan()` for the Task client: resolve the Model, build the request body the
|
|
8699
8677
|
* Model's kind needs, and price it. Pure: no I/O.
|
|
@@ -8994,8 +8972,7 @@ function upscalerPlan(task, model, input) {
|
|
|
8994
8972
|
queued: false
|
|
8995
8973
|
});
|
|
8996
8974
|
}
|
|
8997
|
-
|
|
8998
|
-
//#region src/task-stream.ts
|
|
8975
|
+
// src/task-stream.ts
|
|
8999
8976
|
const MAX_EVENT_CHARACTERS = 16777216;
|
|
9000
8977
|
const JSON_START = /^[[{]/;
|
|
9001
8978
|
function parsePayload(text) {
|
|
@@ -9274,8 +9251,7 @@ function createFrames(requestId) {
|
|
|
9274
9251
|
function enforceBufferLimit(length, requestId) {
|
|
9275
9252
|
if (length > MAX_EVENT_CHARACTERS) throw new MotifError("Stream event exceeds the buffer limit.", 0, "STREAM_EVENT_TOO_LARGE", requestId);
|
|
9276
9253
|
}
|
|
9277
|
-
|
|
9278
|
-
//#region src/task-client.ts
|
|
9254
|
+
// src/task-client.ts
|
|
9279
9255
|
/**
|
|
9280
9256
|
* The Task client: one function per Task. `createMotif()` returns a client
|
|
9281
9257
|
* whose `generate`, `erase`, `upscale` and the rest resolve the Model through
|
|
@@ -9451,5 +9427,4 @@ function createMotif(config = {}) {
|
|
|
9451
9427
|
}
|
|
9452
9428
|
};
|
|
9453
9429
|
}
|
|
9454
|
-
//#endregion
|
|
9455
9430
|
export { ACCOUNT_LOCKED, ASPECT_RATIOS, CREATIVE_FIELDS, CREATIVE_TAXONOMY, CreativeOptionError, DEFAULT_TIER, FORMAT_PRESETS, INVALID_OPTION, ImageSizeBoundsError, LOOKS, MotifError, NO_MODEL_AVAILABLE, RESOLUTIONS, TASKS, TASK_IDS, TIERS, createMotif, enrichPrompt, err, formatCost, getFalKeyFromEnv, getLook, isFalAccountLocked, isTaskId, modelProfile, motifEnvSchema, ok, parseMotifEnv, promptWarnings, resolveTask, sanitizePrompt, sumCosts, tierChangesChoice, validateCreativeDirection };
|