@howells/motif-sdk 1.3.0 → 2.0.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 +18 -1
- package/dist/image.d.ts +225 -321
- package/dist/image.js +3015 -2652
- package/dist/index.cjs +6332 -4858
- package/dist/index.d.cts +3050 -3074
- package/dist/index.d.ts +3050 -3074
- package/dist/index.js +6277 -4789
- package/package.json +6 -6
package/dist/image.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Result } from
|
|
3
|
-
|
|
1
|
+
import { ImageModel, generateImage } from "ai";
|
|
2
|
+
import { Result } from "neverthrow";
|
|
3
|
+
//#region src/errors.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* `MotifError` and its coercion helper.
|
|
6
6
|
*
|
|
@@ -10,23 +10,15 @@ import { Result } from 'neverthrow';
|
|
|
10
10
|
* re-exports `MotifError` so the package's public surface is unchanged.
|
|
11
11
|
*/
|
|
12
12
|
declare class MotifError extends Error {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
readonly status: number;
|
|
14
|
+
readonly code?: string;
|
|
15
|
+
/** fal's request-correlation id (from the `x-fal-request-id` header or the
|
|
16
|
+
* error body). Ties a failure back to fal's dashboard/support. */
|
|
17
|
+
readonly requestId?: string;
|
|
18
|
+
constructor(message: string, status: number, code?: string, requestId?: string);
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* Public types for the provider-agnostic image generation + editing layer
|
|
23
|
-
* (`@howells/motif-sdk/image`).
|
|
24
|
-
*
|
|
25
|
-
* This layer is additive: it sits alongside the fal-specific `FalClient`
|
|
26
|
-
* surface and reuses the SDK's Result convention (`Result<T, MotifError>` — no
|
|
27
|
-
* thrown exceptions). See docs/design/provider-agnostic-image-layer.md.
|
|
28
|
-
*/
|
|
29
|
-
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/image/types.d.ts
|
|
30
22
|
/**
|
|
31
23
|
* Quality/latency tier. Resolves through a provider-aware tier→model map when no
|
|
32
24
|
* explicit `model` id is given. `balanced` is the default when a tier is omitted.
|
|
@@ -42,10 +34,10 @@ type ImageProviderId = "google" | "openai" | "replicate" | "fal" | (string & Rec
|
|
|
42
34
|
type ImageCostSource = "provider-metadata" | "table" | "unknown";
|
|
43
35
|
/** Normalized per-call spend attached to every result. */
|
|
44
36
|
interface ImageCost {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
/** Total USD for the call (all images), best-effort. */
|
|
38
|
+
usd: number;
|
|
39
|
+
/** Where the figure came from: the provider's metadata, the static table, or unknown. */
|
|
40
|
+
source: ImageCostSource;
|
|
49
41
|
}
|
|
50
42
|
/**
|
|
51
43
|
* Client configuration. Every provider key is optional and falls back to that
|
|
@@ -54,137 +46,137 @@ interface ImageCost {
|
|
|
54
46
|
* credential `apiToken`, not `apiKey`.
|
|
55
47
|
*/
|
|
56
48
|
interface MotifImageConfig {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
49
|
+
/** Provider used when a call does not specify one. Defaults to `google`. */
|
|
50
|
+
defaultProvider?: ImageProviderId;
|
|
51
|
+
/** Google provider overrides. `apiKey` falls back to `GOOGLE_GENERATIVE_AI_API_KEY`. */
|
|
52
|
+
google?: {
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
};
|
|
55
|
+
/** OpenAI provider overrides. `apiKey` falls back to `OPENAI_API_KEY`. */
|
|
56
|
+
openai?: {
|
|
57
|
+
apiKey?: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Replicate provider overrides. Replicate's SDK names the credential
|
|
61
|
+
* `apiToken` (not `apiKey`); it falls back to `REPLICATE_API_TOKEN`.
|
|
62
|
+
*/
|
|
63
|
+
replicate?: {
|
|
64
|
+
apiToken?: string;
|
|
65
|
+
};
|
|
66
|
+
/** fal provider overrides. `apiKey` falls back to `FAL_KEY`. */
|
|
67
|
+
fal?: {
|
|
68
|
+
apiKey?: string;
|
|
69
|
+
};
|
|
78
70
|
}
|
|
79
71
|
/** Options for a text→image generation. */
|
|
80
72
|
interface GenerateImageOptions {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
73
|
+
/** The text prompt. */
|
|
74
|
+
prompt: string;
|
|
75
|
+
/** Quality/latency tier. Ignored when `model` is set. */
|
|
76
|
+
tier?: ImageTier;
|
|
77
|
+
/** Explicit provider model id. Overrides `tier`. */
|
|
78
|
+
model?: string;
|
|
79
|
+
/** Provider override for this call. */
|
|
80
|
+
provider?: ImageProviderId;
|
|
81
|
+
/**
|
|
82
|
+
* Aspect ratio, e.g. `"1:1"`. An alternative to {@link size}; pass one or the
|
|
83
|
+
* other. If both are passed the provider decides which to honor and typically
|
|
84
|
+
* surfaces a warning (see {@link MotifImageResult.warnings}).
|
|
85
|
+
*/
|
|
86
|
+
aspectRatio?: `${number}:${number}`;
|
|
87
|
+
/**
|
|
88
|
+
* Explicit pixel size, e.g. `"1024x1024"`. An alternative to
|
|
89
|
+
* {@link aspectRatio}; pass one or the other. If both are passed the provider
|
|
90
|
+
* decides which to honor and typically surfaces a warning (see
|
|
91
|
+
* {@link MotifImageResult.warnings}).
|
|
92
|
+
*/
|
|
93
|
+
size?: `${number}x${number}`;
|
|
94
|
+
/** Number of images to generate. */
|
|
95
|
+
n?: number;
|
|
96
|
+
/** Seed for reproducible generation, where the provider supports it. */
|
|
97
|
+
seed?: number;
|
|
98
|
+
/** Abort signal to cancel the in-flight request. */
|
|
99
|
+
signal?: AbortSignal;
|
|
100
|
+
/**
|
|
101
|
+
* Extra HTTP headers forwarded to the provider request. Fal's non-retained IO
|
|
102
|
+
* (paired with FalClient.deletePayloads) is
|
|
103
|
+
* `headers: { "X-Fal-Store-IO": "0" }`.
|
|
104
|
+
*/
|
|
105
|
+
headers?: Record<string, string>;
|
|
106
|
+
/**
|
|
107
|
+
* Provider-specific options, passed straight through to the underlying model
|
|
108
|
+
* as body parameters. Outer key = provider name, inner key = option name.
|
|
109
|
+
* Values must be JSON-representable; a non-JSON value (undefined, function,
|
|
110
|
+
* bigint, symbol) makes the call fail with a `MotifError`.
|
|
111
|
+
*/
|
|
112
|
+
providerOptions?: Record<string, Record<string, unknown>>;
|
|
121
113
|
}
|
|
122
114
|
/** Options for a multi-image edit (images in → image out), with an optional mask. */
|
|
123
115
|
interface EditImageOptions {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Input images. Each entry is raw bytes (`Uint8Array`) or a string. A string
|
|
118
|
+
* may be base64, a `data:` URL, OR a remote `http(s)://` URL. Remote URLs are
|
|
119
|
+
* FETCHED by the provider — and on some providers (e.g. OpenAI) that fetch
|
|
120
|
+
* happens from the local process running this SDK. Callers that accept
|
|
121
|
+
* untrusted URLs should fetch and validate the bytes themselves before
|
|
122
|
+
* passing them here (SSRF / local-network exposure otherwise).
|
|
123
|
+
*/
|
|
124
|
+
images: (Uint8Array | string)[];
|
|
125
|
+
/** Natural-language edit instruction. */
|
|
126
|
+
instruction: string;
|
|
127
|
+
/**
|
|
128
|
+
* Optional mask constraining the edited region. Same accepted forms as
|
|
129
|
+
* {@link EditImageOptions.images} (bytes, base64, `data:` URL, or a remote
|
|
130
|
+
* `http(s)://` URL that the provider fetches — see the images note on
|
|
131
|
+
* untrusted URLs). When multiple images are passed, the mask applies to
|
|
132
|
+
* `images[0]`.
|
|
133
|
+
*/
|
|
134
|
+
mask?: Uint8Array | string;
|
|
135
|
+
/** Quality/latency tier. Ignored when `model` is set. */
|
|
136
|
+
tier?: ImageTier;
|
|
137
|
+
/** Explicit provider model id. Overrides `tier`. */
|
|
138
|
+
model?: string;
|
|
139
|
+
/** Provider override for this call. */
|
|
140
|
+
provider?: ImageProviderId;
|
|
141
|
+
/** Number of images to generate. */
|
|
142
|
+
n?: number;
|
|
143
|
+
/** Seed for reproducible generation, where the provider supports it. */
|
|
144
|
+
seed?: number;
|
|
145
|
+
/** Abort signal to cancel the in-flight request. */
|
|
146
|
+
signal?: AbortSignal;
|
|
147
|
+
/**
|
|
148
|
+
* Extra HTTP headers forwarded to the provider request. Fal's non-retained IO
|
|
149
|
+
* (paired with FalClient.deletePayloads) is
|
|
150
|
+
* `headers: { "X-Fal-Store-IO": "0" }`.
|
|
151
|
+
*/
|
|
152
|
+
headers?: Record<string, string>;
|
|
153
|
+
/** Provider-specific options (see {@link GenerateImageOptions.providerOptions}). */
|
|
154
|
+
providerOptions?: Record<string, Record<string, unknown>>;
|
|
163
155
|
}
|
|
164
156
|
/** A single generated image, mirroring the AI SDK's `GeneratedFile`. */
|
|
165
157
|
interface MotifImageFile {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
158
|
+
uint8Array: Uint8Array;
|
|
159
|
+
base64: string;
|
|
160
|
+
mediaType: string;
|
|
169
161
|
}
|
|
170
162
|
/** Normalized result of a generate/edit call. */
|
|
171
163
|
interface MotifImageResult {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
164
|
+
/** Generated images. */
|
|
165
|
+
images: MotifImageFile[];
|
|
166
|
+
/** Normalized per-call cost + provenance. */
|
|
167
|
+
cost: ImageCost;
|
|
168
|
+
/** Resolved provider. */
|
|
169
|
+
provider: ImageProviderId;
|
|
170
|
+
/** Resolved model id. */
|
|
171
|
+
model: string;
|
|
172
|
+
/** Provider correlation id, where the provider surfaces one. */
|
|
173
|
+
requestId?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Degraded-success warnings from the provider (a requested setting was
|
|
176
|
+
* ignored or adjusted — e.g. passing both `size` and `aspectRatio`). Each is a
|
|
177
|
+
* readable string. Omitted entirely when the provider returned none.
|
|
178
|
+
*/
|
|
179
|
+
warnings?: readonly string[];
|
|
188
180
|
}
|
|
189
181
|
/**
|
|
190
182
|
* Picks the winning candidate for a {@link MotifImageClient.bestOfN} call.
|
|
@@ -197,14 +189,14 @@ interface MotifImageResult {
|
|
|
197
189
|
* is not required.
|
|
198
190
|
*/
|
|
199
191
|
type ImageJudge = (candidates: readonly MotifImageResult[], context: {
|
|
200
|
-
|
|
201
|
-
|
|
192
|
+
readonly prompt?: string;
|
|
193
|
+
readonly instruction?: string;
|
|
202
194
|
}) => Promise<{
|
|
203
|
-
|
|
204
|
-
|
|
195
|
+
index: number;
|
|
196
|
+
reason?: string;
|
|
205
197
|
}> | {
|
|
206
|
-
|
|
207
|
-
|
|
198
|
+
index: number;
|
|
199
|
+
reason?: string;
|
|
208
200
|
};
|
|
209
201
|
/**
|
|
210
202
|
* Options for a best-of-N generation. Extends either {@link GenerateImageOptions}
|
|
@@ -212,120 +204,94 @@ type ImageJudge = (candidates: readonly MotifImageResult[], context: {
|
|
|
212
204
|
* `images` selects the edit path — with the candidate count and an optional judge.
|
|
213
205
|
*/
|
|
214
206
|
type BestOfNOptions = (GenerateImageOptions | EditImageOptions) & {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
207
|
+
/** How many candidates to generate (>= 1). */
|
|
208
|
+
n: number;
|
|
209
|
+
/** Chooses the winner. Omit → candidate 0 wins. */
|
|
210
|
+
judge?: ImageJudge;
|
|
219
211
|
};
|
|
220
212
|
/** Result of a {@link MotifImageClient.bestOfN} call. */
|
|
221
213
|
interface BestOfNResult {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
214
|
+
/** The winning candidate (its single-image {@link MotifImageResult}). */
|
|
215
|
+
best: MotifImageResult;
|
|
216
|
+
/** The index of `best` within `candidates`. */
|
|
217
|
+
chosenIndex: number;
|
|
218
|
+
/** Judge's rationale, if it returned one. */
|
|
219
|
+
reason?: string;
|
|
220
|
+
/** All successful candidates, in generation order. */
|
|
221
|
+
candidates: readonly MotifImageResult[];
|
|
222
|
+
/** Total USD across all candidates that were generated (successes only). */
|
|
223
|
+
totalCostUsd: number;
|
|
232
224
|
}
|
|
233
225
|
/** The provider-agnostic image client. Every method returns a Result — no throws. */
|
|
234
226
|
interface MotifImageClient {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
227
|
+
/** Text→image generation. */
|
|
228
|
+
generate: (opts: GenerateImageOptions) => Promise<Result<MotifImageResult, MotifError>>;
|
|
229
|
+
/** Multi-image edit (with optional mask). */
|
|
230
|
+
edit: (opts: EditImageOptions) => Promise<Result<MotifImageResult, MotifError>>;
|
|
231
|
+
/**
|
|
232
|
+
* Generate N candidates (in parallel) and pick the best via an optional
|
|
233
|
+
* injectable judge. Discriminates generate vs edit by the presence of
|
|
234
|
+
* `images`. Returns the winner plus all successful candidates and total spend.
|
|
235
|
+
*/
|
|
236
|
+
bestOfN: (opts: BestOfNOptions) => Promise<Result<BestOfNResult, MotifError>>;
|
|
245
237
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
* Internal dependency-injection seam for the image layer.
|
|
249
|
-
*
|
|
250
|
-
* These types are INTERNAL: they are consumed by `createMotifImage`'s `deps`
|
|
251
|
-
* parameter and by the offline tests, but they are deliberately NOT re-exported
|
|
252
|
-
* from the public `@howells/motif-sdk/image` subpath, so they never appear in
|
|
253
|
-
* `dist/image.d.ts`. Import them from `./deps` inside the package (and from
|
|
254
|
-
* `../src/image/deps` in tests).
|
|
255
|
-
*/
|
|
256
|
-
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/image/deps.d.ts
|
|
257
240
|
/** A model resolver: builds an AI SDK `ImageModel` for a (provider, model, key). */
|
|
258
241
|
type ResolveImageModel = (provider: ImageProviderId, modelId: string, apiKey?: string) => ImageModel;
|
|
259
242
|
/** Internal dependency-injection seam (default: real `generateImage` + adapters). */
|
|
260
243
|
interface MotifImageDeps {
|
|
261
|
-
|
|
262
|
-
|
|
244
|
+
generateImage?: typeof generateImage;
|
|
245
|
+
resolveModel?: ResolveImageModel;
|
|
263
246
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
* Provider registry for the image layer.
|
|
267
|
-
*
|
|
268
|
-
* Each provider (google, openai, replicate, fal) contributes exactly one
|
|
269
|
-
* {@link ImageProviderAdapter}. The dispatch functions in `index.ts` and the
|
|
270
|
-
* cost lookup in `cost.ts` read the registry by id, so adding a provider is a
|
|
271
|
-
* single registry entry — not new branches spread across generate/edit/cost.
|
|
272
|
-
*/
|
|
273
|
-
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region src/image/provider.d.ts
|
|
274
249
|
/**
|
|
275
250
|
* A single image provider. A thin wrapper over the provider's `@ai-sdk/*` image
|
|
276
251
|
* model, plus the metadata the layer needs to route by tier, resolve keys, and
|
|
277
252
|
* meter spend.
|
|
278
253
|
*/
|
|
279
254
|
interface ImageProviderAdapter {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
255
|
+
/** Provider id, matching the key it is registered under in {@link PROVIDERS}. */
|
|
256
|
+
readonly id: ImageProviderId;
|
|
257
|
+
/** Tier → model id map, used when a call does not pass an explicit `model`. */
|
|
258
|
+
readonly tierModels: Readonly<Record<ImageTier, string>>;
|
|
259
|
+
/** Env var read for the API key when no key is supplied in config. */
|
|
260
|
+
readonly apiKeyEnv: string;
|
|
261
|
+
/**
|
|
262
|
+
* Build the AI SDK `ImageModel` for a model id. Prefers the passed `apiKey`,
|
|
263
|
+
* else the adapter's `apiKeyEnv`. Throws `MotifError` when neither is present
|
|
264
|
+
* (callers translate this into a `Result.err`). Building a model performs no
|
|
265
|
+
* network I/O.
|
|
266
|
+
*/
|
|
267
|
+
readonly resolveModel: (modelId: string, apiKey?: string) => ImageModel;
|
|
268
|
+
/**
|
|
269
|
+
* Static per-model USD/**image** table (best-effort; cited per adapter). This
|
|
270
|
+
* is multiplied by the returned image count to form the call total.
|
|
271
|
+
*
|
|
272
|
+
* Cost contract: if an adapter instead surfaces a cost on
|
|
273
|
+
* `result.providerMetadata` (the preferred source; see
|
|
274
|
+
* {@link costFromProviderMetadata}), that value MUST already be the **call
|
|
275
|
+
* total** across all `n` images — NOT a per-image figure. `priceUsdByModel`
|
|
276
|
+
* is per-image; `providerMetadata.cost` is the whole call. These two paths
|
|
277
|
+
* intentionally differ, so an adapter must not populate a per-image number
|
|
278
|
+
* into `providerMetadata.cost`.
|
|
279
|
+
*/
|
|
280
|
+
readonly priceUsdByModel: Readonly<Record<string, number>>;
|
|
306
281
|
}
|
|
307
282
|
/**
|
|
308
283
|
* The provider registry. Every id in {@link ImageProviderId}'s closed part maps
|
|
309
284
|
* to its adapter; the open union tail means a lookup can still miss, so access
|
|
310
285
|
* goes through {@link getProviderAdapter}.
|
|
311
286
|
*/
|
|
312
|
-
declare const PROVIDERS: Record<ImageProviderId, ImageProviderAdapter>;
|
|
287
|
+
export declare const PROVIDERS: Record<ImageProviderId, ImageProviderAdapter>;
|
|
313
288
|
/**
|
|
314
289
|
* Look up an adapter by provider id, throwing a `MotifError` for an unknown
|
|
315
290
|
* provider (callers catch this into a `Result.err`).
|
|
316
291
|
*/
|
|
317
|
-
declare function getProviderAdapter(provider: ImageProviderId): ImageProviderAdapter;
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
* Google (Gemini) provider adapter.
|
|
321
|
-
*
|
|
322
|
-
* Builds a Vercel AI SDK `ImageModel` from `@ai-sdk/google`. Building a model
|
|
323
|
-
* performs no network I/O — the request only happens when `generateImage`
|
|
324
|
-
* invokes `model.doGenerate`. Gemini supports both text→image generation and
|
|
325
|
-
* multi-image-in → image-out editing (with an optional mask), which is the core
|
|
326
|
-
* operation this layer normalizes.
|
|
327
|
-
*/
|
|
328
|
-
|
|
292
|
+
export declare function getProviderAdapter(provider: ImageProviderId): ImageProviderAdapter;
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/image/google.d.ts
|
|
329
295
|
/**
|
|
330
296
|
* Tier → Gemini image model id.
|
|
331
297
|
*
|
|
@@ -333,111 +299,49 @@ declare function getProviderAdapter(provider: ImageProviderId): ImageProviderAda
|
|
|
333
299
|
* consumer, see the design doc). `gemini-2.5-flash-image` is the proven-reachable
|
|
334
300
|
* floor; the preview ids may require allowlist/tier access.
|
|
335
301
|
*/
|
|
336
|
-
declare const GOOGLE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
302
|
+
export declare const GOOGLE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
337
303
|
/** Env var read for the Google API key when `apiKey` is not supplied in config. */
|
|
338
|
-
declare const GOOGLE_API_KEY_ENV = "GOOGLE_GENERATIVE_AI_API_KEY";
|
|
339
|
-
|
|
304
|
+
export declare const GOOGLE_API_KEY_ENV = "GOOGLE_GENERATIVE_AI_API_KEY";
|
|
305
|
+
//#endregion
|
|
306
|
+
//#region src/image/openai.d.ts
|
|
340
307
|
/**
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* Builds a Vercel AI SDK `ImageModel` from `@ai-sdk/openai`. Building a model
|
|
344
|
-
* performs no network I/O — the request only happens when `generateImage`
|
|
345
|
-
* invokes `model.doGenerate`.
|
|
308
|
+
* Flare favors speed for everyday generation; Sunburst favors editing precision.
|
|
309
|
+
* Explicit model ids still override tiers, including older GPT Image models.
|
|
346
310
|
*/
|
|
347
|
-
|
|
348
|
-
/** Tier → OpenAI image model id (all tiers → the single gpt-image model). */
|
|
349
|
-
declare const OPENAI_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
311
|
+
export declare const OPENAI_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
350
312
|
/** Env var read for the OpenAI API key when `apiKey` is not supplied in config. */
|
|
351
|
-
declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
* Replicate provider adapter.
|
|
355
|
-
*
|
|
356
|
-
* Builds a Vercel AI SDK `ImageModel` from `@ai-sdk/replicate`. Building a model
|
|
357
|
-
* performs no network I/O — the request only happens when `generateImage`
|
|
358
|
-
* invokes `model.doGenerate`.
|
|
359
|
-
*
|
|
360
|
-
* NOTE: Replicate's SDK names the credential option `apiToken` (not `apiKey`),
|
|
361
|
-
* and reads `REPLICATE_API_TOKEN` from the environment.
|
|
362
|
-
*/
|
|
363
|
-
|
|
313
|
+
export declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
314
|
+
//#endregion
|
|
315
|
+
//#region src/image/replicate.d.ts
|
|
364
316
|
/** Tier → Replicate model id (all tiers → FLUX 1.1 Pro Ultra for now). */
|
|
365
|
-
declare const REPLICATE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
317
|
+
export declare const REPLICATE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
366
318
|
/** Env var read for the Replicate API token when `apiToken` is not in config. */
|
|
367
|
-
declare const REPLICATE_API_KEY_ENV = "REPLICATE_API_TOKEN";
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
* fal provider adapter.
|
|
371
|
-
*
|
|
372
|
-
* Builds a Vercel AI SDK `ImageModel` from `@ai-sdk/fal`. Building a model
|
|
373
|
-
* performs no network I/O — the request only happens when `generateImage`
|
|
374
|
-
* invokes `model.doGenerate`. This is the lightweight fal *image* adapter; the
|
|
375
|
-
* richer `FalClient` fal client (queue, upload, upscale, rmbg, video, tools)
|
|
376
|
-
* is a separate, later fold (design doc §8, phase 1d).
|
|
377
|
-
*
|
|
378
|
-
* ENDPOINT QUIRK (Phase 0): fal's gpt-image endpoint wants `image_size` as a
|
|
379
|
-
* STRING enum (e.g. "1024x1024"), passed at generate time via
|
|
380
|
-
* `providerOptions.fal.image_size` — NOT the AI SDK's generic `size` object.
|
|
381
|
-
* This adapter does NOT auto-inject it; callers pass `providerOptions` when they
|
|
382
|
-
* need a specific size. Example:
|
|
383
|
-
* img.generate({
|
|
384
|
-
* provider: "fal",
|
|
385
|
-
* tier: "balanced",
|
|
386
|
-
* prompt: "...",
|
|
387
|
-
* providerOptions: { fal: { image_size: "1024x1024" } },
|
|
388
|
-
* });
|
|
389
|
-
*/
|
|
390
|
-
|
|
319
|
+
export declare const REPLICATE_API_KEY_ENV = "REPLICATE_API_TOKEN";
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/image/fal.d.ts
|
|
391
322
|
/**
|
|
392
323
|
* Tier → fal model id. For fal, explicit `model:` endpoint ids are the primary
|
|
393
324
|
* path (any fal endpoint resolves via passthrough); this tier map is a
|
|
394
325
|
* convenience covering the two most common (FLUX Pro Ultra + gpt-image).
|
|
395
326
|
*/
|
|
396
|
-
declare const FAL_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
327
|
+
export declare const FAL_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
397
328
|
/** Env var read for the fal key when `apiKey` is not supplied in config. */
|
|
398
|
-
declare const FAL_API_KEY_ENV = "FAL_KEY";
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
* Per-call cost tracking for the image layer.
|
|
402
|
-
*
|
|
403
|
-
* Preference order:
|
|
404
|
-
* 1. A cost surfaced by the provider on `result.providerMetadata` (most image
|
|
405
|
-
* providers do NOT surface one today, so this is usually absent).
|
|
406
|
-
* 2. A static per-model table, owned per-adapter (`priceUsdByModel`) and read
|
|
407
|
-
* from the provider registry (see sources in each adapter).
|
|
408
|
-
* 3. Unknown → `{ usd: 0, source: "unknown" }`.
|
|
409
|
-
*/
|
|
410
|
-
|
|
329
|
+
export declare const FAL_API_KEY_ENV = "FAL_KEY";
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region src/image/cost.d.ts
|
|
411
332
|
/**
|
|
412
333
|
* Extract a provider-reported total cost from a `generateImage` result's
|
|
413
334
|
* `providerMetadata`, if the provider surfaces a numeric `cost`. The shape is
|
|
414
335
|
* `{ [provider]: { ...; cost?: number } }`. Returns undefined otherwise.
|
|
415
336
|
*/
|
|
416
|
-
declare function costFromProviderMetadata(providerMetadata: unknown): number | undefined;
|
|
337
|
+
export declare function costFromProviderMetadata(providerMetadata: unknown): number | undefined;
|
|
417
338
|
/**
|
|
418
339
|
* Normalized per-call cost for a generation. Prefers a provider-metadata cost,
|
|
419
340
|
* then the static table (× image count), then unknown.
|
|
420
341
|
*/
|
|
421
|
-
declare function costForImages(provider: ImageProviderId, modelId: string, providerMetadata: unknown, imageCount: number): ImageCost;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
* `@howells/motif-sdk/image` — provider-agnostic image generation + editing.
|
|
425
|
-
*
|
|
426
|
-
* ESM-only subpath export, built on the Vercel AI SDK image interface
|
|
427
|
-
* (`generateImage`, `@ai-sdk/*`). Additive to the fal-specific `FalClient`
|
|
428
|
-
* surface; reuses the SDK's Result convention (`Result<T, MotifError>` — no
|
|
429
|
-
* thrown exceptions). Google (Gemini) is the only provider in Phase 1a.
|
|
430
|
-
*
|
|
431
|
-
* @example
|
|
432
|
-
* ```ts
|
|
433
|
-
* import { createMotifImage } from "@howells/motif-sdk/image";
|
|
434
|
-
*
|
|
435
|
-
* const img = createMotifImage({ defaultProvider: "google" });
|
|
436
|
-
* const r = await img.generate({ tier: "fast", prompt: "a bare concrete wall" });
|
|
437
|
-
* if (r.isOk()) console.log(r.value.images[0].mediaType, r.value.cost);
|
|
438
|
-
* ```
|
|
439
|
-
*/
|
|
440
|
-
|
|
342
|
+
export declare function costForImages(provider: ImageProviderId, modelId: string, providerMetadata: unknown, imageCount: number): ImageCost;
|
|
343
|
+
//#endregion
|
|
344
|
+
//#region src/image/index.d.ts
|
|
441
345
|
/**
|
|
442
346
|
* Create a provider-agnostic image client.
|
|
443
347
|
*
|
|
@@ -445,6 +349,6 @@ declare function costForImages(provider: ImageProviderId, modelId: string, provi
|
|
|
445
349
|
* @param deps - INTERNAL testing seam. Defaults to the real AI SDK `generateImage`
|
|
446
350
|
* and the built-in provider adapters; tests inject fakes here to run offline.
|
|
447
351
|
*/
|
|
448
|
-
declare function createMotifImage(config?: MotifImageConfig, deps?: MotifImageDeps): MotifImageClient;
|
|
449
|
-
|
|
450
|
-
export {
|
|
352
|
+
export declare function createMotifImage(config?: MotifImageConfig, deps?: MotifImageDeps): MotifImageClient;
|
|
353
|
+
//#endregion
|
|
354
|
+
export type { BestOfNOptions, BestOfNResult, EditImageOptions, GenerateImageOptions, ImageCost, ImageCostSource, ImageJudge, ImageProviderAdapter, ImageProviderId, ImageTier, MotifImageClient, MotifImageConfig, MotifImageFile, MotifImageResult };
|