mcp-duojie-image 0.5.4 → 0.5.5
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/provider.js +23 -5
- package/package.json +1 -1
package/dist/provider.js
CHANGED
|
@@ -46,8 +46,21 @@ function mapSize(size) {
|
|
|
46
46
|
function isOpenAIImageModel(model) {
|
|
47
47
|
return model === "gpt-image-2";
|
|
48
48
|
}
|
|
49
|
+
function normalizeAspectRatio(aspectRatio) {
|
|
50
|
+
const normalized = aspectRatio?.trim().replace(":", ":").replace(/\s+/g, "");
|
|
51
|
+
const match = normalized?.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
|
|
52
|
+
if (!match)
|
|
53
|
+
return undefined;
|
|
54
|
+
const width = Number(match[1]);
|
|
55
|
+
const height = Number(match[2]);
|
|
56
|
+
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return `${match[1]}:${match[2]}`;
|
|
60
|
+
}
|
|
49
61
|
function parseAspectRatio(aspectRatio) {
|
|
50
|
-
const
|
|
62
|
+
const normalized = normalizeAspectRatio(aspectRatio);
|
|
63
|
+
const match = normalized?.match(/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)$/);
|
|
51
64
|
if (!match)
|
|
52
65
|
return [1, 1];
|
|
53
66
|
return [Number(match[1]), Number(match[2])];
|
|
@@ -78,10 +91,11 @@ function mapOpenAISize(size, aspectRatio) {
|
|
|
78
91
|
};
|
|
79
92
|
if (size === "4K")
|
|
80
93
|
return mapOpenAI4KSize(aspectRatio);
|
|
81
|
-
|
|
94
|
+
const [ratioWidth, ratioHeight] = parseAspectRatio(aspectRatio);
|
|
95
|
+
if (ratioWidth > ratioHeight) {
|
|
82
96
|
return size === "2K" ? "2048x1536" : "1536x1024";
|
|
83
97
|
}
|
|
84
|
-
if (
|
|
98
|
+
if (ratioHeight > ratioWidth) {
|
|
85
99
|
return size === "2K" ? "1536x2048" : "1024x1536";
|
|
86
100
|
}
|
|
87
101
|
return squareBySize[size] ?? "1024x1024";
|
|
@@ -149,7 +163,8 @@ async function generateGeminiImage(config, opts) {
|
|
|
149
163
|
async function generateOpenAIImage(config, opts) {
|
|
150
164
|
const model = opts.model ?? config.model;
|
|
151
165
|
const prompt = opts.negativePrompt ? `${opts.prompt}\n\nAvoid: ${opts.negativePrompt}` : opts.prompt;
|
|
152
|
-
const
|
|
166
|
+
const aspectRatio = normalizeAspectRatio(opts.aspectRatio);
|
|
167
|
+
const size = mapOpenAISize(opts.size ?? "1K", aspectRatio);
|
|
153
168
|
const hasReferenceImages = Boolean(opts.referenceImages?.length);
|
|
154
169
|
const url = `${config.baseUrl}${hasReferenceImages ? "/v1/images/edits" : "/v1/images/generations"}`;
|
|
155
170
|
let body;
|
|
@@ -161,6 +176,9 @@ async function generateOpenAIImage(config, opts) {
|
|
|
161
176
|
form.set("model", model);
|
|
162
177
|
form.set("prompt", prompt);
|
|
163
178
|
form.set("size", size);
|
|
179
|
+
if (aspectRatio) {
|
|
180
|
+
form.set("aspect_ratio", aspectRatio);
|
|
181
|
+
}
|
|
164
182
|
for (const [index, imgPath] of opts.referenceImages.entries()) {
|
|
165
183
|
const data = await resizeIfNeeded(imgPath);
|
|
166
184
|
const bytes = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
@@ -170,7 +188,7 @@ async function generateOpenAIImage(config, opts) {
|
|
|
170
188
|
}
|
|
171
189
|
else {
|
|
172
190
|
headers = { ...headers, "Content-Type": "application/json" };
|
|
173
|
-
body = JSON.stringify({ model, prompt, size });
|
|
191
|
+
body = JSON.stringify({ model, prompt, size, ...(aspectRatio ? { aspect_ratio: aspectRatio } : {}) });
|
|
174
192
|
}
|
|
175
193
|
const res = await fetchWithRetry(url, {
|
|
176
194
|
method: "POST",
|