@agent-proxy/gateway 0.11.1 → 0.11.3
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 +1 -2
- package/dist/index.js +107 -68
- package/dist/ui/index.html +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -26,8 +26,7 @@ agent-proxy install
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
默认连接本机上游 `http://127.0.0.1:8317/v1`,网关端口为 `8320`。
|
|
29
|
-
默认运行目录是 `~/.agent-proxy-gateway
|
|
30
|
-
`install` 会合并用户设置并复制受管文件,保留旧目录;自定义实例目录不自动迁移。
|
|
29
|
+
默认运行目录是 `~/.agent-proxy-gateway`。
|
|
31
30
|
按提示输入 API Key 并选择要在 Codex 中显示的模型:
|
|
32
31
|
|
|
33
32
|
- `↑` / `↓` 移动,空格勾选,回车确认。
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var __export = (target, all) => {
|
|
|
13
13
|
|
|
14
14
|
// src/cli.ts
|
|
15
15
|
import fs21 from "fs";
|
|
16
|
-
import
|
|
16
|
+
import path15 from "path";
|
|
17
17
|
import { createHash as createHash3 } from "crypto";
|
|
18
18
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
19
19
|
import bytes2 from "bytes";
|
|
@@ -230,10 +230,7 @@ function managedCatalogFiles(paths) {
|
|
|
230
230
|
return [
|
|
231
231
|
catalogFileFor(paths, "cliproxy"),
|
|
232
232
|
catalogFileFor(paths, "newapi"),
|
|
233
|
-
path2.join(paths.runtimeHome, "codex-catalog.json")
|
|
234
|
-
path2.join(paths.runtimeHome, "zcode-catalog.json"),
|
|
235
|
-
path2.join(paths.runtimeHome, "codebuddy-catalog.json"),
|
|
236
|
-
path2.join(paths.runtimeHome, "workbuddy-catalog.json")
|
|
233
|
+
path2.join(paths.runtimeHome, "codex-catalog.json")
|
|
237
234
|
];
|
|
238
235
|
}
|
|
239
236
|
|
|
@@ -1027,13 +1024,15 @@ function migrateManagedDefaultPaths(config, legacyHome, nextHome) {
|
|
|
1027
1024
|
result.model_merge_json = path6.join(nextHome, "models.json");
|
|
1028
1025
|
return result;
|
|
1029
1026
|
}
|
|
1030
|
-
function managedEntry(name) {
|
|
1031
|
-
return ["config.json", "state.json", "models.json", "models-cache.json", "ui-token", "logs", "gateway.log", "gateway.error.log", "webui.log"].includes(name) || /^(?:cliproxy|newapi|codex|zcode|codebuddy(?:-(?:cn|intl))?|workbuddy(?:-(?:cn|intl))?|qoder(?:-(?:cn|intl))?|agy|opencode-zen)-(?:catalog|metadata)\.json$/.test(name) || /^gateway-\d[\dT:_-]*\.log$/.test(name) || /^(?:config|state)\.json\.(?:bak|backup)[\w.-]*$/.test(name);
|
|
1032
|
-
}
|
|
1033
1027
|
function prepareDefaultInstallMigration(paths, env = process.env, platform = process.platform, launchctlExecutor, manualCodexConfig = false) {
|
|
1034
1028
|
if (env[RUNTIME_HOME_ENV]?.trim() || realPathOrResolve(paths.runtimeHome) !== realPathOrResolve(path6.join(paths.home, DEFAULT_RUNTIME_DIRECTORY)))
|
|
1035
1029
|
return;
|
|
1036
1030
|
const legacyPaths = resolvePaths({ ...env, HOME: paths.home, CODEX_CLIPROXY_HOME: path6.join(paths.home, LEGACY_RUNTIME_DIRECTORY) });
|
|
1031
|
+
const legacyRoot = entryStat(legacyPaths.runtimeHome);
|
|
1032
|
+
if (!legacyRoot || legacyRoot.isSymbolicLink())
|
|
1033
|
+
return;
|
|
1034
|
+
if (!legacyRoot.isDirectory())
|
|
1035
|
+
throw new Error(`Migration source is not a directory: ${legacyPaths.runtimeHome}; preserve this entry and repair it before retrying install`);
|
|
1037
1036
|
const legacyConfig = readObject(legacyPaths.gatewayConfig);
|
|
1038
1037
|
const legacyState = readObject(legacyPaths.stateFile);
|
|
1039
1038
|
if (!legacyConfig && !legacyState)
|
|
@@ -1064,10 +1063,9 @@ function prepareDefaultInstallMigration(paths, env = process.env, platform = pro
|
|
|
1064
1063
|
completeMigration();
|
|
1065
1064
|
},
|
|
1066
1065
|
apply() {
|
|
1067
|
-
const originalEntries = new Set(fs7.existsSync(paths.runtimeHome) ? fs7.readdirSync(paths.runtimeHome) : []);
|
|
1068
1066
|
const snapshots = new Map;
|
|
1069
1067
|
const created = new Set;
|
|
1070
|
-
const createdDirectories = new
|
|
1068
|
+
const createdDirectories = new Map;
|
|
1071
1069
|
let restoreOwner;
|
|
1072
1070
|
let restoreWebUi;
|
|
1073
1071
|
let credentialWritten = false;
|
|
@@ -1076,11 +1074,13 @@ function prepareDefaultInstallMigration(paths, env = process.env, platform = pro
|
|
|
1076
1074
|
if (stat) {
|
|
1077
1075
|
if (!stat.isDirectory())
|
|
1078
1076
|
throw new Error(`Migration target is not a directory: ${directory}`);
|
|
1079
|
-
return;
|
|
1077
|
+
return false;
|
|
1080
1078
|
}
|
|
1081
1079
|
ensureDirectory(path6.dirname(directory));
|
|
1082
1080
|
fs7.mkdirSync(directory, { mode });
|
|
1083
|
-
createdDirectories.
|
|
1081
|
+
createdDirectories.set(directory, mode);
|
|
1082
|
+
fs7.chmodSync(directory, mode);
|
|
1083
|
+
return true;
|
|
1084
1084
|
};
|
|
1085
1085
|
const capture = (file) => {
|
|
1086
1086
|
if (snapshots.has(file) || created.has(file))
|
|
@@ -1094,22 +1094,26 @@ function prepareDefaultInstallMigration(paths, env = process.env, platform = pro
|
|
|
1094
1094
|
created.add(file);
|
|
1095
1095
|
};
|
|
1096
1096
|
const copy = (source, target) => {
|
|
1097
|
+
if (entryStat(target))
|
|
1098
|
+
return;
|
|
1097
1099
|
const stat = fs7.lstatSync(source);
|
|
1098
1100
|
if (stat.isSymbolicLink())
|
|
1099
|
-
|
|
1101
|
+
return;
|
|
1100
1102
|
if (stat.isDirectory()) {
|
|
1101
|
-
|
|
1103
|
+
const mode = stat.mode & 511;
|
|
1104
|
+
if (!ensureDirectory(target, mode | 448))
|
|
1105
|
+
return;
|
|
1106
|
+
createdDirectories.set(target, mode);
|
|
1102
1107
|
for (const name of fs7.readdirSync(source))
|
|
1103
1108
|
copy(path6.join(source, name), path6.join(target, name));
|
|
1109
|
+
fs7.chmodSync(target, mode);
|
|
1104
1110
|
} else if (stat.isFile()) {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
fs7.chmodSync(target, stat.mode & 511);
|
|
1110
|
-
}
|
|
1111
|
+
ensureDirectory(path6.dirname(target));
|
|
1112
|
+
fs7.copyFileSync(source, target, fs7.constants.COPYFILE_EXCL);
|
|
1113
|
+
created.add(target);
|
|
1114
|
+
fs7.chmodSync(target, stat.mode & 511);
|
|
1111
1115
|
} else
|
|
1112
|
-
throw new Error(`
|
|
1116
|
+
throw new Error(`Migration source is not a regular file: ${source}; preserve this entry and repair it before retrying install`);
|
|
1113
1117
|
};
|
|
1114
1118
|
const rollback = () => {
|
|
1115
1119
|
const errors = [];
|
|
@@ -1122,29 +1126,42 @@ function prepareDefaultInstallMigration(paths, env = process.env, platform = pro
|
|
|
1122
1126
|
};
|
|
1123
1127
|
restore(() => restoreWebUi?.());
|
|
1124
1128
|
restore(() => restoreOwner?.());
|
|
1129
|
+
for (const [directory, mode] of createdDirectories)
|
|
1130
|
+
restore(() => {
|
|
1131
|
+
const stat = entryStat(directory);
|
|
1132
|
+
if (stat?.isDirectory())
|
|
1133
|
+
fs7.chmodSync(directory, mode | 448);
|
|
1134
|
+
});
|
|
1125
1135
|
if (credentialWritten)
|
|
1126
1136
|
restore(() => createApiKeyStore(platform, paths.credentialsFile).delete());
|
|
1127
1137
|
for (const [file, snapshot] of snapshots)
|
|
1128
1138
|
restore(() => atomicWrite(file, snapshot.content, snapshot.mode));
|
|
1129
1139
|
for (const file of created)
|
|
1130
1140
|
restore(() => fs7.rmSync(file, { force: true }));
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
+
for (const [directory, mode] of [...createdDirectories].reverse())
|
|
1142
|
+
restore(() => {
|
|
1143
|
+
const stat = entryStat(directory);
|
|
1144
|
+
if (!stat?.isDirectory())
|
|
1145
|
+
return;
|
|
1146
|
+
if (fs7.readdirSync(directory).length === 0)
|
|
1147
|
+
fs7.rmdirSync(directory);
|
|
1148
|
+
else
|
|
1149
|
+
fs7.chmodSync(directory, mode);
|
|
1150
|
+
});
|
|
1141
1151
|
if (errors.length)
|
|
1142
1152
|
throw new Error(`Default installation restore incomplete: ${errors.join("; ")}`);
|
|
1143
1153
|
};
|
|
1144
1154
|
try {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1155
|
+
const sourceRoot = entryStat(legacyPaths.runtimeHome);
|
|
1156
|
+
if (!sourceRoot?.isDirectory())
|
|
1157
|
+
throw new Error(`Migration source is not a directory: ${legacyPaths.runtimeHome}; preserve this entry and repair it before retrying install`);
|
|
1158
|
+
const runtimeMode = sourceRoot.mode & 511;
|
|
1159
|
+
if (ensureDirectory(paths.runtimeHome, runtimeMode | 448))
|
|
1160
|
+
createdDirectories.set(paths.runtimeHome, runtimeMode);
|
|
1161
|
+
for (const name of fs7.readdirSync(legacyPaths.runtimeHome)) {
|
|
1162
|
+
if (name !== "credentials.json")
|
|
1163
|
+
copy(path6.join(legacyPaths.runtimeHome, name), path6.join(paths.runtimeHome, name));
|
|
1164
|
+
}
|
|
1148
1165
|
capture(paths.gatewayConfig);
|
|
1149
1166
|
const backupStamp = Date.now().toString();
|
|
1150
1167
|
for (const file of [paths.gatewayConfig, paths.stateFile]) {
|
|
@@ -1197,6 +1214,8 @@ function prepareDefaultInstallMigration(paths, env = process.env, platform = pro
|
|
|
1197
1214
|
atomicWrite(paths.stateFile, `${JSON.stringify(installedState, null, 2)}
|
|
1198
1215
|
`, fs7.statSync(paths.stateFile).mode & 511);
|
|
1199
1216
|
};
|
|
1217
|
+
if (createdDirectories.has(paths.runtimeHome))
|
|
1218
|
+
fs7.chmodSync(paths.runtimeHome, runtimeMode);
|
|
1200
1219
|
return rollback;
|
|
1201
1220
|
} catch (error) {
|
|
1202
1221
|
try {
|
|
@@ -4437,11 +4456,12 @@ async function rebuildCatalog(paths, config, proxyModels, modelsConfigFile) {
|
|
|
4437
4456
|
|
|
4438
4457
|
// src/gateway-composition.ts
|
|
4439
4458
|
import { PluginRegistry as PluginRegistry2, compileModelPattern } from "@agent-proxy/plugin-api";
|
|
4440
|
-
import
|
|
4441
|
-
import {
|
|
4442
|
-
import {
|
|
4443
|
-
import {
|
|
4444
|
-
import {
|
|
4459
|
+
import path12 from "path";
|
|
4460
|
+
import { createZcodePlugin, ZCODE_MODEL_PATTERNS, ZCODE_RUNTIME_ARTIFACTS } from "@agent-proxy/zcode";
|
|
4461
|
+
import { createCodebuddyPlugin, CODEBUDDY_MODEL_PATTERNS, CODEBUDDY_RUNTIME_ARTIFACTS } from "@agent-proxy/codebuddy";
|
|
4462
|
+
import { createQoderPlugin, QODER_MODEL_PATTERNS, QODER_RUNTIME_ARTIFACTS } from "@agent-proxy/qoder";
|
|
4463
|
+
import { createAgyPlugin, AGY_MODEL_PATTERNS, AGY_RUNTIME_ARTIFACTS } from "@agent-proxy/agy";
|
|
4464
|
+
import { createOpencodeZenPlugin, OPENCODE_ZEN_MODEL_PATTERNS, OPENCODE_ZEN_RUNTIME_ARTIFACTS } from "@agent-proxy/opencode-zen";
|
|
4445
4465
|
|
|
4446
4466
|
// src/process-log.ts
|
|
4447
4467
|
import fs12 from "fs";
|
|
@@ -5377,10 +5397,10 @@ function writeStaticCatalog(paths, config, adapterModels, ownsModel = () => fals
|
|
|
5377
5397
|
`);
|
|
5378
5398
|
return catalog;
|
|
5379
5399
|
}
|
|
5380
|
-
function applyModelCatalogToml(source, active, paths, catalogFile) {
|
|
5400
|
+
function applyModelCatalogToml(source, active, paths, catalogFile, managedFiles) {
|
|
5381
5401
|
const configuredCatalog = readRootTomlString(source, "model_catalog_json");
|
|
5382
5402
|
const legacyCatalogFile = path10.join(paths.codexHome, "cliproxy-catalog.json");
|
|
5383
|
-
if (configuredCatalog && ![...
|
|
5403
|
+
if (configuredCatalog && ![...managedFiles, codexCatalogFile(paths), legacyCatalogFile].includes(configuredCatalog)) {
|
|
5384
5404
|
throw new Error(`Refusing to replace unmanaged model_catalog_json: ${configuredCatalog}`);
|
|
5385
5405
|
}
|
|
5386
5406
|
if (configuredCatalog === undefined && hasRootTomlKey(source, "model_catalog_json")) {
|
|
@@ -5392,7 +5412,11 @@ function applyModelCatalogToml(source, active, paths, catalogFile) {
|
|
|
5392
5412
|
};
|
|
5393
5413
|
}
|
|
5394
5414
|
var hash = (source) => createHash2("sha256").update(source).digest("hex");
|
|
5395
|
-
async function updateCodexModelCatalog(paths, config, catalogSource, {
|
|
5415
|
+
async function updateCodexModelCatalog(paths, config, catalogSource, {
|
|
5416
|
+
refreshAdapters = false,
|
|
5417
|
+
manual: manualOverride,
|
|
5418
|
+
managedFiles = managedCatalogFiles(paths)
|
|
5419
|
+
} = {}) {
|
|
5396
5420
|
const stateSource = fs14.existsSync(paths.stateFile) ? fs14.readFileSync(paths.stateFile, "utf8") : undefined;
|
|
5397
5421
|
const state = stateSource === undefined ? {} : JSON.parse(stateSource);
|
|
5398
5422
|
const manual = manualOverride ?? state.codexConfigManaged === false;
|
|
@@ -5400,7 +5424,7 @@ async function updateCodexModelCatalog(paths, config, catalogSource, { refreshAd
|
|
|
5400
5424
|
const source = tomlExisted ? fs14.readFileSync(paths.configToml, "utf8") : "";
|
|
5401
5425
|
const catalogPath = codexCatalogFile(paths);
|
|
5402
5426
|
const active = config.upstreamOnly === true;
|
|
5403
|
-
const { patchedToml, previousCatalog } = manual ? { patchedToml: source, previousCatalog: readRootTomlString(source, "model_catalog_json") ?? null } : applyModelCatalogToml(source, active, paths, catalogPath);
|
|
5427
|
+
const { patchedToml, previousCatalog } = manual ? { patchedToml: source, previousCatalog: readRootTomlString(source, "model_catalog_json") ?? null } : applyModelCatalogToml(source, active, paths, catalogPath, managedFiles);
|
|
5404
5428
|
const tomlChanged = patchedToml !== source;
|
|
5405
5429
|
const previousSnapshot = fs14.existsSync(catalogPath) ? fs14.readFileSync(catalogPath, "utf8") : undefined;
|
|
5406
5430
|
let snapshotWritten = false;
|
|
@@ -7043,6 +7067,18 @@ var installedPatterns = [
|
|
|
7043
7067
|
function isInstalledPluginModel(model) {
|
|
7044
7068
|
return installedPatterns.some((pattern) => Boolean(pattern.match(model)));
|
|
7045
7069
|
}
|
|
7070
|
+
function installedPluginArtifactFiles(runtimePaths = resolvePaths()) {
|
|
7071
|
+
return [
|
|
7072
|
+
...ZCODE_RUNTIME_ARTIFACTS,
|
|
7073
|
+
...CODEBUDDY_RUNTIME_ARTIFACTS,
|
|
7074
|
+
...QODER_RUNTIME_ARTIFACTS,
|
|
7075
|
+
...AGY_RUNTIME_ARTIFACTS,
|
|
7076
|
+
...OPENCODE_ZEN_RUNTIME_ARTIFACTS
|
|
7077
|
+
].map((name) => path12.join(runtimePaths.runtimeHome, name));
|
|
7078
|
+
}
|
|
7079
|
+
function managedRuntimeCatalogFiles(runtimePaths = resolvePaths()) {
|
|
7080
|
+
return [...managedCatalogFiles(runtimePaths), ...installedPluginArtifactFiles(runtimePaths)];
|
|
7081
|
+
}
|
|
7046
7082
|
function createConfiguredPluginRegistry(config, dependencies = {}, processLog, runtimePaths = resolvePaths(), apiKey, catalogMode = config.upstreamOnly === true ? "manual" : "dynamic") {
|
|
7047
7083
|
config = { ...config };
|
|
7048
7084
|
const host = createGatewayHostServices(config, processLog, runtimePaths, apiKey);
|
|
@@ -7164,16 +7200,19 @@ function rebuildStaticCatalog2(paths, config, dependencies = {}, options = {}) {
|
|
|
7164
7200
|
return rebuildStaticCatalog(paths, config, createCatalogSource(config, dependencies), options);
|
|
7165
7201
|
}
|
|
7166
7202
|
function updateCodexModelCatalog2(paths, config, dependencies = {}, options = {}) {
|
|
7167
|
-
return updateCodexModelCatalog(paths, config, createCatalogSource(config, dependencies),
|
|
7203
|
+
return updateCodexModelCatalog(paths, config, createCatalogSource(config, dependencies), {
|
|
7204
|
+
...options,
|
|
7205
|
+
managedFiles: managedRuntimeCatalogFiles(paths)
|
|
7206
|
+
});
|
|
7168
7207
|
}
|
|
7169
7208
|
// src/webui.ts
|
|
7170
7209
|
import fs20 from "fs";
|
|
7171
|
-
import
|
|
7210
|
+
import path14 from "path";
|
|
7172
7211
|
import { randomBytes } from "crypto";
|
|
7173
7212
|
|
|
7174
7213
|
// src/app-server.ts
|
|
7175
7214
|
import fs18 from "fs";
|
|
7176
|
-
import
|
|
7215
|
+
import path13 from "path";
|
|
7177
7216
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
7178
7217
|
import { dlopen } from "bun:ffi";
|
|
7179
7218
|
var GLOBAL_OPTIONS_WITH_VALUE = new Set([
|
|
@@ -7394,9 +7433,9 @@ function parseWindowsCommandLine(commandLine) {
|
|
|
7394
7433
|
}
|
|
7395
7434
|
function windowsSystemPath(...segments) {
|
|
7396
7435
|
const systemRoot = process.env.SystemRoot || process.env.windir;
|
|
7397
|
-
if (!systemRoot || !
|
|
7436
|
+
if (!systemRoot || !path13.win32.isAbsolute(systemRoot))
|
|
7398
7437
|
throw new Error("Windows system root is unavailable");
|
|
7399
|
-
return
|
|
7438
|
+
return path13.win32.join(systemRoot, ...segments);
|
|
7400
7439
|
}
|
|
7401
7440
|
function listWindowsProcesses() {
|
|
7402
7441
|
const powershell = windowsSystemPath("System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
@@ -7889,14 +7928,14 @@ var REQUEST_LOG_TAIL_BYTES = 64 * 1024;
|
|
|
7889
7928
|
var REQUEST_LOG_DEFAULT_PAGE_SIZE = 100;
|
|
7890
7929
|
var REQUEST_LOG_MAX_PAGE_SIZE = 500;
|
|
7891
7930
|
var RESTART_DELAY_MS = 400;
|
|
7892
|
-
var UI_HTML_PATH =
|
|
7931
|
+
var UI_HTML_PATH = path14.resolve(import.meta.dir, "../dist/ui/index.html");
|
|
7893
7932
|
function webUiContextForInstance(configPath, defaultPaths) {
|
|
7894
7933
|
const resolved = realPathOrResolve(configPath);
|
|
7895
7934
|
if (resolved === realPathOrResolve(defaultPaths.gatewayConfig))
|
|
7896
7935
|
return { paths: defaultPaths };
|
|
7897
7936
|
return {
|
|
7898
7937
|
paths: {
|
|
7899
|
-
...resolvePaths({ HOME: defaultPaths.home, CODEX_HOME: defaultPaths.codexHome },
|
|
7938
|
+
...resolvePaths({ HOME: defaultPaths.home, CODEX_HOME: defaultPaths.codexHome }, path14.dirname(resolved)),
|
|
7900
7939
|
gatewayConfig: resolved
|
|
7901
7940
|
},
|
|
7902
7941
|
instanceOnly: true
|
|
@@ -8133,7 +8172,7 @@ function configResponse(paths, providerDeps, instanceOnly = false) {
|
|
|
8133
8172
|
excludedOther
|
|
8134
8173
|
},
|
|
8135
8174
|
detected: {
|
|
8136
|
-
zcode: zcodeConfigPresent(providerDeps?.zcodeHome ??
|
|
8175
|
+
zcode: zcodeConfigPresent(providerDeps?.zcodeHome ?? path14.join(paths.home, ".zcode")),
|
|
8137
8176
|
codebuddy: codebuddyCredentialsPresent(codebuddyAuthDir),
|
|
8138
8177
|
codebuddyAccountLabel: accountLabel ?? null,
|
|
8139
8178
|
qoder: qoderSources.length > 0,
|
|
@@ -8193,7 +8232,7 @@ function requestLogsResponse(config, paths, url) {
|
|
|
8193
8232
|
}
|
|
8194
8233
|
const all = names.filter((name) => isRequestLogName(name)).flatMap((name) => {
|
|
8195
8234
|
try {
|
|
8196
|
-
const stat = fs20.statSync(
|
|
8235
|
+
const stat = fs20.statSync(path14.join(dir, name));
|
|
8197
8236
|
return [{
|
|
8198
8237
|
name,
|
|
8199
8238
|
size: stat.size,
|
|
@@ -8871,7 +8910,7 @@ function timestamp() {
|
|
|
8871
8910
|
return new Date().toISOString().replace(/[-:]/g, "").slice(0, 15).replace("T", "");
|
|
8872
8911
|
}
|
|
8873
8912
|
function backupConfig(file) {
|
|
8874
|
-
fs21.mkdirSync(
|
|
8913
|
+
fs21.mkdirSync(path15.dirname(file), { recursive: true });
|
|
8875
8914
|
const existed = fs21.existsSync(file);
|
|
8876
8915
|
const backup = `${file}.bak-cliproxy-gateway-${timestamp()}`;
|
|
8877
8916
|
if (existed)
|
|
@@ -8885,7 +8924,7 @@ function hash2(contents) {
|
|
|
8885
8924
|
}
|
|
8886
8925
|
function restoreBackup(file, record) {
|
|
8887
8926
|
if (record.existed) {
|
|
8888
|
-
fs21.mkdirSync(
|
|
8927
|
+
fs21.mkdirSync(path15.dirname(file), { recursive: true });
|
|
8889
8928
|
fs21.copyFileSync(record.backup, file);
|
|
8890
8929
|
} else {
|
|
8891
8930
|
fs21.rmSync(file, { force: true });
|
|
@@ -8947,12 +8986,12 @@ function removeManagedRuntimeFiles(paths, options = {}) {
|
|
|
8947
8986
|
for (const file of [
|
|
8948
8987
|
...options.preserveGatewayConfig ? [] : [paths.gatewayConfig],
|
|
8949
8988
|
...options.preserveState ? [] : [paths.stateFile],
|
|
8950
|
-
...
|
|
8951
|
-
|
|
8989
|
+
...managedRuntimeCatalogFiles(paths),
|
|
8990
|
+
path15.join(paths.runtimeHome, "catalog-metadata.json"),
|
|
8952
8991
|
paths.modelMergeFile,
|
|
8953
8992
|
paths.stdoutLog,
|
|
8954
|
-
|
|
8955
|
-
|
|
8993
|
+
path15.join(paths.runtimeHome, "webui.log"),
|
|
8994
|
+
path15.join(paths.runtimeHome, LEGACY_STDERR_LOG)
|
|
8956
8995
|
]) {
|
|
8957
8996
|
fs21.rmSync(file, { force: true });
|
|
8958
8997
|
}
|
|
@@ -9173,7 +9212,7 @@ async function installCurrent(options, completeMigration) {
|
|
|
9173
9212
|
applyRoutingMode(config, paths, upstreamOnly);
|
|
9174
9213
|
const installSelector = stringOption(options, "select");
|
|
9175
9214
|
if (!manualCodexConfig) {
|
|
9176
|
-
applyModelCatalogToml(currentToml, upstreamOnly && !isSelectNone(installSelector), paths, codexCatalogFile(paths));
|
|
9215
|
+
applyModelCatalogToml(currentToml, upstreamOnly && !isSelectNone(installSelector), paths, codexCatalogFile(paths), managedRuntimeCatalogFiles(paths));
|
|
9177
9216
|
}
|
|
9178
9217
|
const previousApiKey = readApiKey(true);
|
|
9179
9218
|
const apiKey = getInstallApiKey(config, previousConfig, stringOption(options, "key-env"), {
|
|
@@ -9203,7 +9242,7 @@ async function installCurrent(options, completeMigration) {
|
|
|
9203
9242
|
console.log(`Selected ${selectedModels.length} ${upstreamLabel(config)} models.`);
|
|
9204
9243
|
}
|
|
9205
9244
|
config.selectedModels = selectedModels;
|
|
9206
|
-
const { patchedToml: modelCatalogToml } = manualCodexConfig ? { patchedToml: currentToml } : applyModelCatalogToml(currentToml, upstreamOnly, paths, codexCatalogFile(paths));
|
|
9245
|
+
const { patchedToml: modelCatalogToml } = manualCodexConfig ? { patchedToml: currentToml } : applyModelCatalogToml(currentToml, upstreamOnly, paths, codexCatalogFile(paths), managedRuntimeCatalogFiles(paths));
|
|
9207
9246
|
const previousState = switching ? fs21.readFileSync(paths.stateFile, "utf8") : undefined;
|
|
9208
9247
|
const priorState = switching ? loadJson(paths.stateFile) : undefined;
|
|
9209
9248
|
const previousManaged = priorState ? isCodexConfigManaged(priorState) && priorState.uninstallClientRestored !== true : true;
|
|
@@ -9416,7 +9455,7 @@ async function uninstall(options) {
|
|
|
9416
9455
|
assertCodexHomeAvailable(paths, false);
|
|
9417
9456
|
uninstallLaunchAgent(paths.launchAgent);
|
|
9418
9457
|
uninstallLaunchAgent(paths.webUiLaunchAgent);
|
|
9419
|
-
const legacyCatalogFile =
|
|
9458
|
+
const legacyCatalogFile = path15.join(paths.codexHome, "cliproxy-catalog.json");
|
|
9420
9459
|
if (restoresClient) {
|
|
9421
9460
|
const currentToml = fs21.existsSync(paths.configToml) ? fs21.readFileSync(paths.configToml, "utf8") : "";
|
|
9422
9461
|
restoreManagedCodexToml(paths, state, currentToml);
|
|
@@ -9607,9 +9646,9 @@ async function models(options) {
|
|
|
9607
9646
|
}
|
|
9608
9647
|
const manualCodexConfig = fs21.existsSync(paths.stateFile) && !isCodexConfigManaged(loadJson(paths.stateFile));
|
|
9609
9648
|
const source = fs21.existsSync(paths.configToml) ? fs21.readFileSync(paths.configToml, "utf8") : "";
|
|
9610
|
-
const legacyCatalogFile =
|
|
9649
|
+
const legacyCatalogFile = path15.join(paths.codexHome, "cliproxy-catalog.json");
|
|
9611
9650
|
if (!manualCodexConfig) {
|
|
9612
|
-
applyModelCatalogToml(source, upstreamOnly, paths, codexCatalogFile(paths));
|
|
9651
|
+
applyModelCatalogToml(source, upstreamOnly, paths, codexCatalogFile(paths), managedRuntimeCatalogFiles(paths));
|
|
9613
9652
|
}
|
|
9614
9653
|
const { modelsConfigFile, rules } = await loadModelOverrideRules(paths, config, Boolean(modelMergeJson));
|
|
9615
9654
|
const selectNone = isSelectNone(selector);
|
|
@@ -9703,7 +9742,7 @@ function serve(options) {
|
|
|
9703
9742
|
if (!fs21.existsSync(configPath))
|
|
9704
9743
|
throw new Error(`Gateway config not found: ${configPath}`);
|
|
9705
9744
|
const config = loadGatewayConfig(configPath);
|
|
9706
|
-
const isProductionInstance = configPath === realPathOrResolve(
|
|
9745
|
+
const isProductionInstance = configPath === realPathOrResolve(path15.join(paths.runtimeHome, "config.json"));
|
|
9707
9746
|
const processLog = isProductionInstance ? { file: paths.stdoutLog, maxBytes: config.maxGatewayLogBytes ?? 0 } : undefined;
|
|
9708
9747
|
startGateway(config, loadRealtimeProviderMode(paths.configToml), paths.upstreamModelsCacheFile, { codexModelsCacheFile: paths.modelsCacheFile }, processLog, { codexModelsCacheFile: paths.modelsCacheFile }, { codexModelsCacheFile: paths.modelsCacheFile }, { codexModelsCacheFile: paths.modelsCacheFile }, { codexModelsCacheFile: paths.modelsCacheFile });
|
|
9709
9748
|
if (isProductionInstance)
|
|
@@ -9735,7 +9774,7 @@ async function waitForWebUi(port, timeoutMs = 1e4) {
|
|
|
9735
9774
|
throw new Error(`Web UI did not come up on port ${port} within ${timeoutMs / 1000}s`);
|
|
9736
9775
|
}
|
|
9737
9776
|
function webUiLogPath(paths) {
|
|
9738
|
-
return
|
|
9777
|
+
return path15.join(paths.runtimeHome, "webui.log");
|
|
9739
9778
|
}
|
|
9740
9779
|
function runWebUiForeground(paths, config, openBrowser) {
|
|
9741
9780
|
const ctx = webUiContextForInstance(paths.gatewayConfig, paths);
|
|
@@ -10018,7 +10057,7 @@ async function configCommand(options) {
|
|
|
10018
10057
|
const managesCodex = !fs21.existsSync(paths.stateFile) || isCodexConfigManaged(loadJson(paths.stateFile));
|
|
10019
10058
|
if (managesCodex) {
|
|
10020
10059
|
const source = fs21.existsSync(paths.configToml) ? fs21.readFileSync(paths.configToml, "utf8") : "";
|
|
10021
|
-
applyModelCatalogToml(source, config.upstreamOnly === true, paths, codexCatalogFile(paths));
|
|
10060
|
+
applyModelCatalogToml(source, config.upstreamOnly === true, paths, codexCatalogFile(paths), managedRuntimeCatalogFiles(paths));
|
|
10022
10061
|
}
|
|
10023
10062
|
if (zcodeTarget !== undefined) {
|
|
10024
10063
|
config.zcode = zcodeTarget;
|
|
@@ -10157,7 +10196,7 @@ function ownsManagedCodexConfig(paths, state, legacyBaseUrl) {
|
|
|
10157
10196
|
function syncGatewayConfigFile(paths, configFile = paths.gatewayConfig) {
|
|
10158
10197
|
if (!fs21.existsSync(configFile))
|
|
10159
10198
|
return;
|
|
10160
|
-
const managesState = realPathOrResolve(configFile) === realPathOrResolve(
|
|
10199
|
+
const managesState = realPathOrResolve(configFile) === realPathOrResolve(path15.join(paths.runtimeHome, "config.json"));
|
|
10161
10200
|
const raw = loadJson(configFile);
|
|
10162
10201
|
if (!isJsonObject(raw))
|
|
10163
10202
|
throw new Error(`Gateway config must be a JSON object: ${configFile}`);
|
|
@@ -10320,7 +10359,7 @@ async function runCli(args) {
|
|
|
10320
10359
|
}
|
|
10321
10360
|
const configOption = command === "serve" ? stringOption(options, "config") : undefined;
|
|
10322
10361
|
const configPath = configOption ? realPathOrResolve(configOption) : undefined;
|
|
10323
|
-
let paths = configPath ? { ...resolvePaths(process.env,
|
|
10362
|
+
let paths = configPath ? { ...resolvePaths(process.env, path15.dirname(configPath)), gatewayConfig: configPath } : resolvePaths();
|
|
10324
10363
|
const migration = command === "install" ? prepareDefaultInstallMigration(paths) : undefined;
|
|
10325
10364
|
paths = migration?.paths ?? resolveInstalledCodexPaths(paths);
|
|
10326
10365
|
return runWithInstancePaths(paths, async () => {
|