@shop-os/modelkit 0.2.23 → 0.2.24

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/dist/index.js CHANGED
@@ -396,6 +396,32 @@ var IMAGE_MODELS = [
396
396
  logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/characters/1787909065794-k9a7zz.png"
397
397
  }
398
398
  },
399
+ {
400
+ // References switch to the edit endpoint: the first is the image to edit,
401
+ // the rest (up to 4) guide it.
402
+ id: "ideogram-4.5",
403
+ aliases: [],
404
+ label: "Ideogram 4.5",
405
+ type: "image",
406
+ adapter: "fal",
407
+ providerModelId: "ideogram/v4.5",
408
+ lifecycle: "active",
409
+ exposure: ["cowork", "space_builder"],
410
+ constraints: {
411
+ aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3", "5:4", "4:5"],
412
+ sizes: ["1K", "2K"],
413
+ qualityOptions: ["auto", "low", "medium", "high"],
414
+ references: { images: 5 },
415
+ supports: ["quality", "count", "seed"]
416
+ },
417
+ defaults: { size: "2K", aspectRatio: "1:1", quality: "medium", count: 1 },
418
+ usage: { ...IMAGE_USAGE, slug: "ideogram" },
419
+ pricingKind: "image_size",
420
+ display: {
421
+ provider: "ideogram",
422
+ description: "Ideogram's precise edit model: repeated edits keep the untouched pixels and colours intact, at the source's native resolution. Also generates from text."
423
+ }
424
+ },
399
425
  {
400
426
  id: "seedream-5-0-pro",
401
427
  aliases: ["seedream-4-5"],
@@ -3585,6 +3611,7 @@ function createFalAdapter(deps = defaultDeps) {
3585
3611
  id: "fal",
3586
3612
  generateImage: (req, ctx) => {
3587
3613
  throwIfAborted(ctx.signal);
3614
+ if (isIdeogram(ctx.model.providerModelId)) return generateIdeogramImage(req, ctx, deps);
3588
3615
  return generateMuseImage(req, ctx, deps);
3589
3616
  },
3590
3617
  generateVideo: (req, ctx) => {
@@ -3841,6 +3868,72 @@ async function generateMuseImage(req, ctx, deps) {
3841
3868
  raw: payload
3842
3869
  };
3843
3870
  }
3871
+ var IDEOGRAM_MODEL_IDS = /* @__PURE__ */ new Set(["ideogram/v4.5"]);
3872
+ function isIdeogram(providerModelId) {
3873
+ return IDEOGRAM_MODEL_IDS.has(providerModelId.toLowerCase());
3874
+ }
3875
+ var IDEOGRAM_SIZES = {
3876
+ "1:1": { "1K": "1024x1024", "2K": "2048x2048" },
3877
+ "16:9": { "1K": "1280x720", "2K": "2560x1440" },
3878
+ "9:16": { "1K": "720x1280", "2K": "1440x2560" },
3879
+ "4:3": { "1K": "1152x864", "2K": "2304x1728" },
3880
+ "3:4": { "1K": "864x1152", "2K": "1728x2304" },
3881
+ "3:2": { "1K": "1248x832", "2K": "2496x1664" },
3882
+ "2:3": { "1K": "832x1248", "2K": "1664x2496" },
3883
+ "5:4": { "1K": "1120x896", "2K": "2240x1792" },
3884
+ "4:5": { "1K": "896x1120", "2K": "1792x2240" }
3885
+ };
3886
+ function parseExactSize(value) {
3887
+ const match = /^(\d+)x(\d+)$/.exec(value ?? "");
3888
+ return match ? { width: Number(match[1]), height: Number(match[2]) } : void 0;
3889
+ }
3890
+ function ideogramImageSize(req) {
3891
+ const exact = parseExactSize(req.exactSize);
3892
+ if (exact) return exact;
3893
+ if (req.aspectRatio === void 0 || req.aspectRatio === "adaptive") return void 0;
3894
+ return parseExactSize(IDEOGRAM_SIZES[req.aspectRatio]?.[req.size === "1K" ? "1K" : "2K"]);
3895
+ }
3896
+ async function generateIdeogramImage(req, ctx, deps) {
3897
+ const [source, ...references] = (req.references ?? []).map(refToUrl);
3898
+ const input = { prompt: req.prompt, num_images: req.count ?? 1 };
3899
+ if (req.quality !== void 0 && req.quality !== "auto") input.quality = req.quality;
3900
+ if (req.seed !== void 0) input.seed = req.seed;
3901
+ const id = ctx.model.providerModelId;
3902
+ let endpoint = id;
3903
+ if (source === void 0) {
3904
+ input.enable_prompt_expansion = false;
3905
+ const size = ideogramImageSize(req);
3906
+ if (size) input.image_size = size;
3907
+ } else {
3908
+ endpoint = `${id}/edit`;
3909
+ input.image_url = source;
3910
+ input.edit_precision = "high";
3911
+ if (references.length > 0) input.reference_image_urls = references;
3912
+ }
3913
+ const payload = await runJob(ctx, deps, endpoint, input);
3914
+ const parsed = museImageResultSchema.safeParse(payload);
3915
+ const images = parsed.success ? parsed.data.images ?? [] : [];
3916
+ const files = await Promise.all(
3917
+ images.flatMap((img) => {
3918
+ if (img.url === void 0) return [];
3919
+ return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
3920
+ })
3921
+ );
3922
+ if (files.length === 0) {
3923
+ throw new ModelKitError({
3924
+ code: "provider_rejected",
3925
+ message: "fal Ideogram returned no image",
3926
+ provider: "fal",
3927
+ model: ctx.model.id,
3928
+ retryable: false
3929
+ });
3930
+ }
3931
+ return {
3932
+ images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
3933
+ usage: imageUsage(ctx, req, files.length),
3934
+ raw: payload
3935
+ };
3936
+ }
3844
3937
  var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
3845
3938
  "minimax/h3-max",
3846
3939
  "minimax/h3-max/reference-to-video"