@howells/motif-sdk 4.0.0 → 5.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.
package/dist/index.d.cts CHANGED
@@ -34,7 +34,8 @@ interface CreativeOption {
34
34
  interface LookOption extends CreativeOption {
35
35
  /**
36
36
  * Whether a mood may be combined with this look. Flat looks (surfaces,
37
- * prints, paintings, studio objects) carry their own light and refuse one.
37
+ * paintings, illustrations, studio objects) carry their own light and
38
+ * refuse one.
38
39
  */
39
40
  acceptsMood: boolean;
40
41
  /** Default aspect ratio, e.g. `"3:2"`. */
@@ -70,10 +71,11 @@ export declare class CreativeOptionError extends Error implements CreativeOption
70
71
  /** Canonical creative field order used for prompt enrichment and schema output. */
71
72
  export declare const CREATIVE_FIELDS: readonly ["look", "mood"];
72
73
  /**
73
- * Built-in creative direction catalogue: twelve house looks and six light moods.
74
+ * Built-in creative direction catalogue: nine house looks and six light moods.
74
75
  *
75
76
  * Each option carries the exact prompt sentence appended when it is selected.
76
- * Looks also carry the aspect ratio and model they were tuned for.
77
+ * Looks also carry the aspect ratio and model they were tuned for. The five
78
+ * photographic looks come first, then the four flat ones.
77
79
  */
78
80
  export declare const CREATIVE_TAXONOMY: {
79
81
  readonly look: readonly [{
@@ -87,92 +89,68 @@ export declare const CREATIVE_TAXONOMY: {
87
89
  }, {
88
90
  readonly acceptsMood: true;
89
91
  readonly aspect: "1:1";
90
- readonly clause: "Editorial still life on a warm bone plaster ground, chalky unglazed surfaces, a long soft shadow, generous empty space, shot on film with fine grain. No text, no logos, no people";
91
- readonly description: "Objects and material samples on a plaster ground, for product and swatch shots.";
92
+ readonly clause: "Editorial still life in the register of Aesop and Kinfolk, on a warm bone plaster ground, chalky unglazed surfaces in muted mineral colour, a long soft shadow, generous empty space, shot on film with fine grain, restrained and materially rich. No text, no logos, no people";
93
+ readonly description: "Objects and products on a plaster ground, for product and editorial still life.";
92
94
  readonly id: "still-life";
93
- readonly label: "Material still life";
95
+ readonly label: "Editorial still life";
94
96
  readonly model: "flux2-pro";
95
97
  }, {
96
98
  readonly acceptsMood: true;
97
99
  readonly aspect: "3:2";
98
- readonly clause: "Interior photograph shot square-on at eye level on a 35mm lens, warm off-white plaster, wide oak floorboards, linen, brass and a little pattern, light, bright and layered, collected rather than styled, slightly imperfect and lived-in rather than showroom-perfect, photographic realism. No text, no logos, no people";
100
+ readonly clause: "Interior photograph in the register of House & Garden and Kinfolk, shot square-on at eye level on a 35mm lens, warm off-white plaster, wide oak floorboards, linen, brass and a little pattern, light, bright and layered, collected rather than styled, lived-in rather than showroom-perfect, soft natural daylight, shot on film with fine grain. No text, no logos, no people";
99
101
  readonly description: "Bright, collected rooms that feel lived in, for interior scenes.";
100
- readonly id: "lived-in";
101
- readonly label: "Lived-in interior";
102
+ readonly id: "interior";
103
+ readonly label: "Interior";
102
104
  readonly model: "flux2-pro";
103
105
  }, {
104
106
  readonly acceptsMood: true;
105
107
  readonly aspect: "4:5";
106
- readonly clause: "Architectural editorial photograph at full room scale, honest materials meeting precise detailing, one hero element genuinely installed, plausible light and shadow, generous negative space, empty of people. No text, no logos";
107
- readonly description: "Whole rooms with one product installed, for showing a material at scale.";
108
+ readonly clause: "Architectural photograph in the register of House & Garden and Kinfolk, a considered house seen from outside at editorial distance with its garden and setting, pale render, stone or timber meeting precise detailing, clipped planting, soft warm daylight and long shadow, generous negative space, immaculate and calm, shot on film with fine grain. No text, no logos, no people";
109
+ readonly description: "Buildings and their settings from outside, for architecture, property and place.";
108
110
  readonly id: "architectural";
109
- readonly label: "Architectural scale";
111
+ readonly label: "Architectural exterior";
110
112
  readonly model: "banana";
111
- }, {
112
- readonly acceptsMood: true;
113
- readonly aspect: "4:3";
114
- readonly clause: "Amateur phone photo of a real home taken by the homeowner, slightly wonky framing, unstyled domestic photography, ordinary exposure. No text, no people";
115
- readonly description: "Unstyled phone snapshots of real homes, for believable before and after shots.";
116
- readonly id: "homeowner";
117
- readonly label: "Homeowner snapshot";
118
- readonly model: "seedream45";
119
113
  }, {
120
114
  readonly acceptsMood: true;
121
115
  readonly aspect: "1:1";
122
- readonly clause: "Stylised architectural illustration of the room, colour laid as flat planes on walls, joinery and trim, fine hand-drawn line with a gentle gouache wash, clearly a drawing of a design decision rather than a photograph. No text, no people";
123
- readonly description: "Line and gouache room drawings, for showing a colour scheme as a design idea.";
124
- readonly experimental: true;
125
- readonly id: "drawing";
126
- readonly label: "Palette drawing";
127
- readonly model: "gpt2";
116
+ readonly clause: "Editorial documentary portrait in the register of Kinfolk, muted warm palette, waist-up and unposed against a plain plaster or linen ground, plain clothing with no logos, soft natural light, shot on film with fine grain. No text";
117
+ readonly description: "Natural, unposed documentary portraits of people. Pair with a mood for the light.";
118
+ readonly id: "portrait";
119
+ readonly label: "Documentary portrait";
120
+ readonly model: "seedream45";
128
121
  }, {
129
122
  readonly acceptsMood: false;
130
123
  readonly aspect: "1:1";
131
- readonly clause: "Straight-on orthographic photograph of the surface filling the entire frame edge to edge, even shadowless studio light, crisp macro texture, colour-accurate. No text, no logos";
132
- readonly description: "Flat, edge-to-edge surface photographs, for textures and material swatches.";
133
- readonly id: "plate";
134
- readonly label: "Flat plate";
124
+ readonly clause: "A single matte object centred with generous empty space, soft diffused studio light, minimal and quiet in the register of Aesop, one committed muted mineral colour on a plain ground. No text, no logos, no people";
125
+ readonly description: "One object in one colour on a clean ground, for icons and simple product shots.";
126
+ readonly id: "object";
127
+ readonly label: "Studio object";
135
128
  readonly model: "flux2-pro";
136
129
  }, {
137
130
  readonly acceptsMood: false;
138
131
  readonly aspect: "1:1";
139
- readonly clause: "Fine hand-engraved botanical plate with delicate hatching and dry brush, grey ink only, reaching near-black at its densest, on matte uncoated stock under flat even light, cropped mid-motif and running past all four edges, never simplified or cartoonish. No text";
140
- readonly description: "Grey-ink botanical engravings that run off the edges, for patterns and backgrounds.";
141
- readonly id: "engraved";
142
- readonly label: "Engraved grey ink";
143
- readonly model: "gpt2";
144
- }, {
145
- readonly acceptsMood: false;
146
- readonly aspect: "2:3";
147
- readonly clause: "Tightly cropped photograph of a single piece of late-1940s American printed matter, flat and square-on in even light, every pixel paper, letterpress and wood type, sun-faded ink, foxing, soft creases and thumbtack holes, era-correct typography, nothing that looks like a digital photo run through a filter";
148
- readonly description: "Aged mid-century printed matter such as posters and cards, where the lettering matters.";
149
- readonly id: "ephemera";
150
- readonly label: "Period ephemera";
151
- readonly model: "ideogram4";
132
+ readonly clause: "Straight-on orthographic photograph of the surface filling the entire frame edge to edge, even shadowless studio light, crisp macro texture, colour-accurate and quietly material. No text, no logos";
133
+ readonly description: "Flat, edge-to-edge surface photographs, for textures, backgrounds and material swatches.";
134
+ readonly id: "surface";
135
+ readonly label: "Flat surface";
136
+ readonly model: "flux2-pro";
152
137
  }, {
153
138
  readonly acceptsMood: false;
154
- readonly aspect: "3:4";
155
- readonly clause: "Physical mineral pigment and chalk gesso on coarse natural linen, two or three confident gestures, warm ivory, oatmeal, putty and soft charcoal, flat diffuse museum reproduction lighting, shown unframed. No text";
156
- readonly description: "Loose abstract paintings on linen, for wall art and calm backgrounds.";
157
- readonly id: "canvas";
158
- readonly label: "Linen abstract";
139
+ readonly aspect: "3:2";
140
+ readonly clause: "Painted abstraction filling the frame edge to edge, mineral pigment and chalk gesso on coarse natural linen, two or three confident gestures, warm ivory, oatmeal, putty and soft charcoal, flat diffuse reproduction light. No text";
141
+ readonly description: "Painted abstraction edge to edge, for wall art, heroes and calm backgrounds.";
142
+ readonly id: "abstract";
143
+ readonly label: "Painted abstract";
159
144
  readonly model: "banana";
160
- }, {
161
- readonly acceptsMood: true;
162
- readonly aspect: "1:1";
163
- readonly clause: "Editorial documentary portrait, muted warm palette, waist-up, unposed, plain clothing with no logos. No text";
164
- readonly description: "Natural, unposed documentary portraits of people. Pair with a mood for the light.";
165
- readonly id: "portrait";
166
- readonly label: "Documentary portrait";
167
- readonly model: "seedream45";
168
145
  }, {
169
146
  readonly acceptsMood: false;
170
147
  readonly aspect: "1:1";
171
- readonly clause: "A single matte object centred with generous empty space, soft diffused studio light, minimal and quiet, one committed colour. No text, no logos, no people";
172
- readonly description: "One object in one colour on a clean ground, for icons and simple product shots.";
173
- readonly id: "object";
174
- readonly label: "Studio object";
175
- readonly model: "flux2-pro";
148
+ readonly clause: "Stylised editorial illustration in the register of Kinfolk, colour laid as flat planes in a warm muted palette of ivory, putty, sage and charcoal, fine hand-drawn line with a gentle gouache wash, generous empty space, clearly a drawing rather than a photograph. No text, no logos";
149
+ readonly description: "Line and gouache illustration of any subject, for drawn editorial imagery.";
150
+ readonly experimental: true;
151
+ readonly id: "illustration";
152
+ readonly label: "Editorial illustration";
153
+ readonly model: "gpt2";
176
154
  }];
177
155
  readonly mood: readonly [{
178
156
  readonly clause: "soft natural daylight from a window out of frame, gentle falloff into the corners, low contrast, even diffused light with soft, held highlights";
@@ -208,7 +186,7 @@ export declare const CREATIVE_TAXONOMY: {
208
186
  };
209
187
  /** Every house look, in catalogue order. */
210
188
  export declare const LOOKS: readonly LookOption[];
211
- /** Stable id of a house look, e.g. `"lived-in"`. */
189
+ /** Stable id of a house look, e.g. `"interior"`. */
212
190
  type LookId = (typeof CREATIVE_TAXONOMY.look)[number]["id"];
213
191
  /** Stable id of a light mood, e.g. `"overcast"`. */
214
192
  type MoodId = (typeof CREATIVE_TAXONOMY.mood)[number]["id"];
@@ -284,6 +262,15 @@ interface ImageSizeBounds {
284
262
  /** Both edges must be multiples of this. Motif uses 16 when absent. */
285
263
  multipleOf?: number;
286
264
  }
265
+ interface JobStatus {
266
+ error?: string;
267
+ logs?: {
268
+ message: string;
269
+ timestamp: string;
270
+ }[];
271
+ queuePosition?: number;
272
+ status: "queued" | "processing" | "completed" | "failed";
273
+ }
287
274
  /** ─── Configuration ──────────────────────────────────────────── */
288
275
  /** The network seam: a `fetch`-shaped function. */
289
276
  type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
@@ -1057,6 +1044,38 @@ export declare function resolveTask(task: TaskId, request: TaskRequest, environm
1057
1044
  */
1058
1045
  export declare function tierChangesChoice(task: TaskId, request: Omit<TaskRequest, "tier">, environment: TaskEnvironment): boolean;
1059
1046
  //#endregion
1047
+ //#region src/task-stream.d.ts
1048
+ interface TaskStreamOptions {
1049
+ signal?: AbortSignal;
1050
+ /** Overall deadline covering connection and consumption, in milliseconds. */
1051
+ timeout?: number;
1052
+ }
1053
+ interface EventMetadata {
1054
+ event?: string;
1055
+ id?: string;
1056
+ }
1057
+ type TaskStreamEvent = EventMetadata & ({
1058
+ type: "images";
1059
+ files: TaskFile[];
1060
+ raw: unknown;
1061
+ } | {
1062
+ type: "progress";
1063
+ progress?: number;
1064
+ message?: string;
1065
+ raw: unknown;
1066
+ } | {
1067
+ type: "provider";
1068
+ data: unknown;
1069
+ });
1070
+ interface TaskStream {
1071
+ plan: TaskPlan;
1072
+ requestId?: string;
1073
+ /** Single-use stream. EOF does not establish generation success. */
1074
+ events: AsyncIterable<Result$1<TaskStreamEvent, MotifError>>;
1075
+ /** Stops local consumption; does not guarantee provider cancellation or refund. */
1076
+ abort: () => void;
1077
+ }
1078
+ //#endregion
1060
1079
  //#region src/tool-cost.d.ts
1061
1080
  /** Pixel dimensions of one file an endpoint returned. */
1062
1081
  interface OutputDimensions {
@@ -1177,7 +1196,12 @@ interface TaskInput {
1177
1196
  params?: Readonly<Record<string, unknown>>;
1178
1197
  /** Ask fal not to store IO payloads. */
1179
1198
  ephemeral?: boolean;
1180
- onProgress?: (status: string, queuePosition?: number) => void;
1199
+ /**
1200
+ * Called on each poll of fal's queue with its status ("queued",
1201
+ * "processing", "completed", "failed") and, while queued, the place in line. Passing
1202
+ * it runs a fal generation through the queue, since only the queue reports.
1203
+ */
1204
+ onProgress?: (status: JobStatus["status"], queuePosition?: number) => void;
1181
1205
  }
1182
1206
  interface TaskFile {
1183
1207
  /** Output key the URL came from, e.g. "image", "masks", "model_glb". */
@@ -1222,6 +1246,7 @@ interface MotifClient {
1222
1246
  /** Pure: resolve the Model, build the request, price it. No I/O. */
1223
1247
  plan: (task: TaskId, input: TaskInput, options?: PlanOptions) => Result$1<TaskPlan, MotifError>;
1224
1248
  run: (task: TaskId, input: TaskInput) => Promise<Result$1<TaskOutput, MotifError>>;
1249
+ stream: (task: TaskId, input: TaskInput, options?: TaskStreamOptions) => Promise<Result$1<TaskStream, MotifError>>;
1225
1250
  animate: TaskFunction;
1226
1251
  ask: TaskFunction;
1227
1252
  cutout: TaskFunction;
@@ -1300,4 +1325,4 @@ export declare function getFalKeyFromEnv(input?: Record<string, unknown>): strin
1300
1325
  /** The OpenAI key, used by direct OpenAI routes such as gpt2 transparency. */
1301
1326
  export declare function getOpenAiKeyFromEnv(input?: Record<string, unknown>): string | undefined;
1302
1327
  //#endregion
1303
- 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 TaskUnresolved, type Tier, type Unblocker, err, ok };
1328
+ 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
@@ -34,7 +34,8 @@ interface CreativeOption {
34
34
  interface LookOption extends CreativeOption {
35
35
  /**
36
36
  * Whether a mood may be combined with this look. Flat looks (surfaces,
37
- * prints, paintings, studio objects) carry their own light and refuse one.
37
+ * paintings, illustrations, studio objects) carry their own light and
38
+ * refuse one.
38
39
  */
39
40
  acceptsMood: boolean;
40
41
  /** Default aspect ratio, e.g. `"3:2"`. */
@@ -70,10 +71,11 @@ export declare class CreativeOptionError extends Error implements CreativeOption
70
71
  /** Canonical creative field order used for prompt enrichment and schema output. */
71
72
  export declare const CREATIVE_FIELDS: readonly ["look", "mood"];
72
73
  /**
73
- * Built-in creative direction catalogue: twelve house looks and six light moods.
74
+ * Built-in creative direction catalogue: nine house looks and six light moods.
74
75
  *
75
76
  * Each option carries the exact prompt sentence appended when it is selected.
76
- * Looks also carry the aspect ratio and model they were tuned for.
77
+ * Looks also carry the aspect ratio and model they were tuned for. The five
78
+ * photographic looks come first, then the four flat ones.
77
79
  */
78
80
  export declare const CREATIVE_TAXONOMY: {
79
81
  readonly look: readonly [{
@@ -87,92 +89,68 @@ export declare const CREATIVE_TAXONOMY: {
87
89
  }, {
88
90
  readonly acceptsMood: true;
89
91
  readonly aspect: "1:1";
90
- readonly clause: "Editorial still life on a warm bone plaster ground, chalky unglazed surfaces, a long soft shadow, generous empty space, shot on film with fine grain. No text, no logos, no people";
91
- readonly description: "Objects and material samples on a plaster ground, for product and swatch shots.";
92
+ readonly clause: "Editorial still life in the register of Aesop and Kinfolk, on a warm bone plaster ground, chalky unglazed surfaces in muted mineral colour, a long soft shadow, generous empty space, shot on film with fine grain, restrained and materially rich. No text, no logos, no people";
93
+ readonly description: "Objects and products on a plaster ground, for product and editorial still life.";
92
94
  readonly id: "still-life";
93
- readonly label: "Material still life";
95
+ readonly label: "Editorial still life";
94
96
  readonly model: "flux2-pro";
95
97
  }, {
96
98
  readonly acceptsMood: true;
97
99
  readonly aspect: "3:2";
98
- readonly clause: "Interior photograph shot square-on at eye level on a 35mm lens, warm off-white plaster, wide oak floorboards, linen, brass and a little pattern, light, bright and layered, collected rather than styled, slightly imperfect and lived-in rather than showroom-perfect, photographic realism. No text, no logos, no people";
100
+ readonly clause: "Interior photograph in the register of House & Garden and Kinfolk, shot square-on at eye level on a 35mm lens, warm off-white plaster, wide oak floorboards, linen, brass and a little pattern, light, bright and layered, collected rather than styled, lived-in rather than showroom-perfect, soft natural daylight, shot on film with fine grain. No text, no logos, no people";
99
101
  readonly description: "Bright, collected rooms that feel lived in, for interior scenes.";
100
- readonly id: "lived-in";
101
- readonly label: "Lived-in interior";
102
+ readonly id: "interior";
103
+ readonly label: "Interior";
102
104
  readonly model: "flux2-pro";
103
105
  }, {
104
106
  readonly acceptsMood: true;
105
107
  readonly aspect: "4:5";
106
- readonly clause: "Architectural editorial photograph at full room scale, honest materials meeting precise detailing, one hero element genuinely installed, plausible light and shadow, generous negative space, empty of people. No text, no logos";
107
- readonly description: "Whole rooms with one product installed, for showing a material at scale.";
108
+ readonly clause: "Architectural photograph in the register of House & Garden and Kinfolk, a considered house seen from outside at editorial distance with its garden and setting, pale render, stone or timber meeting precise detailing, clipped planting, soft warm daylight and long shadow, generous negative space, immaculate and calm, shot on film with fine grain. No text, no logos, no people";
109
+ readonly description: "Buildings and their settings from outside, for architecture, property and place.";
108
110
  readonly id: "architectural";
109
- readonly label: "Architectural scale";
111
+ readonly label: "Architectural exterior";
110
112
  readonly model: "banana";
111
- }, {
112
- readonly acceptsMood: true;
113
- readonly aspect: "4:3";
114
- readonly clause: "Amateur phone photo of a real home taken by the homeowner, slightly wonky framing, unstyled domestic photography, ordinary exposure. No text, no people";
115
- readonly description: "Unstyled phone snapshots of real homes, for believable before and after shots.";
116
- readonly id: "homeowner";
117
- readonly label: "Homeowner snapshot";
118
- readonly model: "seedream45";
119
113
  }, {
120
114
  readonly acceptsMood: true;
121
115
  readonly aspect: "1:1";
122
- readonly clause: "Stylised architectural illustration of the room, colour laid as flat planes on walls, joinery and trim, fine hand-drawn line with a gentle gouache wash, clearly a drawing of a design decision rather than a photograph. No text, no people";
123
- readonly description: "Line and gouache room drawings, for showing a colour scheme as a design idea.";
124
- readonly experimental: true;
125
- readonly id: "drawing";
126
- readonly label: "Palette drawing";
127
- readonly model: "gpt2";
116
+ readonly clause: "Editorial documentary portrait in the register of Kinfolk, muted warm palette, waist-up and unposed against a plain plaster or linen ground, plain clothing with no logos, soft natural light, shot on film with fine grain. No text";
117
+ readonly description: "Natural, unposed documentary portraits of people. Pair with a mood for the light.";
118
+ readonly id: "portrait";
119
+ readonly label: "Documentary portrait";
120
+ readonly model: "seedream45";
128
121
  }, {
129
122
  readonly acceptsMood: false;
130
123
  readonly aspect: "1:1";
131
- readonly clause: "Straight-on orthographic photograph of the surface filling the entire frame edge to edge, even shadowless studio light, crisp macro texture, colour-accurate. No text, no logos";
132
- readonly description: "Flat, edge-to-edge surface photographs, for textures and material swatches.";
133
- readonly id: "plate";
134
- readonly label: "Flat plate";
124
+ readonly clause: "A single matte object centred with generous empty space, soft diffused studio light, minimal and quiet in the register of Aesop, one committed muted mineral colour on a plain ground. No text, no logos, no people";
125
+ readonly description: "One object in one colour on a clean ground, for icons and simple product shots.";
126
+ readonly id: "object";
127
+ readonly label: "Studio object";
135
128
  readonly model: "flux2-pro";
136
129
  }, {
137
130
  readonly acceptsMood: false;
138
131
  readonly aspect: "1:1";
139
- readonly clause: "Fine hand-engraved botanical plate with delicate hatching and dry brush, grey ink only, reaching near-black at its densest, on matte uncoated stock under flat even light, cropped mid-motif and running past all four edges, never simplified or cartoonish. No text";
140
- readonly description: "Grey-ink botanical engravings that run off the edges, for patterns and backgrounds.";
141
- readonly id: "engraved";
142
- readonly label: "Engraved grey ink";
143
- readonly model: "gpt2";
144
- }, {
145
- readonly acceptsMood: false;
146
- readonly aspect: "2:3";
147
- readonly clause: "Tightly cropped photograph of a single piece of late-1940s American printed matter, flat and square-on in even light, every pixel paper, letterpress and wood type, sun-faded ink, foxing, soft creases and thumbtack holes, era-correct typography, nothing that looks like a digital photo run through a filter";
148
- readonly description: "Aged mid-century printed matter such as posters and cards, where the lettering matters.";
149
- readonly id: "ephemera";
150
- readonly label: "Period ephemera";
151
- readonly model: "ideogram4";
132
+ readonly clause: "Straight-on orthographic photograph of the surface filling the entire frame edge to edge, even shadowless studio light, crisp macro texture, colour-accurate and quietly material. No text, no logos";
133
+ readonly description: "Flat, edge-to-edge surface photographs, for textures, backgrounds and material swatches.";
134
+ readonly id: "surface";
135
+ readonly label: "Flat surface";
136
+ readonly model: "flux2-pro";
152
137
  }, {
153
138
  readonly acceptsMood: false;
154
- readonly aspect: "3:4";
155
- readonly clause: "Physical mineral pigment and chalk gesso on coarse natural linen, two or three confident gestures, warm ivory, oatmeal, putty and soft charcoal, flat diffuse museum reproduction lighting, shown unframed. No text";
156
- readonly description: "Loose abstract paintings on linen, for wall art and calm backgrounds.";
157
- readonly id: "canvas";
158
- readonly label: "Linen abstract";
139
+ readonly aspect: "3:2";
140
+ readonly clause: "Painted abstraction filling the frame edge to edge, mineral pigment and chalk gesso on coarse natural linen, two or three confident gestures, warm ivory, oatmeal, putty and soft charcoal, flat diffuse reproduction light. No text";
141
+ readonly description: "Painted abstraction edge to edge, for wall art, heroes and calm backgrounds.";
142
+ readonly id: "abstract";
143
+ readonly label: "Painted abstract";
159
144
  readonly model: "banana";
160
- }, {
161
- readonly acceptsMood: true;
162
- readonly aspect: "1:1";
163
- readonly clause: "Editorial documentary portrait, muted warm palette, waist-up, unposed, plain clothing with no logos. No text";
164
- readonly description: "Natural, unposed documentary portraits of people. Pair with a mood for the light.";
165
- readonly id: "portrait";
166
- readonly label: "Documentary portrait";
167
- readonly model: "seedream45";
168
145
  }, {
169
146
  readonly acceptsMood: false;
170
147
  readonly aspect: "1:1";
171
- readonly clause: "A single matte object centred with generous empty space, soft diffused studio light, minimal and quiet, one committed colour. No text, no logos, no people";
172
- readonly description: "One object in one colour on a clean ground, for icons and simple product shots.";
173
- readonly id: "object";
174
- readonly label: "Studio object";
175
- readonly model: "flux2-pro";
148
+ readonly clause: "Stylised editorial illustration in the register of Kinfolk, colour laid as flat planes in a warm muted palette of ivory, putty, sage and charcoal, fine hand-drawn line with a gentle gouache wash, generous empty space, clearly a drawing rather than a photograph. No text, no logos";
149
+ readonly description: "Line and gouache illustration of any subject, for drawn editorial imagery.";
150
+ readonly experimental: true;
151
+ readonly id: "illustration";
152
+ readonly label: "Editorial illustration";
153
+ readonly model: "gpt2";
176
154
  }];
177
155
  readonly mood: readonly [{
178
156
  readonly clause: "soft natural daylight from a window out of frame, gentle falloff into the corners, low contrast, even diffused light with soft, held highlights";
@@ -208,7 +186,7 @@ export declare const CREATIVE_TAXONOMY: {
208
186
  };
209
187
  /** Every house look, in catalogue order. */
210
188
  export declare const LOOKS: readonly LookOption[];
211
- /** Stable id of a house look, e.g. `"lived-in"`. */
189
+ /** Stable id of a house look, e.g. `"interior"`. */
212
190
  type LookId = (typeof CREATIVE_TAXONOMY.look)[number]["id"];
213
191
  /** Stable id of a light mood, e.g. `"overcast"`. */
214
192
  type MoodId = (typeof CREATIVE_TAXONOMY.mood)[number]["id"];
@@ -284,6 +262,15 @@ interface ImageSizeBounds {
284
262
  /** Both edges must be multiples of this. Motif uses 16 when absent. */
285
263
  multipleOf?: number;
286
264
  }
265
+ interface JobStatus {
266
+ error?: string;
267
+ logs?: {
268
+ message: string;
269
+ timestamp: string;
270
+ }[];
271
+ queuePosition?: number;
272
+ status: "queued" | "processing" | "completed" | "failed";
273
+ }
287
274
  /** ─── Configuration ──────────────────────────────────────────── */
288
275
  /** The network seam: a `fetch`-shaped function. */
289
276
  type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
@@ -1057,6 +1044,38 @@ export declare function resolveTask(task: TaskId, request: TaskRequest, environm
1057
1044
  */
1058
1045
  export declare function tierChangesChoice(task: TaskId, request: Omit<TaskRequest, "tier">, environment: TaskEnvironment): boolean;
1059
1046
  //#endregion
1047
+ //#region src/task-stream.d.ts
1048
+ interface TaskStreamOptions {
1049
+ signal?: AbortSignal;
1050
+ /** Overall deadline covering connection and consumption, in milliseconds. */
1051
+ timeout?: number;
1052
+ }
1053
+ interface EventMetadata {
1054
+ event?: string;
1055
+ id?: string;
1056
+ }
1057
+ type TaskStreamEvent = EventMetadata & ({
1058
+ type: "images";
1059
+ files: TaskFile[];
1060
+ raw: unknown;
1061
+ } | {
1062
+ type: "progress";
1063
+ progress?: number;
1064
+ message?: string;
1065
+ raw: unknown;
1066
+ } | {
1067
+ type: "provider";
1068
+ data: unknown;
1069
+ });
1070
+ interface TaskStream {
1071
+ plan: TaskPlan;
1072
+ requestId?: string;
1073
+ /** Single-use stream. EOF does not establish generation success. */
1074
+ events: AsyncIterable<Result$1<TaskStreamEvent, MotifError>>;
1075
+ /** Stops local consumption; does not guarantee provider cancellation or refund. */
1076
+ abort: () => void;
1077
+ }
1078
+ //#endregion
1060
1079
  //#region src/tool-cost.d.ts
1061
1080
  /** Pixel dimensions of one file an endpoint returned. */
1062
1081
  interface OutputDimensions {
@@ -1177,7 +1196,12 @@ interface TaskInput {
1177
1196
  params?: Readonly<Record<string, unknown>>;
1178
1197
  /** Ask fal not to store IO payloads. */
1179
1198
  ephemeral?: boolean;
1180
- onProgress?: (status: string, queuePosition?: number) => void;
1199
+ /**
1200
+ * Called on each poll of fal's queue with its status ("queued",
1201
+ * "processing", "completed", "failed") and, while queued, the place in line. Passing
1202
+ * it runs a fal generation through the queue, since only the queue reports.
1203
+ */
1204
+ onProgress?: (status: JobStatus["status"], queuePosition?: number) => void;
1181
1205
  }
1182
1206
  interface TaskFile {
1183
1207
  /** Output key the URL came from, e.g. "image", "masks", "model_glb". */
@@ -1222,6 +1246,7 @@ interface MotifClient {
1222
1246
  /** Pure: resolve the Model, build the request, price it. No I/O. */
1223
1247
  plan: (task: TaskId, input: TaskInput, options?: PlanOptions) => Result$1<TaskPlan, MotifError>;
1224
1248
  run: (task: TaskId, input: TaskInput) => Promise<Result$1<TaskOutput, MotifError>>;
1249
+ stream: (task: TaskId, input: TaskInput, options?: TaskStreamOptions) => Promise<Result$1<TaskStream, MotifError>>;
1225
1250
  animate: TaskFunction;
1226
1251
  ask: TaskFunction;
1227
1252
  cutout: TaskFunction;
@@ -1300,4 +1325,4 @@ export declare function getFalKeyFromEnv(input?: Record<string, unknown>): strin
1300
1325
  /** The OpenAI key, used by direct OpenAI routes such as gpt2 transparency. */
1301
1326
  export declare function getOpenAiKeyFromEnv(input?: Record<string, unknown>): string | undefined;
1302
1327
  //#endregion
1303
- 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 TaskUnresolved, type Tier, type Unblocker, err, ok };
1328
+ 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 };