@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.cjs CHANGED
@@ -506,6 +506,32 @@ var IMAGE_MODELS = [
506
506
  logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/characters/1787909065794-k9a7zz.png"
507
507
  }
508
508
  },
509
+ {
510
+ // References switch to the edit endpoint: the first is the image to edit,
511
+ // the rest (up to 4) guide it.
512
+ id: "ideogram-4.5",
513
+ aliases: [],
514
+ label: "Ideogram 4.5",
515
+ type: "image",
516
+ adapter: "fal",
517
+ providerModelId: "ideogram/v4.5",
518
+ lifecycle: "active",
519
+ exposure: ["cowork", "space_builder"],
520
+ constraints: {
521
+ aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3", "5:4", "4:5"],
522
+ sizes: ["1K", "2K"],
523
+ qualityOptions: ["auto", "low", "medium", "high"],
524
+ references: { images: 5 },
525
+ supports: ["quality", "count", "seed"]
526
+ },
527
+ defaults: { size: "2K", aspectRatio: "1:1", quality: "medium", count: 1 },
528
+ usage: { ...IMAGE_USAGE, slug: "ideogram" },
529
+ pricingKind: "image_size",
530
+ display: {
531
+ provider: "ideogram",
532
+ 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."
533
+ }
534
+ },
509
535
  {
510
536
  id: "seedream-5-0-pro",
511
537
  aliases: ["seedream-4-5"],
@@ -3695,6 +3721,7 @@ function createFalAdapter(deps = defaultDeps) {
3695
3721
  id: "fal",
3696
3722
  generateImage: (req, ctx) => {
3697
3723
  throwIfAborted(ctx.signal);
3724
+ if (isIdeogram(ctx.model.providerModelId)) return generateIdeogramImage(req, ctx, deps);
3698
3725
  return generateMuseImage(req, ctx, deps);
3699
3726
  },
3700
3727
  generateVideo: (req, ctx) => {
@@ -3951,6 +3978,72 @@ async function generateMuseImage(req, ctx, deps) {
3951
3978
  raw: payload
3952
3979
  };
3953
3980
  }
3981
+ var IDEOGRAM_MODEL_IDS = /* @__PURE__ */ new Set(["ideogram/v4.5"]);
3982
+ function isIdeogram(providerModelId) {
3983
+ return IDEOGRAM_MODEL_IDS.has(providerModelId.toLowerCase());
3984
+ }
3985
+ var IDEOGRAM_SIZES = {
3986
+ "1:1": { "1K": "1024x1024", "2K": "2048x2048" },
3987
+ "16:9": { "1K": "1280x720", "2K": "2560x1440" },
3988
+ "9:16": { "1K": "720x1280", "2K": "1440x2560" },
3989
+ "4:3": { "1K": "1152x864", "2K": "2304x1728" },
3990
+ "3:4": { "1K": "864x1152", "2K": "1728x2304" },
3991
+ "3:2": { "1K": "1248x832", "2K": "2496x1664" },
3992
+ "2:3": { "1K": "832x1248", "2K": "1664x2496" },
3993
+ "5:4": { "1K": "1120x896", "2K": "2240x1792" },
3994
+ "4:5": { "1K": "896x1120", "2K": "1792x2240" }
3995
+ };
3996
+ function parseExactSize(value) {
3997
+ const match = /^(\d+)x(\d+)$/.exec(value ?? "");
3998
+ return match ? { width: Number(match[1]), height: Number(match[2]) } : void 0;
3999
+ }
4000
+ function ideogramImageSize(req) {
4001
+ const exact = parseExactSize(req.exactSize);
4002
+ if (exact) return exact;
4003
+ if (req.aspectRatio === void 0 || req.aspectRatio === "adaptive") return void 0;
4004
+ return parseExactSize(IDEOGRAM_SIZES[req.aspectRatio]?.[req.size === "1K" ? "1K" : "2K"]);
4005
+ }
4006
+ async function generateIdeogramImage(req, ctx, deps) {
4007
+ const [source, ...references] = (req.references ?? []).map(refToUrl);
4008
+ const input = { prompt: req.prompt, num_images: req.count ?? 1 };
4009
+ if (req.quality !== void 0 && req.quality !== "auto") input.quality = req.quality;
4010
+ if (req.seed !== void 0) input.seed = req.seed;
4011
+ const id = ctx.model.providerModelId;
4012
+ let endpoint = id;
4013
+ if (source === void 0) {
4014
+ input.enable_prompt_expansion = false;
4015
+ const size = ideogramImageSize(req);
4016
+ if (size) input.image_size = size;
4017
+ } else {
4018
+ endpoint = `${id}/edit`;
4019
+ input.image_url = source;
4020
+ input.edit_precision = "high";
4021
+ if (references.length > 0) input.reference_image_urls = references;
4022
+ }
4023
+ const payload = await runJob(ctx, deps, endpoint, input);
4024
+ const parsed = museImageResultSchema.safeParse(payload);
4025
+ const images = parsed.success ? parsed.data.images ?? [] : [];
4026
+ const files = await Promise.all(
4027
+ images.flatMap((img) => {
4028
+ if (img.url === void 0) return [];
4029
+ return [decodeImage(ctx, img.url, img.content_type ?? void 0)];
4030
+ })
4031
+ );
4032
+ if (files.length === 0) {
4033
+ throw new ModelKitError({
4034
+ code: "provider_rejected",
4035
+ message: "fal Ideogram returned no image",
4036
+ provider: "fal",
4037
+ model: ctx.model.id,
4038
+ retryable: false
4039
+ });
4040
+ }
4041
+ return {
4042
+ images: files.map((f) => ({ bytes: f.bytes, mime: f.mime })),
4043
+ usage: imageUsage(ctx, req, files.length),
4044
+ raw: payload
4045
+ };
4046
+ }
3954
4047
  var H3_MAX_MODEL_IDS = /* @__PURE__ */ new Set([
3955
4048
  "minimax/h3-max",
3956
4049
  "minimax/h3-max/reference-to-video"