File size: 3,829 Bytes
253e783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/** Normalizes image generation request overrides against provider/model capabilities. */
import { resolveMediaGeometryOverrides } from "../media-generation/geometry-normalization.js";
import { hasMediaNormalizationEntry } from "../media-generation/runtime-shared.js";
import type {
  ImageGenerationBackground,
  ImageGenerationIgnoredOverride,
  ImageGenerationNormalization,
  ImageGenerationOutputFormat,
  ImageGenerationProvider,
  ImageGenerationQuality,
  ImageGenerationResolution,
  ImageGenerationSourceImage,
} from "./types.js";

type ResolvedImageGenerationOverrides = {
  size?: string;
  aspectRatio?: string;
  resolution?: ImageGenerationResolution;
  quality?: ImageGenerationQuality;
  outputFormat?: ImageGenerationOutputFormat;
  background?: ImageGenerationBackground;
  ignoredOverrides: ImageGenerationIgnoredOverride[];
  normalization?: ImageGenerationNormalization;
};

/** Returns supported image overrides plus ignored/normalized override metadata for replies. */
export function resolveImageGenerationOverrides(params: {
  provider: ImageGenerationProvider;
  model?: string;
  size?: string;
  aspectRatio?: string;
  resolution?: ImageGenerationResolution;
  quality?: ImageGenerationQuality;
  outputFormat?: ImageGenerationOutputFormat;
  background?: ImageGenerationBackground;
  inputImages?: ImageGenerationSourceImage[];
}): ResolvedImageGenerationOverrides {
  // Edit and generate modes can expose different knobs for the same provider.
  const modeCaps = params.inputImages?.length
    ? params.provider.capabilities.edit
    : params.provider.capabilities.generate;
  const geometry = params.provider.capabilities.geometry;
  const sanitized = resolveMediaGeometryOverrides({
    size: params.size,
    aspectRatio: params.aspectRatio,
    resolution: params.resolution,
    capabilities: {
      ...modeCaps,
      sizes: params.model
        ? (geometry?.sizesByModel?.[params.model] ?? geometry?.sizes)
        : geometry?.sizes,
      aspectRatios: params.model
        ? (geometry?.aspectRatiosByModel?.[params.model] ?? geometry?.aspectRatios)
        : geometry?.aspectRatios,
      resolutions: params.model
        ? (geometry?.resolutionsByModel?.[params.model] ?? geometry?.resolutions)
        : geometry?.resolutions,
    },
    fallbackSizes: geometry?.sizes,
  });
  const ignoredOverrides: ImageGenerationIgnoredOverride[] = sanitized.ignoredOverrides;
  let { quality, outputFormat, background } = params;
  const output = params.provider.capabilities.output;
  const qualities =
    (params.model ? output?.qualitiesByModel?.[params.model] : undefined) ?? output?.qualities;
  const formats =
    (params.model ? output?.formatsByModel?.[params.model] : undefined) ?? output?.formats;
  const backgrounds =
    (params.model ? output?.backgroundsByModel?.[params.model] : undefined) ?? output?.backgrounds;

  if (quality && !(qualities ?? []).includes(quality)) {
    ignoredOverrides.push({ key: "quality", value: quality });
    quality = undefined;
  }
  if (outputFormat && !(formats ?? []).includes(outputFormat)) {
    ignoredOverrides.push({ key: "outputFormat", value: outputFormat });
    outputFormat = undefined;
  }
  if (background && !(backgrounds ?? []).includes(background)) {
    ignoredOverrides.push({ key: "background", value: background });
    background = undefined;
  }

  const { normalization } = sanitized;
  return {
    size: sanitized.size,
    aspectRatio: sanitized.aspectRatio,
    resolution: sanitized.resolution,
    quality,
    outputFormat,
    background,
    ignoredOverrides,
    normalization:
      hasMediaNormalizationEntry(normalization.size) ||
      hasMediaNormalizationEntry(normalization.aspectRatio) ||
      hasMediaNormalizationEntry(normalization.resolution)
        ? normalization
        : undefined,
  };
}