@howells/motif-sdk 6.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/image.d.ts +17 -22
- package/dist/image.js +24 -639
- package/dist/index.cjs +50 -810
- package/dist/index.d.cts +20 -29
- package/dist/index.d.ts +20 -29
- package/dist/index.js +50 -810
- package/dist/registry.d.ts +1750 -0
- package/dist/registry.js +2705 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Every Task function returns `Result<TaskOutput, MotifError>` from `neverthrow` a
|
|
|
34
34
|
|
|
35
35
|
## Curated Models and Tiers
|
|
36
36
|
|
|
37
|
-
The Task client curates
|
|
37
|
+
The Task client curates 23 generation Models, with separate rankings for generation and editing. Both follow Arena, read 29 October 2026. `TASKS.generate` and `TASKS.vary` expose the current choices, Tiers and evidence in `basis` and `rankedAt`. Sunburst and Flare run GPT Image 2.6; Arena has not scored 2.6 yet, so their benchmarks are the GPT Image 2.5 scores, and each carries a `note` saying so. A generation with `references` uses the editing ranking.
|
|
38
38
|
|
|
39
39
|
| Tier | Generation default | Editing default |
|
|
40
40
|
| -------------------- | ------------------ | ----------------- |
|
|
@@ -42,11 +42,11 @@ The Task client curates 24 generation Models, with separate rankings for generat
|
|
|
42
42
|
| `balanced` (default) | Nano Banana 2.1 | Grok Image 2 |
|
|
43
43
|
| `fast` | Nano Banana 2 Lite | Grok |
|
|
44
44
|
|
|
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.
|
|
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.
|
|
46
46
|
|
|
47
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
|
-
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.
|
|
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.
|
|
50
50
|
|
|
51
51
|
Pass `onProgress(status, queuePosition)` to hear fal's queue state while a run waits: `"queued"` with its place in line, then `"processing"`, then `"completed"` (or `"failed"`). Passing it sends the run through fal's queue, since only the queue reports state. Models without streaming report state, not a percentage.
|
|
52
52
|
|
|
@@ -73,7 +73,7 @@ if (plan.isOk()) {
|
|
|
73
73
|
|
|
74
74
|
## Stream a Task
|
|
75
75
|
|
|
76
|
-
`stream(task, input, options?)` opens a direct inference stream on the resolved route. Streaming is explicitly supported for GPT Image 1.5
|
|
76
|
+
`stream(task, input, options?)` opens a direct inference stream on the resolved route. Streaming is explicitly supported for GPT Image 1.5, including its edit route. Other routes return `STREAMING_UNSUPPORTED` before any provider request; Motif never substitutes another model or retries a stream.
|
|
77
77
|
|
|
78
78
|
```ts
|
|
79
79
|
const controller = new AbortController();
|
|
@@ -100,7 +100,7 @@ Events use `images`, `progress` or `provider` types. Images carry the same `Task
|
|
|
100
100
|
|
|
101
101
|
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()`.
|
|
102
102
|
|
|
103
|
-
For a local checkout, `node packages/motif-sdk/examples/stream.mjs
|
|
103
|
+
For a local checkout, `node packages/motif-sdk/examples/stream.mjs` prints the resolved request without a provider call. Adding `--run` spends provider credits; it requires `FAL_KEY` and a built SDK. The runner is a repository example, not a packaged public API.
|
|
104
104
|
|
|
105
105
|
## Main Exports
|
|
106
106
|
|
package/dist/image.d.ts
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@howells/motif-sdk/image` — provider-agnostic image generation + editing.
|
|
3
|
+
*
|
|
4
|
+
* ESM-only subpath export, built on the Vercel AI SDK image interface
|
|
5
|
+
* (`generateImage`, `@ai-sdk/*`). The caller names the provider and model;
|
|
6
|
+
* reuses the SDK's Result convention (`Result<T, MotifError>` — no
|
|
7
|
+
* thrown exceptions). Gemini is reached through OpenRouter.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { createMotifImage } from "@howells/motif-sdk/image";
|
|
12
|
+
*
|
|
13
|
+
* const img = createMotifImage({ defaultProvider: "openrouter" });
|
|
14
|
+
* const r = await img.generate({ model: "gemini-3.1-flash-image", prompt: "a bare concrete wall" });
|
|
15
|
+
* if (r.isOk()) console.log(r.value.images[0].mediaType, r.value.cost);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
1
18
|
import { ImageModel, generateImage } from "ai";
|
|
2
19
|
import { Result } from "neverthrow";
|
|
3
|
-
//#region src/types.d.ts
|
|
4
20
|
/** ─── Configuration ──────────────────────────────────────────── */
|
|
5
21
|
/** The network seam: a `fetch`-shaped function. */
|
|
6
22
|
type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
7
|
-
//#endregion
|
|
8
|
-
//#region src/errors.d.ts
|
|
9
23
|
/**
|
|
10
24
|
* `MotifError` and its coercion helper.
|
|
11
25
|
*
|
|
@@ -24,8 +38,6 @@ declare class MotifError extends Error {
|
|
|
24
38
|
readonly details?: Record<string, unknown>;
|
|
25
39
|
constructor(message: string, status: number, code?: string, requestId?: string, details?: Record<string, unknown>);
|
|
26
40
|
}
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region src/image/types.d.ts
|
|
29
41
|
/**
|
|
30
42
|
* Image provider id. All four Phase 1b adapters are implemented
|
|
31
43
|
* (`openrouter`, `openai`, `replicate`, `fal`); the type keeps an open union tail so
|
|
@@ -240,8 +252,6 @@ interface MotifImageClient {
|
|
|
240
252
|
*/
|
|
241
253
|
bestOfN: (opts: BestOfNOptions) => Promise<Result<BestOfNResult, MotifError>>;
|
|
242
254
|
}
|
|
243
|
-
//#endregion
|
|
244
|
-
//#region src/image/deps.d.ts
|
|
245
255
|
/** A model resolver: builds an AI SDK `ImageModel` for a (provider, model, key). */
|
|
246
256
|
type ResolveImageModel = (provider: ImageProviderId, modelId: string, apiKey?: string, fetch?: FalFetch) => ImageModel;
|
|
247
257
|
/** Internal dependency-injection seam (default: real `generateImage` + adapters). */
|
|
@@ -249,8 +259,6 @@ interface MotifImageDeps {
|
|
|
249
259
|
generateImage?: typeof generateImage;
|
|
250
260
|
resolveModel?: ResolveImageModel;
|
|
251
261
|
}
|
|
252
|
-
//#endregion
|
|
253
|
-
//#region src/image/provider.d.ts
|
|
254
262
|
/**
|
|
255
263
|
* A single image provider. A thin wrapper over the provider's `@ai-sdk/*` image
|
|
256
264
|
* model, plus the metadata the layer needs to resolve keys and meter spend.
|
|
@@ -292,24 +300,14 @@ export declare const PROVIDERS: Record<ImageProviderId, ImageProviderAdapter>;
|
|
|
292
300
|
* provider (callers catch this into a `Result.err`).
|
|
293
301
|
*/
|
|
294
302
|
export declare function getProviderAdapter(provider: ImageProviderId): ImageProviderAdapter;
|
|
295
|
-
//#endregion
|
|
296
|
-
//#region src/image/openrouter.d.ts
|
|
297
303
|
/** Env var read for the OpenRouter API key when `apiKey` is not supplied in config. */
|
|
298
304
|
export declare const OPENROUTER_API_KEY_ENV = "OPENROUTER_API_KEY";
|
|
299
|
-
//#endregion
|
|
300
|
-
//#region src/image/openai.d.ts
|
|
301
305
|
/** Env var read for the OpenAI API key when `apiKey` is not supplied in config. */
|
|
302
306
|
export declare const OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/image/replicate.d.ts
|
|
305
307
|
/** Env var read for the Replicate API token when `apiToken` is not in config. */
|
|
306
308
|
export declare const REPLICATE_API_KEY_ENV = "REPLICATE_API_TOKEN";
|
|
307
|
-
//#endregion
|
|
308
|
-
//#region src/image/fal.d.ts
|
|
309
309
|
/** Env var read for the fal key when `apiKey` is not supplied in config. */
|
|
310
310
|
export declare const FAL_API_KEY_ENV = "FAL_KEY";
|
|
311
|
-
//#endregion
|
|
312
|
-
//#region src/image/cost.d.ts
|
|
313
311
|
/**
|
|
314
312
|
* Extract a provider-reported total cost from a `generateImage` result's
|
|
315
313
|
* `providerMetadata`, if the provider surfaces a numeric `cost`. The shape is
|
|
@@ -323,8 +321,6 @@ export declare function providerPricePerImageUsd(provider: ImageProviderId, mode
|
|
|
323
321
|
* then the static table (× image count), then unknown.
|
|
324
322
|
*/
|
|
325
323
|
export declare function costForImages(provider: ImageProviderId, modelId: string, providerMetadata: unknown, imageCount: number): ImageCost;
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region src/image/index.d.ts
|
|
328
324
|
/**
|
|
329
325
|
* Create a provider-agnostic image client.
|
|
330
326
|
*
|
|
@@ -333,5 +329,4 @@ export declare function costForImages(provider: ImageProviderId, modelId: string
|
|
|
333
329
|
* and the built-in provider adapters; tests inject fakes here to run offline.
|
|
334
330
|
*/
|
|
335
331
|
export declare function createMotifImage(config?: MotifImageConfig, deps?: MotifImageDeps): MotifImageClient;
|
|
336
|
-
//#endregion
|
|
337
332
|
export type { BestOfNOptions, BestOfNResult, EditImageOptions, GenerateImageOptions, ImageCost, ImageCostSource, ImageJudge, ImageProviderAdapter, ImageProviderId, MotifImageClient, MotifImageConfig, MotifImageFile, MotifImageResult };
|