@howells/motif-sdk 5.3.0 → 5.4.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 CHANGED
@@ -44,7 +44,7 @@ The Task client curates 24 generation Models, with separate rankings for generat
44
44
 
45
45
  These are the first choices when the request's capabilities and available keys permit them. Explicit Models, Looks and pins take precedence. Selected specialists remain for typography, transparency, control and inexpensive drafts. Archived predecessors remain available through explicit Models, pins and existing Looks, including `flux2-dev` for streaming.
46
46
 
47
- Nano Banana 2.1 (`banana21`) supports up to 14 References and 1K/2K/4K output, with no 0.5K output. Its balanced placement uses preliminary Arena evidence. Sunburst and Flare default to the benchmarked `max` quality on fal; `params: { quality: "high" }` with an explicit `model` overrides it. The direct provider image layer described below has its own adapter capabilities and chooses no Model.
47
+ Nano Banana 2.1 (`banana21`) supports up to 14 References and 1K/2K/4K output, with no 0.5K output. Its balanced placement uses preliminary Arena evidence. Sunburst and Flare run GPT Image 2.6 on fal and default to `quality: "max"`; `params: { quality: "high" }` with an explicit `model` overrides it. Both also return an animated GIF (`outputFormat: "gif"`, with `params.frame_count` and `params.frame_duration_ms`) or, from text, an SVG (`outputFormat: "svg"`), and take `markup`: a transparent PNG of arrows, circles and notes the size of the image being edited, which guides a vary or an edit with References. Asking for a format or markup limits the choice to Models that support it. The direct provider image layer described below has its own adapter capabilities and chooses no Model.
48
48
 
