@chai-ui/core 0.1.0 → 0.2.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
@@ -1,3 +1,15 @@
1
+ <p align="center">
2
+ <a href="https://chai-ui.com"><img src="https://chai-ui.com/chai-wordmark.svg" alt="Chai UI" width="220" /></a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="https://www.npmjs.com/package/@chai-ui/core"><img src="https://img.shields.io/npm/v/@chai-ui/core?label=npm&color=009747" alt="npm version" /></a>
7
+ <a href="https://github.com/kazarazat/chai-ui/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-009747" alt="MIT license" /></a>
8
+ <a href="https://github.com/kazarazat/chai-ui/actions/workflows/ci.yml"><img src="https://github.com/kazarazat/chai-ui/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
9
+ <a href="https://codecov.io/gh/kazarazat/chai-ui"><img src="https://codecov.io/gh/kazarazat/chai-ui/graph/badge.svg" alt="Coverage" /></a>
10
+ <a href="https://chai-ui.com/docs/"><img src="https://img.shields.io/badge/docs-chai--ui.com-009747" alt="Docs" /></a>
11
+ </p>
12
+
1
13
  # @chai-ui/core
2
14
 
3
15
  The headless core behind CHAI's components: the data types, the
@@ -59,10 +59,16 @@ export declare function describeFalError(json: {
59
59
  error?: unknown;
60
60
  detail?: unknown;
61
61
  }, fallback: string): string;
62
- /** Builds the one Fal request body CHAI sends — a prompt, plus an `image_url` when an attached image is available (for image-to-video / edit-shaped models). */
62
+ /**
63
+ * Builds the one Fal request body CHAI sends: the prompt, plus the attached
64
+ * images. Most models take one `image_url` (for image-to-video and
65
+ * edit-shaped models); the models in `IMAGE_LIST_MODELS` take every image
66
+ * as `image_urls`.
67
+ */
63
68
  export declare function buildFalRequestBody(args: {
64
69
  prompt: string;
65
- media?: DroppedMedia;
70
+ attachments?: DroppedMedia[];
71
+ model?: string;
66
72
  }): Record<string, unknown>;
67
73
  /** Pulls the generated media URL out of Fal's result JSON for the given output kind — the response shape differs by modality. */
68
74
  export declare function extractFalResultSrc(json: FalResultResponse, kind: FalOutputKind): string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"fal.d.ts","sourceRoot":"","sources":["../../src/engines/fal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAA6D,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,kHAAkH;AAClH,KAAK,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,uGAAuG;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gHAAgH;IAChH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8HAA8H;IAC9H,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,8EAA8E;IAC9E,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mHAAmH;IACnH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AA6BD,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAGD,2KAA2K;AAC3K,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAStG;AAED,gKAAgK;AAChK,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAI1B;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAIpG;AA0DD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,gBAAgB,CAyDhF;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC3B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GAC5E,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BnE"}
1
+ {"version":3,"file":"fal.d.ts","sourceRoot":"","sources":["../../src/engines/fal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAA6D,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE3D,kHAAkH;AAClH,KAAK,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,uGAAuG;IACvG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gHAAgH;IAChH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8HAA8H;IAC9H,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,8EAA8E;IAC9E,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mHAAmH;IACnH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AA6BD,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAGD,2KAA2K;AAC3K,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAStG;AASD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO1B;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAIpG;AA0DD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,gBAAgB,CAyDhF;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAC3B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CAAO,GAC5E,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BnE"}
@@ -47,11 +47,27 @@ export function describeFalError(json, fallback) {
47
47
  return fallback;
48
48
  }
49
49
  }
50
- /** Builds the one Fal request body CHAI sends — a prompt, plus an `image_url` when an attached image is available (for image-to-video / edit-shaped models). */
50
+ /**
51
+ * Fal models that take their input images as an `image_urls` list (the
52
+ * image being edited first) instead of a single `image_url`. Verified
53
+ * against Fal's catalog 2026-10-03.
54
+ */
55
+ const IMAGE_LIST_MODELS = new Set(["blackforestlabs/flux-3/edit-image"]);
56
+ /**
57
+ * Builds the one Fal request body CHAI sends: the prompt, plus the attached
58
+ * images. Most models take one `image_url` (for image-to-video and
59
+ * edit-shaped models); the models in `IMAGE_LIST_MODELS` take every image
60
+ * as `image_urls`.
61
+ */
51
62
  export function buildFalRequestBody(args) {
52
63
  const body = { prompt: args.prompt };
53
- if (args.media?.kind === "image")
54
- body.image_url = args.media.src;
64
+ const images = (args.attachments ?? []).filter((a) => a.kind === "image").map((a) => a.src);
65
+ if (images.length === 0)
66
+ return body;
67
+ if (args.model && IMAGE_LIST_MODELS.has(args.model))
68
+ body.image_urls = images;
69
+ else
70
+ body.image_url = images[0];
55
71
  return body;
56
72
  }
