ima2-gen 1.1.21 → 1.1.23
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 +44 -7
- package/bin/commands/video.js +14 -0
- package/bin/ima2.js +14 -4
- package/bin/lib/platform.js +34 -5
- package/docs/README.ko.md +43 -2
- package/lib/agentQueueWorker.js +6 -0
- package/lib/agentRuntime.js +3 -2
- package/lib/atomicWrite.js +14 -0
- package/lib/grokImageAdapter.js +6 -0
- package/lib/grokProxyLauncher.js +5 -3
- package/lib/grokVideoAdapter.js +1 -1
- package/lib/grokVideoPlannerPrompt.js +10 -0
- package/lib/inflight.js +1 -1
- package/lib/oauthLauncher.js +5 -0
- package/lib/videoFrameExtract.js +3 -3
- package/package.json +5 -7
- package/routes/capabilities.js +13 -0
- package/routes/edit.js +2 -1
- package/routes/generate.js +32 -6
- package/routes/health.js +4 -3
- package/routes/multimode.js +2 -1
- package/routes/video.js +35 -3
- package/server.js +29 -2
- package/skills/ima2/SKILL.md +48 -6
- package/ui/dist/.vite/manifest.json +12 -12
- package/ui/dist/assets/{AgentWorkspace-B_hq9CLg.js → AgentWorkspace-C21zqdTZ.js} +1 -1
- package/ui/dist/assets/{CardNewsWorkspace-wD12J7qk.js → CardNewsWorkspace-BN-ga1lG.js} +1 -1
- package/ui/dist/assets/{NodeCanvas-CI_wuPMf.js → NodeCanvas-BbMa4IhI.js} +1 -1
- package/ui/dist/assets/{PromptBuilderPanel-CUTujJUV.js → PromptBuilderPanel-DRwBJRDQ.js} +1 -1
- package/ui/dist/assets/{PromptImportDialog-CUi66jPK.js → PromptImportDialog-Dp85kHCq.js} +2 -2
- package/ui/dist/assets/{PromptImportDiscoverySection-Cm3vrjY4.js → PromptImportDiscoverySection-BE8Q8MLD.js} +1 -1
- package/ui/dist/assets/{PromptImportFolderSection-DOtWTD9n.js → PromptImportFolderSection-PtH5x0sc.js} +1 -1
- package/ui/dist/assets/{PromptLibraryPanel-BMjQegRa.js → PromptLibraryPanel-FnM9tHI9.js} +2 -2
- package/ui/dist/assets/SettingsWorkspace-MARPGyBL.js +1 -0
- package/ui/dist/assets/index-BAFI6htx.js +42 -0
- package/ui/dist/assets/{index-31uVIdt4.js → index-BSXxr_Bt.js} +1 -1
- package/ui/dist/assets/index-DS-ADE7U.css +1 -0
- package/ui/dist/index.html +2 -2
- package/bin/commands/annotate.ts +0 -119
- package/bin/commands/cancel.ts +0 -48
- package/bin/commands/canvas-versions.ts +0 -80
- package/bin/commands/capabilities.ts +0 -110
- package/bin/commands/cardnews.ts +0 -249
- package/bin/commands/comfy.ts +0 -54
- package/bin/commands/config.ts +0 -186
- package/bin/commands/defaults.ts +0 -192
- package/bin/commands/doctor.ts +0 -202
- package/bin/commands/edit.ts +0 -150
- package/bin/commands/gen.ts +0 -214
- package/bin/commands/grok.ts +0 -90
- package/bin/commands/history.ts +0 -146
- package/bin/commands/ls.ts +0 -64
- package/bin/commands/metadata.ts +0 -39
- package/bin/commands/multimode.ts +0 -196
- package/bin/commands/node.ts +0 -166
- package/bin/commands/observability.ts +0 -176
- package/bin/commands/ping.ts +0 -31
- package/bin/commands/prompt-sub/build.ts +0 -101
- package/bin/commands/prompt.ts +0 -492
- package/bin/commands/ps.ts +0 -81
- package/bin/commands/session.ts +0 -266
- package/bin/commands/show.ts +0 -72
- package/bin/commands/skill.ts +0 -70
- package/bin/commands/video.ts +0 -442
- package/bin/ima2.ts +0 -430
- package/bin/lib/args.ts +0 -92
- package/bin/lib/browser-id.ts +0 -16
- package/bin/lib/client.ts +0 -122
- package/bin/lib/config-store.ts +0 -120
- package/bin/lib/destructive-confirm.ts +0 -19
- package/bin/lib/doctor-checks.ts +0 -91
- package/bin/lib/error-hints.ts +0 -23
- package/bin/lib/files.ts +0 -39
- package/bin/lib/output.ts +0 -73
- package/bin/lib/platform.ts +0 -99
- package/bin/lib/recover-output.ts +0 -139
- package/bin/lib/sse.ts +0 -73
- package/bin/lib/star-prompt.ts +0 -97
- package/bin/lib/storage-doctor.ts +0 -39
- package/bin/lib/ui-build.ts +0 -85
- package/config.ts +0 -354
- package/lib/agentCommandParser.ts +0 -69
- package/lib/agentGenerationPlanner.ts +0 -273
- package/lib/agentQuestionResponder.ts +0 -266
- package/lib/agentQueueStore.ts +0 -270
- package/lib/agentQueueWorker.ts +0 -89
- package/lib/agentRuntime.ts +0 -604
- package/lib/agentSettings.ts +0 -72
- package/lib/agentStore.ts +0 -422
- package/lib/agentStoreRows.ts +0 -136
- package/lib/agentTypes.ts +0 -154
- package/lib/apiCachePolicy.ts +0 -11
- package/lib/assetLifecycle.ts +0 -146
- package/lib/canvasVersionStore.ts +0 -223
- package/lib/capabilities.ts +0 -126
- package/lib/cardNewsGenerator.ts +0 -271
- package/lib/cardNewsJobStore.ts +0 -142
- package/lib/cardNewsManifestStore.ts +0 -154
- package/lib/cardNewsPlanner.ts +0 -236
- package/lib/cardNewsPlannerClient.ts +0 -155
- package/lib/cardNewsPlannerPrompt.ts +0 -62
- package/lib/cardNewsPlannerSchema.ts +0 -321
- package/lib/cardNewsRoleTemplateStore.ts +0 -47
- package/lib/cardNewsTemplateStore.ts +0 -252
- package/lib/codexDetect.ts +0 -71
- package/lib/comfyBridge.ts +0 -235
- package/lib/composerSnapshot.ts +0 -33
- package/lib/configKeys.ts +0 -62
- package/lib/db.ts +0 -295
- package/lib/errInfo.ts +0 -43
- package/lib/errorClassify.ts +0 -100
- package/lib/generationCancel.ts +0 -28
- package/lib/generationErrors.ts +0 -238
- package/lib/grokImageAdapter.ts +0 -513
- package/lib/grokMultimodeAdapter.ts +0 -84
- package/lib/grokProxyLauncher.ts +0 -153
- package/lib/grokRuntime.ts +0 -23
- package/lib/grokSizeMapper.ts +0 -71
- package/lib/grokVideoAdapter.ts +0 -458
- package/lib/grokVideoCanvas.ts +0 -26
- package/lib/grokVideoDownload.ts +0 -59
- package/lib/grokVideoPlannerPrompt.ts +0 -67
- package/lib/historyIndex.ts +0 -51
- package/lib/historyList.ts +0 -181
- package/lib/imageMetadata.ts +0 -113
- package/lib/imageMetadataStore.ts +0 -67
- package/lib/imageModels.ts +0 -165
- package/lib/inflight.ts +0 -281
- package/lib/localImportStore.ts +0 -114
- package/lib/logger.ts +0 -161
- package/lib/nodeStore.ts +0 -91
- package/lib/oauthLauncher.ts +0 -94
- package/lib/oauthNormalize.ts +0 -30
- package/lib/oauthProxy/errors.ts +0 -128
- package/lib/oauthProxy/generators.ts +0 -494
- package/lib/oauthProxy/index.ts +0 -28
- package/lib/oauthProxy/prompts.ts +0 -123
- package/lib/oauthProxy/references.ts +0 -45
- package/lib/oauthProxy/runtime.ts +0 -115
- package/lib/oauthProxy/streams.ts +0 -232
- package/lib/oauthProxy/types.ts +0 -9
- package/lib/oauthProxy.ts +0 -3
- package/lib/openDirectory.ts +0 -47
- package/lib/pngInfo.ts +0 -26
- package/lib/promptBuilder/attachments.ts +0 -74
- package/lib/promptBuilder/client.ts +0 -130
- package/lib/promptBuilder/constants.ts +0 -9
- package/lib/promptBuilder/context.ts +0 -36
- package/lib/promptBuilder/errors.ts +0 -12
- package/lib/promptBuilder/requestSchema.ts +0 -56
- package/lib/promptBuilder/responseParser.ts +0 -219
- package/lib/promptBuilder/systemPrompt.ts +0 -135
- package/lib/promptBuilder/transport.ts +0 -94
- package/lib/promptBuilder/types.ts +0 -109
- package/lib/promptImport/curatedSources.ts +0 -141
- package/lib/promptImport/discoveryRegistry.ts +0 -329
- package/lib/promptImport/errors.ts +0 -18
- package/lib/promptImport/githubDiscovery.ts +0 -309
- package/lib/promptImport/githubFolder.ts +0 -397
- package/lib/promptImport/githubSource.ts +0 -257
- package/lib/promptImport/gptImageHints.ts +0 -70
- package/lib/promptImport/parsePromptCandidates.ts +0 -179
- package/lib/promptImport/promptIndex.ts +0 -326
- package/lib/promptImport/rankPromptCandidates.ts +0 -65
- package/lib/promptImport/types.ts +0 -103
- package/lib/promptSafetyPolicy.ts +0 -5
- package/lib/providerOptions.ts +0 -56
- package/lib/referenceImageCompress.ts +0 -84
- package/lib/refs.ts +0 -133
- package/lib/requestLogger.ts +0 -49
- package/lib/responsesDoctor.ts +0 -456
- package/lib/responsesErrors.ts +0 -83
- package/lib/responsesFallback.ts +0 -114
- package/lib/responsesImageAdapter.ts +0 -466
- package/lib/responsesParse.ts +0 -452
- package/lib/responsesTools.ts +0 -28
- package/lib/runtimeContext.ts +0 -146
- package/lib/runtimePorts.ts +0 -105
- package/lib/sessionStore.ts +0 -308
- package/lib/storageMigration.ts +0 -310
- package/lib/styleSheet.ts +0 -139
- package/lib/systemTrash.ts +0 -20
- package/lib/videoContinuity.ts +0 -180
- package/lib/videoFrameExtract.ts +0 -78
- package/lib/videoSeriesChain.ts +0 -29
- package/lib/visibleTextLanguagePolicy.ts +0 -7
- package/routes/agent.ts +0 -308
- package/routes/annotations.ts +0 -118
- package/routes/canvasVersions.ts +0 -69
- package/routes/capabilities.ts +0 -18
- package/routes/cardNews.ts +0 -211
- package/routes/comfy.ts +0 -43
- package/routes/edit.ts +0 -352
- package/routes/generate.ts +0 -492
- package/routes/grok.ts +0 -24
- package/routes/health.ts +0 -123
- package/routes/history.ts +0 -221
- package/routes/imageImport.ts +0 -37
- package/routes/index.ts +0 -52
- package/routes/metadata.ts +0 -77
- package/routes/multimode.ts +0 -499
- package/routes/nodes.ts +0 -578
- package/routes/promptBuilder.ts +0 -37
- package/routes/promptImport.ts +0 -379
- package/routes/prompts.ts +0 -428
- package/routes/quota.ts +0 -89
- package/routes/sessions.ts +0 -317
- package/routes/storage.ts +0 -47
- package/routes/video.ts +0 -300
- package/routes/videoExtended.ts +0 -284
- package/server.ts +0 -293
- package/ui/dist/assets/SettingsWorkspace-PiaVnsdA.js +0 -1
- package/ui/dist/assets/index-CjgnNtgt.css +0 -1
- package/ui/dist/assets/index-Da2s4_-5.js +0 -36
package/lib/grokProxyLauncher.ts
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { type ChildProcess, spawn } from "node:child_process";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { isWin } from "../bin/lib/platform.js";
|
|
5
|
-
import { config } from "../config.js";
|
|
6
|
-
import { findAvailablePort } from "./runtimePorts.js";
|
|
7
|
-
|
|
8
|
-
const rootDir = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
|
-
const PROGROK_LOGIN_COMMAND = ["progrok", "login"].join(" ");
|
|
10
|
-
|
|
11
|
-
type GrokProxyReadyInfo = {
|
|
12
|
-
url: string;
|
|
13
|
-
port: number;
|
|
14
|
-
requestedPort: number;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
type GrokProxyPortInfo = {
|
|
18
|
-
host: string;
|
|
19
|
-
port: number;
|
|
20
|
-
requestedPort: number;
|
|
21
|
-
url: string;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
type GrokProxyOptions = {
|
|
25
|
-
host?: string;
|
|
26
|
-
port?: number;
|
|
27
|
-
progrokBinPath?: string;
|
|
28
|
-
restartDelayMs?: number;
|
|
29
|
-
onPortSelected?: (info: GrokProxyPortInfo) => void;
|
|
30
|
-
onReady?: (info: GrokProxyReadyInfo) => void;
|
|
31
|
-
onExit?: (info: { code: number | null }) => void;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function parseListeningUrl(line: string): { url: string; port: number } | null {
|
|
35
|
-
const match = String(line || "").match(/https?:\/\/(?:127\.0\.0\.1|localhost):(\d+)\/v1/i);
|
|
36
|
-
if (!match) return null;
|
|
37
|
-
const port = Number(match[1]);
|
|
38
|
-
return Number.isFinite(port) ? { url: match[0], port } : null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function isGrokProxyAuthRequiredMessage(line: string): boolean {
|
|
42
|
-
const normalized = String(line || "").toLowerCase();
|
|
43
|
-
return normalized.includes("not logged in")
|
|
44
|
-
&& (normalized.includes(PROGROK_LOGIN_COMMAND) || normalized.includes("ima2 grok login"));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function normalizeGrokProxyMessage(line: string): string {
|
|
48
|
-
const escaped = PROGROK_LOGIN_COMMAND.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
49
|
-
return String(line || "").replace(new RegExp(`\`?${escaped}\`?`, "gi"), "`ima2 grok login`");
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function localBinPath(): string {
|
|
53
|
-
return join(rootDir, "node_modules", ".bin");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export async function startGrokProxy(options: GrokProxyOptions = {}) {
|
|
57
|
-
const host = options.host ?? config.grokProvider.proxyHost;
|
|
58
|
-
const requestedPort = options.port ?? config.grokProvider.proxyPort;
|
|
59
|
-
const restartDelayMs = options.restartDelayMs ?? config.grokProvider.restartDelayMs;
|
|
60
|
-
let currentChild: ChildProcess | null = null;
|
|
61
|
-
let stopping = false;
|
|
62
|
-
let restartTimer: NodeJS.Timeout | null = null;
|
|
63
|
-
let authRequired = false;
|
|
64
|
-
|
|
65
|
-
const scheduleRestart = () => {
|
|
66
|
-
restartTimer = setTimeout(() => {
|
|
67
|
-
void spawnProxy();
|
|
68
|
-
}, restartDelayMs);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const spawnProxy = async () => {
|
|
72
|
-
let port: number;
|
|
73
|
-
try {
|
|
74
|
-
port = await findAvailablePort(requestedPort, { host });
|
|
75
|
-
} catch (err) {
|
|
76
|
-
const e = err as Error & { message?: string };
|
|
77
|
-
console.error(`[grok] failed to select progrok port: ${e.message || e}`);
|
|
78
|
-
if (!stopping) {
|
|
79
|
-
console.log(`[grok] retrying port selection in ${Math.round(restartDelayMs / 1000)}s...`);
|
|
80
|
-
scheduleRestart();
|
|
81
|
-
}
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (port !== requestedPort) {
|
|
85
|
-
console.log(`[grok] requested port ${requestedPort}, actual port ${port}`);
|
|
86
|
-
}
|
|
87
|
-
options.onPortSelected?.({ host, port, requestedPort, url: `http://${host}:${port}/v1` });
|
|
88
|
-
console.log(`Starting bundled progrok proxy for Grok images at http://${host}:${port}/v1 (managed by ima2 serve)...`);
|
|
89
|
-
const progrokBin = options.progrokBinPath ?? join(localBinPath(), isWin ? "progrok.cmd" : "progrok");
|
|
90
|
-
const child = spawn(progrokBin, ["proxy", "--host", host, "--port", String(port)], {
|
|
91
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
92
|
-
shell: isWin,
|
|
93
|
-
windowsHide: true,
|
|
94
|
-
env: process.env,
|
|
95
|
-
});
|
|
96
|
-
currentChild = child;
|
|
97
|
-
authRequired = false;
|
|
98
|
-
|
|
99
|
-
child.stdout?.on("data", (d) => {
|
|
100
|
-
const msg = normalizeGrokProxyMessage(d.toString().trim());
|
|
101
|
-
if (!msg) return;
|
|
102
|
-
console.log(`[grok] ${msg}`);
|
|
103
|
-
for (const line of msg.split(/\r?\n/)) {
|
|
104
|
-
if (isGrokProxyAuthRequiredMessage(line)) authRequired = true;
|
|
105
|
-
const ready = parseListeningUrl(line);
|
|
106
|
-
if (!ready) continue;
|
|
107
|
-
console.log(`[grok] ready for ima2 Grok provider at ${ready.url}`);
|
|
108
|
-
options.onReady?.({ url: ready.url, port: ready.port, requestedPort });
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
child.stderr?.on("data", (d) => {
|
|
113
|
-
const msg = normalizeGrokProxyMessage(d.toString().trim());
|
|
114
|
-
if (msg) console.error(`[grok] ${msg}`);
|
|
115
|
-
for (const line of msg.split(/\r?\n/)) {
|
|
116
|
-
if (isGrokProxyAuthRequiredMessage(line)) authRequired = true;
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
child.on("error", (err) => {
|
|
121
|
-
console.error(`[grok] failed to start progrok proxy: ${err.message}`);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
child.on("exit", (code) => {
|
|
125
|
-
if (currentChild === child) currentChild = null;
|
|
126
|
-
if (stopping) return;
|
|
127
|
-
options.onExit?.({ code });
|
|
128
|
-
if (authRequired && code !== 0) {
|
|
129
|
-
console.error("[grok] Grok OAuth is not logged in. Run `ima2 grok login` to enable Grok images/video.");
|
|
130
|
-
console.error("[grok] Continuing without auto-restarting the Grok proxy. GPT OAuth/API image generation can still run.");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
console.log(`[grok] exited with code ${code}, restarting in ${Math.round(restartDelayMs / 1000)}s...`);
|
|
134
|
-
scheduleRestart();
|
|
135
|
-
});
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
await spawnProxy();
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
get child() {
|
|
142
|
-
return currentChild;
|
|
143
|
-
},
|
|
144
|
-
kill(signal: NodeJS.Signals = "SIGTERM") {
|
|
145
|
-
this.stop(signal);
|
|
146
|
-
},
|
|
147
|
-
stop(signal: NodeJS.Signals = "SIGTERM") {
|
|
148
|
-
stopping = true;
|
|
149
|
-
if (restartTimer) clearTimeout(restartTimer);
|
|
150
|
-
try { currentChild?.kill(signal); } catch {}
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
}
|
package/lib/grokRuntime.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { RouteRuntimeContext } from "./runtimeContext.js";
|
|
2
|
-
|
|
3
|
-
const DEFAULT_GROK_PROXY_HOST = "127.0.0.1";
|
|
4
|
-
const DEFAULT_GROK_PROXY_PORT = 18645;
|
|
5
|
-
|
|
6
|
-
function normalizeBaseUrl(url: string): string {
|
|
7
|
-
return url.replace(/\/v1\/?$/, "").replace(/\/$/, "");
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function getGrokProxyBaseUrl(ctx: RouteRuntimeContext = {}): string {
|
|
11
|
-
const grokCfg = (ctx.config as any)?.grokProvider || {};
|
|
12
|
-
const explicitUrl = (ctx as { grokUrl?: string }).grokUrl;
|
|
13
|
-
if (explicitUrl) return normalizeBaseUrl(explicitUrl);
|
|
14
|
-
|
|
15
|
-
const host = grokCfg.proxyHost || DEFAULT_GROK_PROXY_HOST;
|
|
16
|
-
const port = (ctx as { grokActualPort?: number }).grokActualPort || grokCfg.proxyPort || DEFAULT_GROK_PROXY_PORT;
|
|
17
|
-
return `http://${host}:${port}`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getGrokProxyUrl(ctx: RouteRuntimeContext = {}, path = "/v1"): string {
|
|
21
|
-
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
22
|
-
return `${getGrokProxyBaseUrl(ctx)}${normalizedPath}`;
|
|
23
|
-
}
|
package/lib/grokSizeMapper.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
export type GrokImageSizeParams = {
|
|
2
|
-
aspect_ratio?: string;
|
|
3
|
-
resolution?: "1k" | "2k";
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
const SUPPORTED_ASPECTS = [
|
|
7
|
-
"1:1",
|
|
8
|
-
"16:9",
|
|
9
|
-
"9:16",
|
|
10
|
-
"4:3",
|
|
11
|
-
"3:4",
|
|
12
|
-
"3:2",
|
|
13
|
-
"2:3",
|
|
14
|
-
"2:1",
|
|
15
|
-
"1:2",
|
|
16
|
-
"19.5:9",
|
|
17
|
-
"9:19.5",
|
|
18
|
-
"20:9",
|
|
19
|
-
"9:20",
|
|
20
|
-
] as const;
|
|
21
|
-
|
|
22
|
-
const PRESET_MAP: Record<string, GrokImageSizeParams> = {
|
|
23
|
-
"1024x1024": { aspect_ratio: "1:1", resolution: "1k" },
|
|
24
|
-
"1536x1024": { aspect_ratio: "3:2", resolution: "1k" },
|
|
25
|
-
"1024x1536": { aspect_ratio: "2:3", resolution: "1k" },
|
|
26
|
-
"1360x1024": { aspect_ratio: "4:3", resolution: "1k" },
|
|
27
|
-
"1024x1360": { aspect_ratio: "3:4", resolution: "1k" },
|
|
28
|
-
"1824x1024": { aspect_ratio: "16:9", resolution: "1k" },
|
|
29
|
-
"1024x1824": { aspect_ratio: "9:16", resolution: "1k" },
|
|
30
|
-
"2048x2048": { aspect_ratio: "1:1", resolution: "2k" },
|
|
31
|
-
"2048x1152": { aspect_ratio: "16:9", resolution: "2k" },
|
|
32
|
-
"1152x2048": { aspect_ratio: "9:16", resolution: "2k" },
|
|
33
|
-
"3840x2160": { aspect_ratio: "16:9", resolution: "2k" },
|
|
34
|
-
"2160x3840": { aspect_ratio: "9:16", resolution: "2k" },
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
function parseSize(size: string): { w: number; h: number } | null {
|
|
38
|
-
const match = /^(\d+)x(\d+)$/.exec(size);
|
|
39
|
-
if (!match) return null;
|
|
40
|
-
const w = Number(match[1]);
|
|
41
|
-
const h = Number(match[2]);
|
|
42
|
-
return Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0 ? { w, h } : null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function aspectValue(aspect: string): number {
|
|
46
|
-
const [w, h] = aspect.split(":").map(Number);
|
|
47
|
-
return w / h;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function closestAspect(w: number, h: number): string {
|
|
51
|
-
const target = w / h;
|
|
52
|
-
return SUPPORTED_ASPECTS.reduce((best, aspect) => {
|
|
53
|
-
const bestDistance = Math.abs(Math.log(target / aspectValue(best)));
|
|
54
|
-
const distance = Math.abs(Math.log(target / aspectValue(aspect)));
|
|
55
|
-
return distance < bestDistance ? aspect : best;
|
|
56
|
-
}, "1:1");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function mapSizeToGrokImageParams(size: string | null | undefined): GrokImageSizeParams {
|
|
60
|
-
if (!size || size === "auto") return { aspect_ratio: "auto" };
|
|
61
|
-
const preset = PRESET_MAP[size];
|
|
62
|
-
if (preset) return preset;
|
|
63
|
-
|
|
64
|
-
const parsed = parseSize(size);
|
|
65
|
-
if (!parsed) return { aspect_ratio: "auto" };
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
aspect_ratio: closestAspect(parsed.w, parsed.h),
|
|
69
|
-
resolution: Math.max(parsed.w, parsed.h) >= 2048 || parsed.w * parsed.h >= 2_000_000 ? "2k" : "1k",
|
|
70
|
-
};
|
|
71
|
-
}
|