@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/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
- //#region src/aspects.ts
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
4531
- //#region src/image-benchmarks.ts
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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
- //#endregion
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 };