57
73
  /** Pulls the generated media URL out of Fal's result JSON for the given output kind — the response shape differs by modality. */
@@ -125,7 +141,7 @@ export function createFalEngine(options = {}) {
125
141
  if (!model) {
126
142
  throw new Error(`falEngine: no model configured for outputKind "${outputKind}" — pass \`model\` or \`modelByKind.${outputKind}\`.`);
127
143
  }
128
- const body = buildFalRequestBody({ prompt, media: attachments[0] });
144
+ const body = buildFalRequestBody({ prompt, attachments, model });
129
145
  if (signal?.aborted)
130
146
  throw abortError();
131
147
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"fal.js","sourceRoot":"","sources":["../../src/engines/fal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fal.js","sourceRoot":"","sources":["../../src/engines/fal.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,4 +5,5 @@ export * from "./media-analysis-prompts.js";
5
5
  export * from "./engines/openrouter.js";
6
6
  export * from "./engines/fal.js";
7
7
  export * from "./model-routing.js";
8
+ export * from "./region-edit.js";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -5,4 +5,5 @@ export * from "./media-analysis-prompts.js";
5
5
  export * from "./engines/openrouter.js";
6
6
  export * from "./engines/fal.js";
7
7
  export * from "./model-routing.js";
8
+ export * from "./region-edit.js";
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Region editing: a person marks boxes on an image, each with its own
3
+ * instruction, and the edit model changes only those areas. This file
4
+ * holds the region shape, the models that support it, and the prompt
5
+ * builder that turns regions into what each model reads.
6
+ */
7
+ import type { ModelOption, RegionFormat } from "./types.js";
8
+ /** A box on an image, as fractions of the image's width and height (0 to 1), so it holds at any display size. */
9
+ export interface RegionBox {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ }
15
+ /** One marked area of an image and what should change there. */
16
+ export interface EditRegion {
17
+ id: string;
18
+ /** Its label and color: "Region 1" uses the first region color. Stays the same when other regions are removed. */
19
+ number: number;
20
+ box: RegionBox;
21
+ prompt: string;
22
+ }
23
+ /** The region cap when a model doesn't set `maxRegions`. One per region color. */
24
+ export declare const DEFAULT_MAX_REGIONS = 6;
25
+ /**
26
+ * Edit models on Fal that take regions with their own instructions. A
27
+ * suggested default list, not a requirement: any `ModelOption` can be
28
+ * offered, and one without `regionFormat` gets its regions in words.
29
+ * Verified against Fal's catalog 2026-10-03.
30
+ */
31
+ export declare const PRECISE_EDIT_MODELS: ModelOption[];
32
+ /**
33
+ * Builds the prompt for an image edit. With no regions it's the prompt as
34
+ * typed. With regions:
35
+ *
36
+ * - `"flux-3-boxes"`: an instruction naming each region `<region_N>`,
37
+ * followed by a JSON array with each region's box, the format Flux 3
38
+ * Image reads from the prompt (it has no separate parameter for boxes).
39
+ * - `"text"` (the default): each region's position described in words, for
40
+ * models without box support. Placement is less precise.
41
+ *
42
+ * `prompt` is the change across the whole image and may be empty when every
43
+ * region has its own instruction.
44
+ */
45
+ export declare function buildRegionEditPrompt({ prompt, regions, format, }: {
46
+ prompt: string;
47
+ regions: EditRegion[];
48
+ format?: RegionFormat;
49
+ }): string;
50
+ //# sourceMappingURL=region-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"region-edit.d.ts","sourceRoot":"","sources":["../src/region-edit.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,iHAAiH;AACjH,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,kHAAkH;IAClH,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,EAS5C,CAAC;AAmBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,OAAO,EACP,MAAe,GAChB,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,GAAG,MAAM,CA8BT"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Region editing: a person marks boxes on an image, each with its own
3
+ * instruction, and the edit model changes only those areas. This file
4
+ * holds the region shape, the models that support it, and the prompt
5
+ * builder that turns regions into what each model reads.
6
+ */
7
+ /** The region cap when a model doesn't set `maxRegions`. One per region color. */
8
+ export const DEFAULT_MAX_REGIONS = 6;
9
+ /**
10
+ * Edit models on Fal that take regions with their own instructions. A
11
+ * suggested default list, not a requirement: any `ModelOption` can be
12
+ * offered, and one without `regionFormat` gets its regions in words.
13
+ * Verified against Fal's catalog 2026-10-03.
14
+ */
15
+ export const PRECISE_EDIT_MODELS = [
16
+ {
17
+ id: "blackforestlabs/flux-3/edit-image",
18
+ label: "Flux 3 Image",
19
+ provider: "Black Forest Labs",
20
+ speed: "standard",
21
+ regionFormat: "flux-3-boxes",
22
+ maxRegions: DEFAULT_MAX_REGIONS,
23
+ },
24
+ ];
25
+ /** The image an edit applies to, as Flux 3 Image names it: the first entry of `image_urls`. */
26
+ const SOURCE_IMAGE = "ref_image_0";
27
+ function regionId(region) {
28
+ return `region_${region.number}`;
29
+ }
30
+ /** Flux 3 Image's box order and scale: [top, left, bottom, right], whole numbers from 0 to 1000. */
31
+ function toFluxBox({ x, y, width, height }) {
32
+ const scale = (v) => Math.round(Math.min(1, Math.max(0, v)) * 1000);
33
+ return [scale(y), scale(x), scale(y + height), scale(x + width)];
34
+ }
35
+ function percent(v) {
36
+ return `${Math.round(Math.min(1, Math.max(0, v)) * 100)}%`;
37
+ }
38
+ /**
39
+ * Builds the prompt for an image edit. With no regions it's the prompt as
40
+ * typed. With regions:
41
+ *
42
+ * - `"flux-3-boxes"`: an instruction naming each region `<region_N>`,
43
+ * followed by a JSON array with each region's box, the format Flux 3
44
+ * Image reads from the prompt (it has no separate parameter for boxes).
45
+ * - `"text"` (the default): each region's position described in words, for
46
+ * models without box support. Placement is less precise.
47
+ *
48
+ * `prompt` is the change across the whole image and may be empty when every
49
+ * region has its own instruction.
50
+ */
51
+ export function buildRegionEditPrompt({ prompt, regions, format = "text", }) {
52
+ const overall = prompt.trim();
53
+ if (regions.length === 0)
54
+ return overall;
55
+ if (format === "flux-3-boxes") {
56
+ const changes = regions.map((r) => `<${regionId(r)}>: ${r.prompt.trim()}`).join("; ");
57
+ const record = [
58
+ `In <${SOURCE_IMAGE}>, change only the marked regions: ${changes}.`,
59
+ overall && `Across the whole image: ${overall}.`,
60
+ "Keep everything outside the regions exactly as it is.",
61
+ ]
62
+ .filter(Boolean)
63
+ .join(" ");
64
+ const rows = regions.map((r) => {
65
+ const box = toFluxBox(r.box);
66
+ return { id: regionId(r), kind: "anchor", from: SOURCE_IMAGE, src_bbox: box, tgt_bbox: box, desc: r.prompt.trim() };
67
+ });
68
+ return `${record} ${JSON.stringify(rows)}`;
69
+ }
70
+ const changes = regions
71
+ .map((r) => `Region ${r.number} (from ${percent(r.box.x)} to ${percent(r.box.x + r.box.width)} across and ` +
72
+ `${percent(r.box.y)} to ${percent(r.box.y + r.box.height)} down): ${r.prompt.trim()}.`)
73
+ .join(" ");
74
+ return [`Edit only these areas of the image. ${changes}`, overall && `Across the whole image: ${overall}.`, "Keep everything else unchanged."]
75
+ .filter(Boolean)
76
+ .join(" ");
77
+ }
78
+ //# sourceMappingURL=region-edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"region-edit.js","sourceRoot":"","sources":["../src/region-edit.ts"],"names":[],"mappings":"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"}
package/dist/run.d.ts CHANGED
@@ -42,6 +42,12 @@ export interface Run {
42
42
  createdAt: number;
43
43
  results: Result[];
44
44
  }
45
+ /**
46
+ * A result's `modelId` while auto-select is still choosing the model: the
47
+ * run exists from the moment of submit, so a result card can show progress
48
+ * right away. Replaced by the real model once routing finishes.
49
+ */
50
+ export declare const ROUTING_MODEL_ID = "routing";
45
51
  /**
46
52
  * Fans a `Request` out into one `"queued"` `Result` per model — a run's
47
53
  * results all exist from the start, so a caller can render "3 of 4 done"
package/dist/run.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEhG,MAAM,WAAW,OAAO;IACtB,+LAA+L;IAC/L,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEjF,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wFAAwF;IACxF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,kKAAkK;IAClK,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4SAA4S;IAC5S,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAQD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAa/C;AAMD,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAI/E;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EACxB,KAAK,CAAC,EAAE,KAAK,EACb,WAAW,CAAC,EAAE,UAAU,EAAE,GACzB,GAAG,CASL;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAOlF;AAED,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAM5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/C,WAAW,EAAE,YAAY,EAAE,GAC1B,iBAAiB,GAAG,SAAS,CAO/B"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEhG,MAAM,WAAW,OAAO;IACtB,+LAA+L;IAC/L,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC;AAEjF,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wFAAwF;IACxF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,kKAAkK;IAClK,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4SAA4S;IAC5S,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAQ1C;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,GAAG,CAa/C;AAMD,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAI/E;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EACxB,KAAK,CAAC,EAAE,KAAK,EACb,WAAW,CAAC,EAAE,UAAU,EAAE,GACzB,GAAG,CASL;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,GAAG,CAOlF;AAED,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAM5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EAC/C,WAAW,EAAE,YAAY,EAAE,GAC1B,iBAAiB,GAAG,SAAS,CAO/B"}
package/dist/run.js CHANGED
@@ -3,6 +3,12 @@
3
3
  * transitions over it: pure, framework-free logic here; `useComposer`
4
4
  * (`@chai-ui/react`) is the thin React binding on top.
5
5
  */
6
+ /**
7
+ * A result's `modelId` while auto-select is still choosing the model: the
8
+ * run exists from the moment of submit, so a result card can show progress
9
+ * right away. Replaced by the real model once routing finishes.
10
+ */
11
+ export const ROUTING_MODEL_ID = "routing";
6
12
  let idCounter = 0;
7
13
  function nextId(prefix) {
8
14
  idCounter += 1;
package/dist/run.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -72,7 +72,18 @@ export interface ModelOption {
72
72
  input: number;
73
73
  output: number;
74
74
  };
75
+ /**
76
+ * For image-edit models: how marked regions are sent. `"flux-3-boxes"`
77
+ * writes each region as a box the model reads (Flux 3 Image). Absent, the
78
+ * regions are described in words, which any edit model accepts but
79
+ * places less precisely. See `buildRegionEditPrompt`.
80
+ */
81
+ regionFormat?: RegionFormat;
82
+ /** For image-edit models: the most regions one edit takes. `EditCard` disables "New region" at this many. */
83
+ maxRegions?: number;
75
84
  }
85
+ /** How an edit's regions reach the model — see `ModelOption.regionFormat`. */
86
+ export type RegionFormat = "flux-3-boxes" | "text";
76
87
  /**
77
88
  * A specific generation use case. These names deliberately match the
78
89
  * leaderboard categories at github.com/oolong-tea-2026/arena-ai-leaderboards,
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,KAAK;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,eAAe,GACf,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,YAAY,GACZ,QAAQ,GACR,cAAc,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,6DAA6D;AAC7D,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,WAAW,KAAK;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D;;;;;OAKG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,6GAA6G;IAC7G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG,MAAM,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB,eAAe,GACf,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,YAAY,GACZ,QAAQ,GACR,cAAc,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chai-ui/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "CHAI UI headless core — the Request/Run/Result data model and pluggable generation engines (Fal.ai, OpenRouter, mock). No framework, no rendering.",
5
5
  "license": "MIT",
6
6
  "author": "kazarazat",
@@ -93,13 +93,29 @@ export function describeFalError(json: { error?: unknown; detail?: unknown }, fa
93
93
  }
94
94
  }
95
95
 
96
- /** Builds the one Fal request body CHAI sends — a prompt, plus an `image_url` when an attached image is available (for image-to-video / edit-shaped models). */
96
+ /**
97
+ * Fal models that take their input images as an `image_urls` list (the
98
+ * image being edited first) instead of a single `image_url`. Verified
99
+ * against Fal's catalog 2026-10-03.
100
+ */
101
+ const IMAGE_LIST_MODELS = new Set(["blackforestlabs/flux-3/edit-image"]);
102
+
103
+ /**
104
+ * Builds the one Fal request body CHAI sends: the prompt, plus the attached
105
+ * images. Most models take one `image_url` (for image-to-video and
106
+ * edit-shaped models); the models in `IMAGE_LIST_MODELS` take every image
107
+ * as `image_urls`.
108
+ */
97
109
  export function buildFalRequestBody(args: {
98
110
  prompt: string;
99
- media?: DroppedMedia;
111
+ attachments?: DroppedMedia[];
112
+ model?: string;
100
113
  }): Record<string, unknown> {
101
114
  const body: Record<string, unknown> = { prompt: args.prompt };
102
- if (args.media?.kind === "image") body.image_url = args.media.src;
115
+ const images = (args.attachments ?? []).filter((a) => a.kind === "image").map((a) => a.src);
116
+ if (images.length === 0) return body;
117
+ if (args.model && IMAGE_LIST_MODELS.has(args.model)) body.image_urls = images;
118
+ else body.image_url = images[0];
103
119
  return body;
104
120
  }
105
121
 
@@ -191,7 +207,7 @@ export function createFalEngine(options: FalEngineOptions = {}): GenerationEngin
191
207
  );
192
208
  }
193
209
 
194
- const body = buildFalRequestBody({ prompt, media: attachments[0] });
210
+ const body = buildFalRequestBody({ prompt, attachments, model });
195
211
  if (signal?.aborted) throw abortError();
196
212
 
197
213
  try {
package/src/index.ts CHANGED
@@ -5,3 +5,4 @@ export * from "./media-analysis-prompts.js";
5
5
  export * from "./engines/openrouter.js";
6
6
  export * from "./engines/fal.js";
7
7
  export * from "./model-routing.js";
8
+ export * from "./region-edit.js";
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Region editing: a person marks boxes on an image, each with its own
3
+ * instruction, and the edit model changes only those areas. This file
4
+ * holds the region shape, the models that support it, and the prompt
5
+ * builder that turns regions into what each model reads.
6
+ */
7
+
8
+ import type { ModelOption, RegionFormat } from "./types.js";
9
+
10
+ /** A box on an image, as fractions of the image's width and height (0 to 1), so it holds at any display size. */
11
+ export interface RegionBox {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }
17
+
18
+ /** One marked area of an image and what should change there. */
19
+ export interface EditRegion {
20
+ id: string;
21
+ /** Its label and color: "Region 1" uses the first region color. Stays the same when other regions are removed. */
22
+ number: number;
23
+ box: RegionBox;
24
+ prompt: string;
25
+ }
26
+
27
+ /** The region cap when a model doesn't set `maxRegions`. One per region color. */
28
+ export const DEFAULT_MAX_REGIONS = 6;
29
+
30
+ /**
31
+ * Edit models on Fal that take regions with their own instructions. A
32
+ * suggested default list, not a requirement: any `ModelOption` can be
33
+ * offered, and one without `regionFormat` gets its regions in words.
34
+ * Verified against Fal's catalog 2026-10-03.
35
+ */
36
+ export const PRECISE_EDIT_MODELS: ModelOption[] = [
37
+ {
38
+ id: "blackforestlabs/flux-3/edit-image",
39
+ label: "Flux 3 Image",
40
+ provider: "Black Forest Labs",
41
+ speed: "standard",
42
+ regionFormat: "flux-3-boxes",
43
+ maxRegions: DEFAULT_MAX_REGIONS,
44
+ },
45
+ ];
46
+
47
+ /** The image an edit applies to, as Flux 3 Image names it: the first entry of `image_urls`. */
48
+ const SOURCE_IMAGE = "ref_image_0";
49
+
50
+ function regionId(region: EditRegion): string {
51
+ return `region_${region.number}`;
52
+ }
53
+
54
+ /** Flux 3 Image's box order and scale: [top, left, bottom, right], whole numbers from 0 to 1000. */
55
+ function toFluxBox({ x, y, width, height }: RegionBox): [number, number, number, number] {
56
+ const scale = (v: number) => Math.round(Math.min(1, Math.max(0, v)) * 1000);
57
+ return [scale(y), scale(x), scale(y + height), scale(x + width)];
58
+ }
59
+
60
+ function percent(v: number): string {
61
+ return `${Math.round(Math.min(1, Math.max(0, v)) * 100)}%`;
62
+ }
63
+
64
+ /**
65
+ * Builds the prompt for an image edit. With no regions it's the prompt as
66
+ * typed. With regions:
67
+ *
68
+ * - `"flux-3-boxes"`: an instruction naming each region `<region_N>`,
69
+ * followed by a JSON array with each region's box, the format Flux 3
70
+ * Image reads from the prompt (it has no separate parameter for boxes).
71
+ * - `"text"` (the default): each region's position described in words, for
72
+ * models without box support. Placement is less precise.
73
+ *
74
+ * `prompt` is the change across the whole image and may be empty when every
75
+ * region has its own instruction.
76
+ */
77
+ export function buildRegionEditPrompt({
78
+ prompt,
79
+ regions,
80
+ format = "text",
81
+ }: {
82
+ prompt: string;
83
+ regions: EditRegion[];
84
+ format?: RegionFormat;
85
+ }): string {
86
+ const overall = prompt.trim();
87
+ if (regions.length === 0) return overall;
88
+
89
+ if (format === "flux-3-boxes") {
90
+ const changes = regions.map((r) => `<${regionId(r)}>: ${r.prompt.trim()}`).join("; ");
91
+ const record = [
92
+ `In <${SOURCE_IMAGE}>, change only the marked regions: ${changes}.`,
93
+ overall && `Across the whole image: ${overall}.`,
94
+ "Keep everything outside the regions exactly as it is.",
95
+ ]
96
+ .filter(Boolean)
97
+ .join(" ");
98
+ const rows = regions.map((r) => {
99
+ const box = toFluxBox(r.box);
100
+ return { id: regionId(r), kind: "anchor", from: SOURCE_IMAGE, src_bbox: box, tgt_bbox: box, desc: r.prompt.trim() };
101
+ });
102
+ return `${record} ${JSON.stringify(rows)}`;
103
+ }
104
+
105
+ const changes = regions
106
+ .map(
107
+ (r) =>
108
+ `Region ${r.number} (from ${percent(r.box.x)} to ${percent(r.box.x + r.box.width)} across and ` +
109
+ `${percent(r.box.y)} to ${percent(r.box.y + r.box.height)} down): ${r.prompt.trim()}.`
110
+ )
111
+ .join(" ");
112
+ return [`Edit only these areas of the image. ${changes}`, overall && `Across the whole image: ${overall}.`, "Keep everything else unchanged."]
113
+ .filter(Boolean)
114
+ .join(" ");
115
+ }
package/src/run.ts CHANGED
@@ -42,6 +42,13 @@ export interface Run {
42
42
  results: Result[];
43
43
  }
44
44
 
45
+ /**
46
+ * A result's `modelId` while auto-select is still choosing the model: the
47
+ * run exists from the moment of submit, so a result card can show progress
48
+ * right away. Replaced by the real model once routing finishes.
49
+ */
50
+ export const ROUTING_MODEL_ID = "routing";
51
+
45
52
  let idCounter = 0;
46
53
  function nextId(prefix: string): string {
47
54
  idCounter += 1;
package/src/types.ts CHANGED
@@ -76,8 +76,20 @@ export interface ModelOption {
76
76
  * only from a source you're actively keeping current.
77
77
  */
78
78
  pricePerMillionTokens?: { input: number; output: number };
79
+ /**
80
+ * For image-edit models: how marked regions are sent. `"flux-3-boxes"`
81
+ * writes each region as a box the model reads (Flux 3 Image). Absent, the
82
+ * regions are described in words, which any edit model accepts but
83
+ * places less precisely. See `buildRegionEditPrompt`.
84
+ */
85
+ regionFormat?: RegionFormat;
86
+ /** For image-edit models: the most regions one edit takes. `EditCard` disables "New region" at this many. */
87
+ maxRegions?: number;
79
88
  }
80
89
 
90
+ /** How an edit's regions reach the model — see `ModelOption.regionFormat`. */
91
+ export type RegionFormat = "flux-3-boxes" | "text";
92
+
81
93
  /**
82
94
  * A specific generation use case. These names deliberately match the
83
95
  * leaderboard categories at github.com/oolong-tea-2026/arena-ai-leaderboards,