@howells/motif-sdk 2.0.0 → 5.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 +66 -94
- package/dist/image.d.ts +33 -50
- package/dist/image.js +1145 -249
- package/dist/index.cjs +5430 -1278
- package/dist/index.d.cts +1137 -3180
- package/dist/index.d.ts +1137 -3180
- package/dist/index.js +5412 -1249
- package/package.json +16 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @howells/motif-sdk
|
|
2
2
|
|
|
3
|
-
Public Node SDK for Motif
|
|
3
|
+
Public Node SDK for Motif: Task-first image, video and utility work on fal.ai, plus a provider-agnostic image layer.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,129 +8,102 @@ Public Node SDK for Motif fal.ai generation, editing, utility tools, and model m
|
|
|
8
8
|
npm install @howells/motif-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Run a Task
|
|
12
12
|
|
|
13
|
-
The
|
|
14
|
-
|
|
15
|
-
The examples in this section use the low-level `FalClient`, the fal-native client for fal-specific capabilities (queue, upload, upscale, background removal, video, and utility tools).
|
|
13
|
+
The Task client, `createMotif`, is the fal surface: name a Task and, optionally, a Tier, and Motif chooses the Model, builds its request and runs it on fal. `createMotifImage` (`@howells/motif-sdk/image`) is the provider-agnostic generate/edit layer across openrouter, openai, replicate, and fal. See [Image Layer](#image-layer-howellsmotif-sdkimage) below.
|
|
16
14
|
|
|
17
15
|
```ts
|
|
18
|
-
import {
|
|
16
|
+
import { createMotif } from "@howells/motif-sdk";
|
|
19
17
|
|
|
20
|
-
const motif =
|
|
21
|
-
apiKey: process.env.FAL_KEY!,
|
|
22
|
-
retries: 3,
|
|
23
|
-
timeout: 120_000,
|
|
24
|
-
});
|
|
18
|
+
const motif = createMotif(); // reads FAL_KEY
|
|
25
19
|
|
|
26
20
|
const result = await motif.generate({
|
|
27
|
-
model: "banana2",
|
|
28
21
|
prompt: "editorial product photo",
|
|
29
22
|
resolution: "2K",
|
|
30
|
-
|
|
31
|
-
ephemeral: true,
|
|
23
|
+
tier: "quality",
|
|
32
24
|
});
|
|
33
25
|
|
|
34
26
|
if (result.isErr()) {
|
|
35
27
|
throw result.error;
|
|
36
28
|
}
|
|
37
29
|
|
|
38
|
-
console.log(result.value.
|
|
30
|
+
console.log(result.value.model, result.value.files[0]?.url, result.value.cost);
|
|
39
31
|
```
|
|
40
32
|
|
|
41
|
-
Every
|
|
33
|
+
Every Task function returns `Result<TaskOutput, MotifError>` from `neverthrow` and does not throw for fal request failures; check `isErr()` / `isOk()`.
|
|
34
|
+
|
|
35
|
+
Pass `onProgress(status, queuePosition)` to hear fal's queue state while a run waits: `"queued"` with its place in line, then `"in_progress"`, then `"completed"`. Passing it sends the run through fal's queue, since only the queue reports state. Models without streaming report state, not a percentage.
|
|
42
36
|
|
|
43
|
-
##
|
|
37
|
+
## Plan Without Calling fal
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
`plan(task, input, { dryRun: true })` resolves the Model and returns the endpoint, body and projected cost with no I/O and no key.
|
|
46
40
|
|
|
47
41
|
```ts
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
quality: "auto",
|
|
57
|
-
syncMode: true,
|
|
58
|
-
});
|
|
42
|
+
const plan = motif.plan(
|
|
43
|
+
"erase",
|
|
44
|
+
{
|
|
45
|
+
image: "https://example.com/room.png",
|
|
46
|
+
prompt: "the chair",
|
|
47
|
+
},
|
|
48
|
+
{ dryRun: true }
|
|
49
|
+
);
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
console.log(
|
|
51
|
+
if (plan.isOk()) {
|
|
52
|
+
console.log(plan.value.model, plan.value.cost);
|
|
53
|
+
}
|
|
62
54
|
```
|
|
63
55
|
|
|
64
|
-
##
|
|
56
|
+
## Stream a Task
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
const job = await motif.submitGeneration({
|
|
68
|
-
model: "gpt2",
|
|
69
|
-
prompt: "gallery poster",
|
|
70
|
-
});
|
|
58
|
+
`stream(task, input, options?)` opens a direct inference stream on the resolved route. Streaming is explicitly supported for GPT Image 2, GPT Image 1.5 and FLUX.2 Dev, including their edit routes. Other routes return `STREAMING_UNSUPPORTED` before any provider request; Motif never substitutes another model or retries a stream.
|
|
71
59
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
60
|
+
```ts
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const opened = await motif.stream(
|
|
63
|
+
"generate",
|
|
64
|
+
{
|
|
65
|
+
model: "gpt2",
|
|
66
|
+
prompt: "editorial product photo",
|
|
67
|
+
references: ["https://example.com/reference.png"],
|
|
68
|
+
},
|
|
69
|
+
{ signal: controller.signal, timeout: 300_000 }
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
if (opened.isErr()) throw opened.error;
|
|
73
|
+
for await (const result of opened.value.events) {
|
|
74
|
+
if (result.isErr()) throw result.error;
|
|
75
|
+
const event = result.value;
|
|
76
|
+
if (event.type === "images") render(event.files);
|
|
77
|
+
if (event.type === "progress") showProgress(event.progress, event.message);
|
|
81
78
|
}
|
|
82
|
-
|
|
83
|
-
const uploaded = await motif.uploadToFalCdn(fileBytes, {
|
|
84
|
-
contentType: "image/png",
|
|
85
|
-
fileName: "reference.png",
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const deleted = await motif.deletePayloads("fal-request-id");
|
|
89
79
|
```
|
|
90
80
|
|
|
91
|
-
|
|
81
|
+
Events use `images`, `progress` or `provider` types. Images carry the same `TaskFile` URL shape as ordinary Task outputs, including data URIs. Progress fractions are normalised only when explicitly between zero and one. The raw provider payload remains available as `raw` or `data`, and SSE event/id metadata is preserved. Preview images depend on the model; an images event is not labelled preview or final, and transport EOF does not prove generation success.
|
|
92
82
|
|
|
93
|
-
|
|
94
|
-
const mask = await motif.runTool({
|
|
95
|
-
tool: "sam3-image",
|
|
96
|
-
input: "https://example.com/input.png",
|
|
97
|
-
options: { prompt: "shoe", max_masks: 2 },
|
|
98
|
-
});
|
|
83
|
+
The handle exposes `plan`, optional `requestId` and `abort()`. Consume its events once. Abort, iterator exit and the overall deadline close local consumption; this does not guarantee cancellation of provider work or a refund. There is no queue submission, reconnection or retry. `plan()` remains a normal execution plan, so its `queued` flag describes `run()`, not `stream()`.
|
|
99
84
|
|
|
100
|
-
|
|
101
|
-
imageUrl: "https://example.com/frame.png",
|
|
102
|
-
prompt: "slow cinematic push-in",
|
|
103
|
-
duration: 5,
|
|
104
|
-
generateAudio: false,
|
|
105
|
-
});
|
|
106
|
-
```
|
|
85
|
+
For a local checkout, `node packages/motif-sdk/examples/stream.mjs --dry-run` prints the resolved request without a provider call. Running it without `--dry-run` spends provider credits; it requires `FAL_KEY` and a built SDK. The runner is a repository example, not a packaged public API.
|
|
107
86
|
|
|
108
87
|
## Main Exports
|
|
109
88
|
|
|
110
|
-
- `
|
|
111
|
-
- `
|
|
112
|
-
- `
|
|
113
|
-
- `
|
|
114
|
-
- `
|
|
115
|
-
- `
|
|
116
|
-
- `
|
|
117
|
-
- `estimateCost`, `estimateVideoCost` - Local cost estimates used by CLI dry runs and SDK previews.
|
|
118
|
-
- `getFalKeyFromEnv` - `@howells/envy` backed `FAL_KEY` parsing.
|
|
89
|
+
- `createMotif` - the Task client: one function per Task plus `run`, `stream`, `plan`, `upload` and `deletePayloads`.
|
|
90
|
+
- `TASKS`, `TASK_IDS`, `TIERS`, `resolveTask`, `modelProfile`, `tierChangesChoice` - the Task registry and Model resolution.
|
|
91
|
+
- `createMotifImage` (`@howells/motif-sdk/image`) - provider-agnostic generate/edit/best-of-N across openrouter, openai, replicate, and fal.
|
|
92
|
+
- `ASPECT_RATIOS`, `RESOLUTIONS`, `FORMAT_PRESETS` - shared sizing metadata.
|
|
93
|
+
- `LOOKS`, `CREATIVE_TAXONOMY`, `enrichPrompt`, `validateCreativeDirection` - house looks and moods.
|
|
94
|
+
- `formatCost`, `sumCosts` - cost formatting and totals.
|
|
95
|
+
- `getFalKeyFromEnv`, `getOpenAiKeyFromEnv` - `@howells/envy` backed key parsing.
|
|
119
96
|
- Re-exported `neverthrow` helpers: `ok`, `err`, `Result`, `ResultAsync`.
|
|
120
97
|
|
|
121
98
|
## Common Types
|
|
122
99
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
- `
|
|
126
|
-
- `UpscaleOptions`, `RemoveBackgroundOptions`, `VideoOptions`, `VideoResponse`
|
|
127
|
-
- `QueuedJob`, `JobStatus`, `FalClientConfig`
|
|
128
|
-
- `ModelConfig`, `AspectRatio`, `Resolution`, `ImageSize`, `ImageQuality`, `BackgroundMode`, `ThinkingLevel`
|
|
129
|
-
- `FalToolConfig`, `FalToolId`, `FalToolRequest`, `FalToolRunOptions`
|
|
100
|
+
- `MotifClient`, `MotifClientConfig`, `TaskInput`, `TaskOutput`, `TaskPlan`, `TaskFile`, `TaskStream`, `TaskStreamEvent`, `TaskStreamOptions`
|
|
101
|
+
- `TaskId`, `Tier`, `TaskDefinition`, `RankedModel`, `TaskRequest`, `TaskResolution`, `ModelProfile`
|
|
102
|
+
- `AspectRatio`, `Resolution`, `CustomImageSize`, `ImageSizeBounds`, `MotifError`
|
|
130
103
|
|
|
131
104
|
## Image Layer (`@howells/motif-sdk/image`)
|
|
132
105
|
|
|
133
|
-
The
|
|
106
|
+
The provider-agnostic image generation + editing layer, for callers who choose the provider and model themselves. It is an ESM-only subpath export, built on the Vercel AI SDK image interface (`ai`'s `generateImage`).
|
|
134
107
|
|
|
135
108
|
```bash
|
|
136
109
|
npm install @howells/motif-sdk
|
|
@@ -139,21 +112,20 @@ npm install @howells/motif-sdk
|
|
|
139
112
|
```ts
|
|
140
113
|
import { createMotifImage } from "@howells/motif-sdk/image";
|
|
141
114
|
|
|
142
|
-
const img = createMotifImage({ defaultProvider: "
|
|
115
|
+
const img = createMotifImage({ defaultProvider: "openrouter" });
|
|
143
116
|
|
|
144
117
|
// text -> image
|
|
145
118
|
const generated = await img.generate({
|
|
146
|
-
|
|
119
|
+
model: "gemini-3.1-flash-image-preview",
|
|
147
120
|
prompt: "a plain room, bare concrete wall",
|
|
148
121
|
aspectRatio: "1:1",
|
|
149
122
|
});
|
|
150
123
|
|
|
151
|
-
// multi-image edit (images + instruction
|
|
124
|
+
// multi-image edit (images + instruction -> image out; masks need the openai provider)
|
|
152
125
|
const edited = await img.edit({
|
|
153
|
-
|
|
126
|
+
model: "gemini-3.1-flash-image-preview",
|
|
154
127
|
images: [roomBytes, tileBytes],
|
|
155
128
|
instruction: "Apply the oak texture from image 2 onto the wall in image 1.",
|
|
156
|
-
mask: surfaceMaskBytes,
|
|
157
129
|
});
|
|
158
130
|
|
|
159
131
|
if (edited.isOk()) {
|
|
@@ -170,14 +142,14 @@ Four providers are implemented, each reading its own API key from the environmen
|
|
|
170
142
|
|
|
171
143
|
| Provider | Env var | Notes |
|
|
172
144
|
| --- | --- | --- |
|
|
173
|
-
| `
|
|
174
|
-
| `openai` | `OPENAI_API_KEY` | GPT Image 2.5 Flare
|
|
145
|
+
| `openrouter` | `OPENROUTER_API_KEY` | Default provider; Gemini gen + edit through OpenRouter (`google/*`), no masks |
|
|
146
|
+
| `openai` | `OPENAI_API_KEY` | GPT Image 2.5 Flare and Sunburst |
|
|
175
147
|
| `replicate` | `REPLICATE_API_TOKEN` | flux-1.1-pro-ultra |
|
|
176
148
|
| `fal` | `FAL_KEY` | fal-hosted adapter |
|
|
177
149
|
|
|
178
|
-
`generate()` and `edit()`
|
|
150
|
+
`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 }`.
|
|
179
151
|
|
|
180
|
-
|
|
152
|
+
Both `gpt-image-2.5-flare` and `gpt-image-2.5-sunburst` support generation and multi-image editing:
|
|
181
153
|
|
|
182
154
|
```ts
|
|
183
155
|
const image = createMotifImage({ defaultProvider: "openai" });
|
|
@@ -192,7 +164,7 @@ const refined = await image.edit({
|
|
|
192
164
|
});
|
|
193
165
|
```
|
|
194
166
|
|
|
195
|
-
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
|
|
167
|
+
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).
|
|
196
168
|
|
|
197
169
|
### Best-of-N with an injectable judge
|
|
198
170
|
|
package/dist/image.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { ImageModel, generateImage } from "ai";
|
|
2
2
|
import { Result } from "neverthrow";
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/** ─── Configuration ──────────────────────────────────────────── */
|
|
5
|
+
/** The network seam: a `fetch`-shaped function. */
|
|
6
|
+
type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
7
|
+
//#endregion
|
|
3
8
|
//#region src/errors.d.ts
|
|
4
9
|
/**
|
|
5
10
|
* `MotifError` and its coercion helper.
|
|
@@ -15,21 +20,18 @@ declare class MotifError extends Error {
|
|
|
15
20
|
/** fal's request-correlation id (from the `x-fal-request-id` header or the
|
|
16
21
|
* error body). Ties a failure back to fal's dashboard/support. */
|
|
17
22
|
readonly requestId?: string;
|
|
18
|
-
|
|
23
|
+
/** Structured context for the failure, e.g. the refused field. */
|
|
24
|
+
readonly details?: Record<string, unknown>;
|
|
25
|
+
constructor(message: string, status: number, code?: string, requestId?: string, details?: Record<string, unknown>);
|
|
19
26
|
}
|
|
20
27
|
//#endregion
|
|
21
28
|
//#region src/image/types.d.ts
|
|
22
|
-
/**
|
|
23
|
-
* Quality/latency tier. Resolves through a provider-aware tier→model map when no
|
|
24
|
-
* explicit `model` id is given. `balanced` is the default when a tier is omitted.
|
|
25
|
-
*/
|
|
26
|
-
type ImageTier = "fast" | "balanced" | "quality" | "hero";
|
|
27
29
|
/**
|
|
28
30
|
* Image provider id. All four Phase 1b adapters are implemented
|
|
29
|
-
* (`
|
|
31
|
+
* (`openrouter`, `openai`, `replicate`, `fal`); the type keeps an open union tail so
|
|
30
32
|
* further adapters can slot in without a breaking type change.
|
|
31
33
|
*/
|
|
32
|
-
type ImageProviderId = "
|
|
34
|
+
type ImageProviderId = "openrouter" | "openai" | "replicate" | "fal" | (string & Record<never, never>);
|
|
33
35
|
/** Source that produced a normalized per-call cost. */
|
|
34
36
|
type ImageCostSource = "provider-metadata" | "table" | "unknown";
|
|
35
37
|
/** Normalized per-call spend attached to every result. */
|
|
@@ -46,10 +48,10 @@ interface ImageCost {
|
|
|
46
48
|
* credential `apiToken`, not `apiKey`.
|
|
47
49
|
*/
|
|
48
50
|
interface MotifImageConfig {
|
|
49
|
-
/** Provider used when a call does not specify one. Defaults to `
|
|
51
|
+
/** Provider used when a call does not specify one. Defaults to `openrouter`. */
|
|
50
52
|
defaultProvider?: ImageProviderId;
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
+
/** OpenRouter provider overrides. `apiKey` falls back to `OPENROUTER_API_KEY`. */
|
|
54
|
+
openrouter?: {
|
|
53
55
|
apiKey?: string;
|
|
54
56
|
};
|
|
55
57
|
/** OpenAI provider overrides. `apiKey` falls back to `OPENAI_API_KEY`. */
|
|
@@ -63,6 +65,13 @@ interface MotifImageConfig {
|
|
|
63
65
|
replicate?: {
|
|
64
66
|
apiToken?: string;
|
|
65
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Replaces global fetch for every provider request. Remote image URLs passed
|
|
70
|
+
* to `edit` are still downloaded by the AI SDK with global fetch.
|
|
71
|
+
*/
|
|
72
|
+
fetch?: FalFetch;
|
|
73
|
+
/** Retries per call for retryable provider failures. AI SDK default: 2. */
|
|
74
|
+
maxRetries?: number;
|
|
66
75
|
/** fal provider overrides. `apiKey` falls back to `FAL_KEY`. */
|
|
67
76
|
fal?: {
|
|
68
77
|
apiKey?: string;
|
|
@@ -72,10 +81,8 @@ interface MotifImageConfig {
|
|
|
72
81
|
interface GenerateImageOptions {
|
|
73
82
|
/** The text prompt. */
|
|
74
83
|
prompt: string;
|
|
75
|
-
/**
|
|
76
|
-
|
|
77
|
-
/** Explicit provider model id. Overrides `tier`. */
|
|
78
|
-
model?: string;
|
|
84
|
+
/** Provider model id. Task resolution chooses it; the image layer never does. */
|
|
85
|
+
model: string;
|
|
79
86
|
/** Provider override for this call. */
|
|
80
87
|
provider?: ImageProviderId;
|
|
81
88
|
/**
|
|
@@ -132,10 +139,8 @@ interface EditImageOptions {
|
|
|
132
139
|
* `images[0]`.
|
|
133
140
|
*/
|
|
134
141
|
mask?: Uint8Array | string;
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
-
/** Explicit provider model id. Overrides `tier`. */
|
|
138
|
-
model?: string;
|
|
142
|
+
/** Provider model id. Task resolution chooses it; the image layer never does. */
|
|
143
|
+
model: string;
|
|
139
144
|
/** Provider override for this call. */
|
|
140
145
|
provider?: ImageProviderId;
|
|
141
146
|
/** Number of images to generate. */
|
|
@@ -238,7 +243,7 @@ interface MotifImageClient {
|
|
|
238
243
|
//#endregion
|
|
239
244
|
//#region src/image/deps.d.ts
|
|
240
245
|
/** A model resolver: builds an AI SDK `ImageModel` for a (provider, model, key). */
|
|
241
|
-
type ResolveImageModel = (provider: ImageProviderId, modelId: string, apiKey?: string) => ImageModel;
|
|
246
|
+
type ResolveImageModel = (provider: ImageProviderId, modelId: string, apiKey?: string, fetch?: FalFetch) => ImageModel;
|
|
242
247
|
/** Internal dependency-injection seam (default: real `generateImage` + adapters). */
|
|
243
248
|
interface MotifImageDeps {
|
|
244
249
|
generateImage?: typeof generateImage;
|
|
@@ -248,14 +253,11 @@ interface MotifImageDeps {
|
|
|
248
253
|
//#region src/image/provider.d.ts
|
|
249
254
|
/**
|
|
250
255
|
* A single image provider. A thin wrapper over the provider's `@ai-sdk/*` image
|
|
251
|
-
* model, plus the metadata the layer needs to
|
|
252
|
-
* meter spend.
|
|
256
|
+
* model, plus the metadata the layer needs to resolve keys and meter spend.
|
|
253
257
|
*/
|
|
254
258
|
interface ImageProviderAdapter {
|
|
255
259
|
/** Provider id, matching the key it is registered under in {@link PROVIDERS}. */
|
|
256
260
|
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
261
|
/** Env var read for the API key when no key is supplied in config. */
|
|
260
262
|
readonly apiKeyEnv: string;
|
|
261
263
|
/**
|
|
@@ -264,7 +266,7 @@ interface ImageProviderAdapter {
|
|
|
264
266
|
* (callers translate this into a `Result.err`). Building a model performs no
|
|
265
267
|
* network I/O.
|
|
266
268
|
*/
|
|
267
|
-
readonly resolveModel: (modelId: string, apiKey?: string) => ImageModel;
|
|
269
|
+
readonly resolveModel: (modelId: string, apiKey?: string, fetch?: FalFetch) => ImageModel;
|
|
268
270
|
/**
|
|
269
271
|
* Static per-model USD/**image** table (best-effort; cited per adapter). This
|
|
270
272
|
* is multiplied by the returned image count to form the call total.
|
|
@@ -291,40 +293,19 @@ export declare const PROVIDERS: Record<ImageProviderId, ImageProviderAdapter>;
|
|
|
291
293
|
*/
|
|
292
294
|
export declare function getProviderAdapter(provider: ImageProviderId): ImageProviderAdapter;
|
|
293
295
|
//#endregion
|
|
294
|
-
//#region src/image/
|
|
295
|
-
/**
|
|
296
|
-
|
|
297
|
-
*
|
|
298
|
-
* Seeded from Material Desk's `RENDER_IMAGE_MODEL_BY_QUALITY` (the driving
|
|
299
|
-
* consumer, see the design doc). `gemini-2.5-flash-image` is the proven-reachable
|
|
300
|
-
* floor; the preview ids may require allowlist/tier access.
|
|
301
|
-
*/
|
|
302
|
-
export declare const GOOGLE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
303
|
-
/** Env var read for the Google API key when `apiKey` is not supplied in config. */
|
|
304
|
-
export declare const GOOGLE_API_KEY_ENV = "GOOGLE_GENERATIVE_AI_API_KEY";
|
|
296
|
+
//#region src/image/openrouter.d.ts
|
|
297
|
+
/** Env var read for the OpenRouter API key when `apiKey` is not supplied in config. */
|
|
298
|
+
export declare const OPENROUTER_API_KEY_ENV = "OPENROUTER_API_KEY";
|
|
305
299
|
//#endregion
|
|
306
300
|
//#region src/image/openai.d.ts
|
|
307
|
-
/**
|
|
308
|
-
* Flare favors speed for everyday generation; Sunburst favors editing precision.
|
|
309
|
-
* Explicit model ids still override tiers, including older GPT Image models.
|
|
310
|
-
*/
|
|
311
|
-
export declare const OPENAI_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
312
301
|
/** Env var read for the OpenAI API key when `apiKey` is not supplied in config. */
|
|
313
302
|
export declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
314
303
|
//#endregion
|
|
315
304
|
//#region src/image/replicate.d.ts
|
|
316
|
-
/** Tier → Replicate model id (all tiers → FLUX 1.1 Pro Ultra for now). */
|
|
317
|
-
export declare const REPLICATE_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
318
305
|
/** Env var read for the Replicate API token when `apiToken` is not in config. */
|
|
319
306
|
export declare const REPLICATE_API_KEY_ENV = "REPLICATE_API_TOKEN";
|
|
320
307
|
//#endregion
|
|
321
308
|
//#region src/image/fal.d.ts
|
|
322
|
-
/**
|
|
323
|
-
* Tier → fal model id. For fal, explicit `model:` endpoint ids are the primary
|
|
324
|
-
* path (any fal endpoint resolves via passthrough); this tier map is a
|
|
325
|
-
* convenience covering the two most common (FLUX Pro Ultra + gpt-image).
|
|
326
|
-
*/
|
|
327
|
-
export declare const FAL_TIER_MODELS: Readonly<Record<ImageTier, string>>;
|
|
328
309
|
/** Env var read for the fal key when `apiKey` is not supplied in config. */
|
|
329
310
|
export declare const FAL_API_KEY_ENV = "FAL_KEY";
|
|
330
311
|
//#endregion
|
|
@@ -335,6 +316,8 @@ export declare const FAL_API_KEY_ENV = "FAL_KEY";
|
|
|
335
316
|
* `{ [provider]: { ...; cost?: number } }`. Returns undefined otherwise.
|
|
336
317
|
*/
|
|
337
318
|
export declare function costFromProviderMetadata(providerMetadata: unknown): number | undefined;
|
|
319
|
+
/** Static per-image USD for a (provider, model), or undefined if unknown. */
|
|
320
|
+
export declare function providerPricePerImageUsd(provider: ImageProviderId, modelId: string): number | undefined;
|
|
338
321
|
/**
|
|
339
322
|
* Normalized per-call cost for a generation. Prefers a provider-metadata cost,
|
|
340
323
|
* then the static table (× image count), then unknown.
|
|
@@ -351,4 +334,4 @@ export declare function costForImages(provider: ImageProviderId, modelId: string
|
|
|
351
334
|
*/
|
|
352
335
|
export declare function createMotifImage(config?: MotifImageConfig, deps?: MotifImageDeps): MotifImageClient;
|
|
353
336
|
//#endregion
|
|
354
|
-
export type { BestOfNOptions, BestOfNResult, EditImageOptions, GenerateImageOptions, ImageCost, ImageCostSource, ImageJudge, ImageProviderAdapter, ImageProviderId,
|
|
337
|
+
export type { BestOfNOptions, BestOfNResult, EditImageOptions, GenerateImageOptions, ImageCost, ImageCostSource, ImageJudge, ImageProviderAdapter, ImageProviderId, MotifImageClient, MotifImageConfig, MotifImageFile, MotifImageResult };
|