49
49
  Token-billed Task plans, including Sunburst, Flare, Nano Banana 2.1, Banana Lite and MAI 2.5, report `cost: { usd: null, basis: "unknown" }`; a published representative price is not an exact total. The [curation audit](https://github.com/howells/motif/blob/main/docs/research/image-model-curation-2026-10-07.md) records the current rankings, specialist roles and provider coverage gaps.
50
50
 
@@ -161,28 +161,28 @@ Four providers are implemented, each reading its own API key from the environmen
161
161
  | Provider | Env var | Notes |
162
162
  | --- | --- | --- |
163
163
  | `openrouter` | `OPENROUTER_API_KEY` | Default provider; Gemini gen + edit through OpenRouter (`google/*`), no masks |
164
- | `openai` | `OPENAI_API_KEY` | GPT Image 2.5 Flare and Sunburst |
164
+ | `openai` | `OPENAI_API_KEY` | GPT Image 2.6 Flare and Sunburst |
165
165
  | `replicate` | `REPLICATE_API_TOKEN` | flux-1.1-pro-ultra |
166
166
  | `fal` | `FAL_KEY` | fal-hosted adapter |
167
167
 
168
168
  `generate()` and `edit()` take a provider model id; Task resolution chooses which model to pass, not the image layer. Every result carries a normalized per-call `cost: { usd, source }`.
169
169
 
170
- Both `gpt-image-2.5-flare` and `gpt-image-2.5-sunburst` support generation and multi-image editing:
170
+ Both `gpt-image-2.6-flare` and `gpt-image-2.6-sunburst` support generation and multi-image editing:
171
171
 
172
172
  ```ts
173
173
  const image = createMotifImage({ defaultProvider: "openai" });
174
174
  const generated = await image.generate({
175
175
  prompt: "A ceramic vase in soft window light",
176
- model: "gpt-image-2.5-flare",
176
+ model: "gpt-image-2.6-flare",
177
177
  });
178
178
  const refined = await image.edit({
179
179
  images: [referenceBytes],
180
180
  instruction: "Change only the vase glaze to deep green",
181
- model: "gpt-image-2.5-sunburst",
181
+ model: "gpt-image-2.6-sunburst",
182
182
  });
183
183
  ```
184
184
 
185
- These models use token-based billing. Motif has no static per-image estimate for them, so `cost` is `{ usd: 0, source: "unknown" }` unless the provider supplies a cost; this does not mean generation is free. See the official [Flare](https://developers.openai.com/api/docs/models/gpt-image-2.5-flare) and [Sunburst](https://developers.openai.com/api/docs/models/gpt-image-2.5-sunburst) model pages. The installed OpenAI adapter accepts `low`, `medium`, `high`, and `auto` quality; the new `xhigh` and `max` settings require a future adapter update. The Task client and the CLI reach these models on fal as `flare` and `sunburst`. Fal supports `xhigh` and `max`, up to 16 edit references, masks and transparent backgrounds. Fal generation estimates are `null` (metered).
185
+ These models use token-based billing. Motif has no static per-image estimate for them, so `cost` is `{ usd: 0, source: "unknown" }` unless the provider supplies a cost; this does not mean generation is free. See the official [Flare](https://developers.openai.com/api/docs/models/gpt-image-2.6-flare) and [Sunburst](https://developers.openai.com/api/docs/models/gpt-image-2.6-sunburst) model pages. Set quality (`auto`, `low`, `medium`, `high`, `xhigh` or `max`) and `background: "transparent"` through `providerOptions.openai`. The Task client and the CLI run the same models on fal as `flare` and `sunburst`, with up to 16 edit references, masks and transparent backgrounds. Fal generation estimates are `null` (metered).
186
186
 
187
187
  ### Best-of-N with an injectable judge
188
188
 
@@ -218,9 +218,3 @@ If some candidates fail, the judge sees only the survivors; if all `n` fail, `be
218
218
  pnpm --filter @howells/motif-sdk test
219
219
  pnpm --filter @howells/motif-sdk typecheck
220
220
  ```
221
-
222
- Live fal canaries are opt-in:
223
-
224
- ```bash
225
- RUN_FAL_CANARY=1 pnpm --filter @howells/motif-sdk test -- tests/fal-canary.test.ts
226
- ```
package/dist/image.js CHANGED
@@ -73,7 +73,7 @@ const MODELS = {
73
73
  rank: 2
74
74
  }
75
75
  },
76
- useCase: "Frontier generation and editing, evaluated at max quality"
76
+ useCase: "Frontier generation and editing at max reasoning effort; scored as GPT Image 2.5 until 2.6 is benchmarked"
77
77
  },
78
78
  defaultQuality: "max",
79
79
  customImageSize: {
@@ -83,11 +83,11 @@ const MODELS = {
83
83
  minPixels: 655360,
84
84
  multipleOf: 16
85
85
  },
86
- editEndpoint: "openai/gpt-image-2.5/flare/edit",
87
- endpoint: "openai/gpt-image-2.5/flare/text-to-image",
86
+ editEndpoint: "openai/gpt-image-2.6/flare/edit",
87
+ endpoint: "openai/gpt-image-2.6/flare/text-to-image",
88
88
  maxReferenceImages: 16,
89
- name: "GPT Image 2.5 Flare",
90
- pricing: "Token-based: text $5/M input, $1.25/M cached, $10/M output; image $8/M input, $2/M cached, $30/M output",
89
+ name: "GPT Image 2.6 Flare",
90
+ pricing: "Token-based: image $8/M input, $2/M cached, $30/M output; text $5/M input, $1.25/M cached",
91
91
  pricePerImageUsd: null,
92
92
  sizeMode: "image_size_enum",
93
93
  supportsAspect: true,
@@ -95,8 +95,23 @@ const MODELS = {
95
95
  supportsEdit: true,
96
96
  supportsMaskImage: true,
97
97
  maskImageField: "mask_url",
98
+ supportsMarkupImage: true,
99
+ autoEditSize: true,
98
100
  supportsNumImages: true,
99
101
  supportsOutputFormat: true,
102
+ supportedOutputFormats: [
103
+ "jpeg",
104
+ "png",
105
+ "webp",
106
+ "gif",
107
+ "svg"
108
+ ],
109
+ supportedEditOutputFormats: [
110
+ "jpeg",
111
+ "png",
112
+ "webp",
113
+ "gif"
114
+ ],
100
115
  supportsQuality: true,
101
116
  supportedQualities: [
102
117
  "auto",
@@ -125,7 +140,7 @@ const MODELS = {
125
140
  rank: 1
126
141
  }
127
142
  },
128
- useCase: "Frontier generation and editing, evaluated at max quality"
143
+ useCase: "Frontier generation and editing at max reasoning effort; scored as GPT Image 2.5 until 2.6 is benchmarked"
129
144
  },
130
145
  defaultQuality: "max",
131
146
  customImageSize: {
@@ -135,11 +150,11 @@ const MODELS = {
135
150
  minPixels: 655360,
136
151
  multipleOf: 16
137
152
  },
138
- editEndpoint: "openai/gpt-image-2.5/sunburst/edit",
139
- endpoint: "openai/gpt-image-2.5/sunburst/text-to-image",
153
+ editEndpoint: "openai/gpt-image-2.6/sunburst/edit",
154
+ endpoint: "openai/gpt-image-2.6/sunburst/text-to-image",
140
155
  maxReferenceImages: 16,
141
- name: "GPT Image 2.5 Sunburst",
142
- pricing: "Token-based: text $5/M input, $1.25/M cached, $10/M output; image $8/M input, $2/M cached, $30/M output",
156
+ name: "GPT Image 2.6 Sunburst",
157
+ pricing: "Token-based: image $8/M input, $2/M cached, $30/M output; text $5/M input, $1.25/M cached",
143
158
  pricePerImageUsd: null,
144
159
  sizeMode: "image_size_enum",
145
160
  supportsAspect: true,
@@ -147,8 +162,23 @@ const MODELS = {
147
162
  supportsEdit: true,
148
163
  supportsMaskImage: true,
149
164
  maskImageField: "mask_url",
165
+ supportsMarkupImage: true,
166
+ autoEditSize: true,
150
167
  supportsNumImages: true,
151
168
  supportsOutputFormat: true,
169
+ supportedOutputFormats: [
170
+ "jpeg",
171
+ "png",
172
+ "webp",
173
+ "gif",
174
+ "svg"
175
+ ],
176
+ supportedEditOutputFormats: [
177
+ "jpeg",
178
+ "png",
179
+ "webp",
180
+ "gif"
181
+ ],
152
182
  supportsQuality: true,
153
183
  supportedQualities: [
154
184
  "auto",
@@ -1854,6 +1884,7 @@ const OPTION_CAPABILITIES = {
1854
1884
  imageSize: (config) => config.sizeMode === "gpt_size" || config.sizeMode === "image_size_enum",
1855
1885
  inputFidelity: (config) => config.sizeMode === "gpt_size",
1856
1886
  limitGenerations: (config) => config.supportsLimitGenerations === true,
1887
+ markupImageUrl: (config) => config.supportsMarkupImage === true,
1857
1888
  maskImageUrl: (config) => config.supportsMaskImage === true,
1858
1889
  negativePrompt: (config) => config.supportsNegativePrompt === true,
1859
1890
  numImages: (config) => config.supportsNumImages,
@@ -3621,10 +3652,10 @@ const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
3621
3652
  * Sanity anchor: the Phase 0 benchmark measured gpt-image direct at $0.042
3622
3653
  * (vs $0.133 via fal — full data and methodology on Linear MOT-23).
3623
3654
  *
3624
- * GPT Image 2.5 is token-priced, with no published per-image estimate. Leave
3655
+ * GPT Image 2.6 is token-priced, with no published per-image estimate. Leave
3625
3656
  * these models absent so cost remains unknown unless supplied by the provider.
3626
- * https://developers.openai.com/api/docs/models/gpt-image-2.5-flare
3627
- * https://developers.openai.com/api/docs/models/gpt-image-2.5-sunburst
3657
+ * https://developers.openai.com/api/docs/models/gpt-image-2.6-flare
3658
+ * https://developers.openai.com/api/docs/models/gpt-image-2.6-sunburst
3628
3659
  */
3629
3660
  const OPENAI_IMAGE_PRICE_USD = { "gpt-image-1": .042 };
3630
3661
  /**