Enhance image and embedding provider support

- Added new image models for GPT 5.2, 5.3, and 5.4, including capabilities for text-to-image and editing.
- Updated embedding handling to include optional dimensions in requests.
- Introduced support for custom embedding providers, allowing dynamic fetching and validation of custom nodes.
- Improved image generation handling with Codex integration, including progress tracking and error handling.
- Enhanced UI components to support adding custom embeddings and displaying their status.
This commit is contained in:
decolua
2026-04-25 16:22:30 +07:00
parent cca615eaff
commit 0b8bed5793
19 changed files with 1039 additions and 130 deletions

View File

@@ -139,9 +139,22 @@ export async function killAppProcesses() {
}
}
// Resolve npx/9router binary to relaunch after update (cross-platform)
function resolveRelaunchCommand() {
const isWin = process.platform === "win32";
// Prefer `npx 9router` — works regardless of global bin path changes after npm i -g
const npx = isWin ? "npx.cmd" : "npx";
return { cmd: npx, args: [UPDATER_CONFIG.npmPackageName] };
}
// Spawn detached headless updater (Node process) then exit current server
export function spawnUpdaterAndExit(packageName = UPDATER_CONFIG.npmPackageName) {
const updaterPath = ensureRuntimeUpdater(resolveBundledUpdaterPath());
const isTray = process.env.TRAY_MODE === "1";
const relaunch = resolveRelaunchCommand();
// Only relaunch in tray/background mode — foreground CLI loses TTY on exit
const relaunchArgs = isTray ? [...relaunch.args, "--tray", "--skip-update"] : [];
spawn(process.execPath, [updaterPath], {
detached: true,
stdio: "ignore",
@@ -158,6 +171,9 @@ export function spawnUpdaterAndExit(packageName = UPDATER_CONFIG.npmPackageName)
UPDATER_WAIT_MAX_MS: String(UPDATER_CONFIG.waitForExitMaxMs),
UPDATER_WAIT_CHECK_MS: String(UPDATER_CONFIG.waitForExitCheckMs),
UPDATER_APP_PORT: String(UPDATER_CONFIG.appPort),
UPDATER_RELAUNCH: isTray ? "1" : "0",
UPDATER_RELAUNCH_CMD: relaunch.cmd,
UPDATER_RELAUNCH_ARGS: JSON.stringify(relaunchArgs),
},
}).unref();

View File

@@ -131,11 +131,11 @@ function sleep(ms) {
function runInstall() {
state.attempt += 1;
setPhase("installing");
pushLog(`[updater] attempt ${state.attempt}/${maxRetries} — npm i -g ${packageName}`);
pushLog(`[updater] attempt ${state.attempt}/${maxRetries} — npm i -g ${packageName} --prefer-online`);
const isWin = process.platform === "win32";
const cmd = isWin ? "npm.cmd" : "npm";
const args = ["i", "-g", packageName];
const args = ["i", "-g", packageName, "--prefer-online"];
const child = spawn(cmd, args, {
stdio: ["ignore", "pipe", "pipe"],
@@ -172,6 +172,28 @@ function runInstall() {
});
}
function relaunchApp() {
if (process.env.UPDATER_RELAUNCH !== "1") return;
const cmd = process.env.UPDATER_RELAUNCH_CMD;
if (!cmd) return;
let args = [];
try { args = JSON.parse(process.env.UPDATER_RELAUNCH_ARGS || "[]"); } catch { /* noop */ }
const isWin = process.platform === "win32";
try {
const child = spawn(cmd, args, {
detached: true,
stdio: "ignore",
windowsHide: true,
shell: isWin,
env: { ...process.env, UPDATER_RELAUNCH: "", UPDATER_RELAUNCH_CMD: "", UPDATER_RELAUNCH_ARGS: "" },
});
child.unref();
pushLog(`[updater] relaunched: ${cmd} ${args.join(" ")} (pid=${child.pid})`);
} catch (e) {
pushLog(`[updater] relaunch failed: ${e.message}`);
}
}
function finalize(success, exitCode, error) {
state.done = true;
state.success = success;
@@ -179,6 +201,7 @@ function finalize(success, exitCode, error) {
state.error = error;
state.finishedAt = Date.now();
setPhase(success ? "done" : "error");
if (success) relaunchApp();
// Linger so browser can poll final status, then exit & close the port
setTimeout(() => {
try { server.close(); } catch { /* ignore */ }