@howells/motif-sdk 7.2.0 → 7.3.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 -3
- package/dist/image.d.ts +3 -10
- package/dist/image.js +116 -1709
- package/dist/index.cjs +6471 -6072
- package/dist/index.d.cts +132 -36
- package/dist/index.d.ts +132 -36
- package/dist/index.js +6469 -6073
- package/dist/registry.d.ts +253 -183
- package/dist/registry.js +149 -65
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,8 @@ console.log(result.value.model, result.value.files[0]?.url, result.value.cost);
|
|
|
32
32
|
|
|
33
33
|
Every Task function returns `Result<TaskOutput, MotifError>` from `neverthrow` and does not throw for fal request failures; check `isErr()` / `isOk()`.
|
|
34
34
|
|
|
35
|
+
Failures stay in the Result, including a fal response that is not the JSON it should be (`INVALID_RESPONSE`). A request that can bill, the synchronous run and the queue submission, is attempted once and never retried: if fal gives no clear answer (a connection error, a timeout or a 5xx), the error is `SUBMISSION_UNCERTAIN` and says fal may have accepted and may bill for it, so check fal's dashboard before submitting again. Status polls, result fetches and storage calls cannot bill and are retried. Once fal has accepted a queued run, every failure after that carries `requestId` and `details.endpoint`; pass the id to `resume` to wait for the same job.
|
|
36
|
+
|
|
35
37
|
## Curated Models and Tiers
|
|
36
38
|
|
|
37
39
|
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.
|
|
@@ -44,11 +46,11 @@ The Task client curates 23 generation Models, with separate rankings for generat
|
|
|
44
46
|
|
|
45
47
|
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
48
|
|
|
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.
|
|
49
|
+
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. A plan carries `size`, the exact `{ width, height }` requested (null when the Model decides the pixels), and `modelProfile(id).sizing` says what each resolution tier means for that Model: tiers are not pixel counts. With no `outputFormat`, every Model that takes a format returns PNG (in the spelling its endpoint uses); a Model with no format setting is left alone, and `params.output_format` replaces the default. 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
50
|
|
|
49
51
|
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
52
|
|
|
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
|
|
53
|
+
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 a generation through fal's queue, since only the queue reports state; a tool that runs synchronously reports nothing. Models without streaming report state, not a percentage.
|
|
52
54
|
|
|
53
55
|
Pass `onSubmitted(requestId)` to hear the request id the moment fal's queue accepts the run, before any wait. Keep it: after a restart, `motif.resume(task, input, requestId)` waits for that same job and returns its output, submitting nothing and so paying nothing twice. Passing `onSubmitted` also queues the run.
|
|
54
56
|
|
|
@@ -98,7 +100,7 @@ for await (const result of opened.value.events) {
|
|
|
98
100
|
|
|
99
101
|
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.
|
|
100
102
|
|
|
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()`.
|
|
103
|
+
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, which says whether the Model always uses fal's queue, describes `run()`, not `stream()`.
|
|
102
104
|
|
|
103
105
|
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
106
|
|
package/dist/image.d.ts
CHANGED
|
@@ -20,14 +20,7 @@ import { Result } from "neverthrow";
|
|
|
20
20
|
/** ─── Configuration ──────────────────────────────────────────── */
|
|
21
21
|
/** The network seam: a `fetch`-shaped function. */
|
|
22
22
|
type FalFetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
23
|
-
/**
|
|
24
|
-
* `MotifError` and its coercion helper.
|
|
25
|
-
*
|
|
26
|
-
* Extracted from `server.ts` so `server-tools.ts` can construct errors without
|
|
27
|
-
* importing back into `server.ts` — that import was a dependency cycle. Both
|
|
28
|
-
* `server.ts` and `server-tools.ts` import from here, and `server.ts`
|
|
29
|
-
* re-exports `MotifError` so the package's public surface is unchanged.
|
|
30
|
-
*/
|
|
23
|
+
/** `MotifError` and the fal HTTP error mapping. */
|
|
31
24
|
declare class MotifError extends Error {
|
|
32
25
|
readonly status: number;
|
|
33
26
|
readonly code?: string;
|
|
@@ -118,7 +111,7 @@ interface GenerateImageOptions {
|
|
|
118
111
|
signal?: AbortSignal;
|
|
119
112
|
/**
|
|
120
113
|
* Extra HTTP headers forwarded to the provider request. Fal's non-retained IO
|
|
121
|
-
* (paired with
|
|
114
|
+
* (paired with `MotifClient.deletePayloads`) is
|
|
122
115
|
* `headers: { "X-Fal-Store-IO": "0" }`.
|
|
123
116
|
*/
|
|
124
117
|
headers?: Record<string, string>;
|
|
@@ -163,7 +156,7 @@ interface EditImageOptions {
|
|
|
163
156
|
signal?: AbortSignal;
|
|
164
157
|
/**
|
|
165
158
|
* Extra HTTP headers forwarded to the provider request. Fal's non-retained IO
|
|
166
|
-
* (paired with
|
|
159
|
+
* (paired with `MotifClient.deletePayloads`) is
|
|
167
160
|
* `headers: { "X-Fal-Store-IO": "0" }`.
|
|
168
161
|
*/
|
|
169
162
|
headers?: Record<string, string>;
|