@yhong91/cpac 0.1.16 → 0.1.18
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 +5 -2
- package/dist/cpac.js +49 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ cpac status
|
|
|
40
40
|
cpac install --all # 注入所有检测到的目标(codex/pi/kimi)
|
|
41
41
|
cpac install --target codex # 只注入 Codex(默认开启 multi-agent v2)
|
|
42
42
|
cpac install --target codex --v2_models # 先多选 spawn_agent 模型再注入
|
|
43
|
+
cpac install --target codex --max_context # 注入时把模型上下文提升到实测上限(opt-in,仅限 codex)
|
|
43
44
|
cpac uninstall --target codex # 字节级恢复原配置
|
|
44
45
|
|
|
45
46
|
# 4b. 临时接管(退出无痕,不写任何配置文件)
|
|
@@ -159,7 +160,7 @@ cpac --help
|
|
|
159
160
|
|
|
160
161
|
```bash
|
|
161
162
|
cpac detect [--json] [--home PATH]
|
|
162
|
-
cpac install [--target codex,pi,kimi] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--home PATH]
|
|
163
|
+
cpac install [--target codex,pi,kimi] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context] [--home PATH]
|
|
163
164
|
cpac uninstall [--target codex,pi,kimi] [--all] [--dry-run] [--home PATH]
|
|
164
165
|
cpac upgrade [--check]
|
|
165
166
|
cpac version
|
|
@@ -222,7 +223,7 @@ Claude Code 的发现协议不携带 context 信息,claude 前缀的未知模
|
|
|
222
223
|
注入 CPA 模型目录:
|
|
223
224
|
|
|
224
225
|
```bash
|
|
225
|
-
cpac inject [--v2_off] [--v2_models] [--config PATH]
|
|
226
|
+
cpac inject [--v2_off] [--v2_models] [--max_context] [--config PATH]
|
|
226
227
|
```
|
|
227
228
|
|
|
228
229
|
查看状态:
|
|
@@ -259,6 +260,8 @@ Codex App/CLI 发给本地代理的 ChatGPT bearer 不会转发到 CPA;代理
|
|
|
259
260
|
|
|
260
261
|
Codex App 的长驻 `app-server` 可能缓存旧目录。`inject` 会删除 `models_cache.json`;如果选择器仍未更新,请重启 Codex App。
|
|
261
262
|
|
|
263
|
+
注入命令可选 `--max_context`(`cpac inject --max_context` 或 `cpac install --target codex --max_context`,默认不带):把 catalog 中 `max_context_window` 高于 `context_window` 的模型提升到上限,并把 `auto_compact_token_limit` 设为上限的 90%。Codex 把 `context_window` 当输入预算而非展示标签,上游默认保留保守运营值(如 GPT-5.6 家族 272k),带上该参数后可用到实测上限(约 921k,opencodex 实测);90% 压缩线确保在硬上限前触发 auto-compact。不带参数注入的仍是原本上下文的目录。该参数仅限 codex,与其他 target 组合使用会直接报错。
|
|
264
|
+
|
|
262
265
|
第一次注入时,原文件按原始 bytes 备份到 `state_dir/config.toml.backup`。重复注入不会覆盖首次备份,并会保留 CPAC 管理字段之外的用户编辑。`restore` 按原 mode 逐字节恢复首次备份、关闭 CPAC loopback 代理;若原文件不存在,则删除注入创建的 `config.toml`。
|
|
263
266
|
|
|
264
267
|
loopback 代理是 detached 用户进程,不安装系统服务。机器重启或进程意外退出后,`cpac status` 会报告 `loopback proxy stopped`;重新执行 `cpac inject` 即可恢复。
|
package/dist/cpac.js
CHANGED
|
@@ -258,6 +258,29 @@ export async function fetchCatalog(cpaUrl, apiKey) {
|
|
|
258
258
|
modelCount: models.length,
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
|
+
// Codex treats a catalog model's context_window as its input budget, not a
|
|
262
|
+
// display label; upstream keeps it a conservative operating cap while
|
|
263
|
+
// max_context_window holds the real ceiling (gpt-5.6: 272k vs ~921k, measured
|
|
264
|
+
// by opencodex). Opt-in lift: raise context_window to max_context_window and
|
|
265
|
+
// set auto_compact_token_limit at 90% (Codex's own convention), keeping
|
|
266
|
+
// compaction ahead of the hard ceiling.
|
|
267
|
+
export function liftContextWindows(bytes) {
|
|
268
|
+
const document = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
269
|
+
for (const model of document.models) {
|
|
270
|
+
const maxWindow = typeof model.max_context_window === "number" &&
|
|
271
|
+
model.max_context_window > 0
|
|
272
|
+
? Math.floor(model.max_context_window)
|
|
273
|
+
: 0;
|
|
274
|
+
const window = typeof model.context_window === "number"
|
|
275
|
+
? Math.floor(model.context_window)
|
|
276
|
+
: 0;
|
|
277
|
+
if (maxWindow <= window)
|
|
278
|
+
continue;
|
|
279
|
+
model.context_window = maxWindow;
|
|
280
|
+
model.auto_compact_token_limit = Math.floor(maxWindow * 0.9);
|
|
281
|
+
}
|
|
282
|
+
return Buffer.from(`${JSON.stringify(document, null, 2)}\n`);
|
|
283
|
+
}
|
|
261
284
|
// Move `order` slugs to the front of the rich catalog (stable for the rest),
|
|
262
285
|
// so the Codex client's first-5 spawn_agent advertisement picks them.
|
|
263
286
|
export function reorderCatalog(bytes, order) {
|
|
@@ -1173,7 +1196,7 @@ function proxyFingerprint(config, apiKey) {
|
|
|
1173
1196
|
.update(apiKey)
|
|
1174
1197
|
.digest("hex");
|
|
1175
1198
|
}
|
|
1176
|
-
export async function inject(config, v2Off = false) {
|
|
1199
|
+
export async function inject(config, v2Off = false, maxContext = false) {
|
|
1177
1200
|
const apiKey = process.env[config.api_key_env]?.trim();
|
|
1178
1201
|
if (!apiKey)
|
|
1179
1202
|
throw new CPACError(`environment variable ${config.api_key_env} is not set`);
|
|
@@ -1211,6 +1234,8 @@ export async function inject(config, v2Off = false) {
|
|
|
1211
1234
|
const catalog = await fetchCatalog(config.cpa_url, apiKey);
|
|
1212
1235
|
if (config.spawn_models?.length)
|
|
1213
1236
|
catalog.bytes = reorderCatalog(catalog.bytes, config.spawn_models);
|
|
1237
|
+
if (maxContext)
|
|
1238
|
+
catalog.bytes = liftContextWindows(catalog.bytes);
|
|
1214
1239
|
const stateDirExisted = existsSync(config.state_dir);
|
|
1215
1240
|
if (!state &&
|
|
1216
1241
|
STATE_FILES.some((name) => existsSync(join(config.state_dir, name)))) {
|
|
@@ -1845,12 +1870,12 @@ const TARGETS = [
|
|
|
1845
1870
|
return false;
|
|
1846
1871
|
}
|
|
1847
1872
|
},
|
|
1848
|
-
install: async (config, dryRun, v2Off) => {
|
|
1873
|
+
install: async (config, dryRun, v2Off, maxContext) => {
|
|
1849
1874
|
if (dryRun) {
|
|
1850
1875
|
console.log("would inject CPA catalog and loopback proxy into Codex");
|
|
1851
1876
|
return;
|
|
1852
1877
|
}
|
|
1853
|
-
await inject(config, v2Off);
|
|
1878
|
+
await inject(config, v2Off, maxContext);
|
|
1854
1879
|
},
|
|
1855
1880
|
uninstall: async (config, dryRun) => {
|
|
1856
1881
|
if (dryRun) {
|
|
@@ -1934,12 +1959,17 @@ export async function runInstall(config, requested, options) {
|
|
|
1934
1959
|
if (selected.length === 0) {
|
|
1935
1960
|
throw new CPACError(`no supported targets detected; use --target ${TARGETS.map((target) => target.id).join(",")} or --all`);
|
|
1936
1961
|
}
|
|
1962
|
+
// Catalog context lifting is Codex-specific; refuse to silently skip it on
|
|
1963
|
+
// other targets so the flag never gains cross-agent meaning.
|
|
1964
|
+
if (options.maxContext && selected.some((target) => target.id !== "codex")) {
|
|
1965
|
+
throw new CPACError("--max_context is only valid with --target codex");
|
|
1966
|
+
}
|
|
1937
1967
|
for (const target of selected) {
|
|
1938
1968
|
if (target.installed(config) && !options.force) {
|
|
1939
1969
|
console.log(`${target.id}: already installed; use --force to reinstall`);
|
|
1940
1970
|
continue;
|
|
1941
1971
|
}
|
|
1942
|
-
await target.install(config, options.dryRun, options.v2Off);
|
|
1972
|
+
await target.install(config, options.dryRun, options.v2Off, options.maxContext);
|
|
1943
1973
|
}
|
|
1944
1974
|
return 0;
|
|
1945
1975
|
}
|
|
@@ -2005,7 +2035,7 @@ export async function runUpgrade(checkOnly) {
|
|
|
2005
2035
|
function usage() {
|
|
2006
2036
|
return [
|
|
2007
2037
|
"Usage: cpac",
|
|
2008
|
-
" cpac inject [--v2_off] [--v2_models] [--config PATH]",
|
|
2038
|
+
" cpac inject [--v2_off] [--v2_models] [--max_context] [--config PATH]",
|
|
2009
2039
|
" cpac <status|restore> [--config PATH]",
|
|
2010
2040
|
" cpac proxy [--config PATH]",
|
|
2011
2041
|
" cpac claude [--config PATH] [--] [claude args...]",
|
|
@@ -2014,7 +2044,7 @@ function usage() {
|
|
|
2014
2044
|
" cpac pi <install|uninstall|status> [--config PATH]",
|
|
2015
2045
|
" cpac kimi <install|uninstall|status> [--config PATH]",
|
|
2016
2046
|
" cpac detect [--json] [--home PATH]",
|
|
2017
|
-
" cpac install [--target codex,pi,kimi] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--home PATH]",
|
|
2047
|
+
" cpac install [--target codex,pi,kimi] [--all] [--dry-run] [--force] [--v2_off] [--v2_models] [--max_context] [--home PATH]",
|
|
2018
2048
|
" cpac uninstall [--target codex,pi,kimi] [--all] [--dry-run] [--home PATH]",
|
|
2019
2049
|
" cpac upgrade [--check]",
|
|
2020
2050
|
" cpac version",
|
|
@@ -2043,6 +2073,7 @@ function parseArgs(args) {
|
|
|
2043
2073
|
check: false,
|
|
2044
2074
|
v2Off: false,
|
|
2045
2075
|
v2Models: false,
|
|
2076
|
+
maxContext: false,
|
|
2046
2077
|
};
|
|
2047
2078
|
for (let index = 1; index < args.length; index++) {
|
|
2048
2079
|
const arg = args[index];
|
|
@@ -2083,6 +2114,9 @@ function parseArgs(args) {
|
|
|
2083
2114
|
else if (arg === "--v2_models" || arg === "--v2-models") {
|
|
2084
2115
|
parsed.v2Models = true;
|
|
2085
2116
|
}
|
|
2117
|
+
else if (arg === "--max_context" || arg === "--max-context") {
|
|
2118
|
+
parsed.maxContext = true;
|
|
2119
|
+
}
|
|
2086
2120
|
else {
|
|
2087
2121
|
throw new CPACError(`unknown option: ${arg}`);
|
|
2088
2122
|
}
|
|
@@ -2194,6 +2228,7 @@ function parseArgs(args) {
|
|
|
2194
2228
|
const positional = [];
|
|
2195
2229
|
let v2Off = false;
|
|
2196
2230
|
let v2Models = false;
|
|
2231
|
+
let maxContext = false;
|
|
2197
2232
|
for (let index = 0; index < args.length; index += 1) {
|
|
2198
2233
|
if (args[index] === "--config") {
|
|
2199
2234
|
const value = args[++index];
|
|
@@ -2207,6 +2242,9 @@ function parseArgs(args) {
|
|
|
2207
2242
|
else if (args[index] === "--v2_models" || args[index] === "--v2-models") {
|
|
2208
2243
|
v2Models = true;
|
|
2209
2244
|
}
|
|
2245
|
+
else if (args[index] === "--max_context" || args[index] === "--max-context") {
|
|
2246
|
+
maxContext = true;
|
|
2247
|
+
}
|
|
2210
2248
|
else if (args[index].startsWith("-")) {
|
|
2211
2249
|
throw new CPACError(`unknown option: ${args[index]}`);
|
|
2212
2250
|
}
|
|
@@ -2217,11 +2255,11 @@ function parseArgs(args) {
|
|
|
2217
2255
|
!["inject", "status", "restore", "proxy"].includes(positional[0])) {
|
|
2218
2256
|
throw new CPACError(usage());
|
|
2219
2257
|
}
|
|
2220
|
-
if (positional[0] !== "inject" && (v2Off || v2Models)) {
|
|
2221
|
-
throw new CPACError("--v2_off / --v2_models is only valid with inject or install");
|
|
2258
|
+
if (positional[0] !== "inject" && (v2Off || v2Models || maxContext)) {
|
|
2259
|
+
throw new CPACError("--v2_off / --v2_models / --max_context is only valid with inject or install");
|
|
2222
2260
|
}
|
|
2223
2261
|
if (positional[0] === "inject") {
|
|
2224
|
-
return { command: "inject", configPath, v2Off, v2Models };
|
|
2262
|
+
return { command: "inject", configPath, v2Off, v2Models, maxContext };
|
|
2225
2263
|
}
|
|
2226
2264
|
return {
|
|
2227
2265
|
command: positional[0],
|
|
@@ -2259,6 +2297,7 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
2259
2297
|
dryRun: parsed.dryRun,
|
|
2260
2298
|
force: parsed.force,
|
|
2261
2299
|
v2Off: parsed.v2Off,
|
|
2300
|
+
maxContext: parsed.maxContext,
|
|
2262
2301
|
});
|
|
2263
2302
|
}
|
|
2264
2303
|
if (parsed.command === "uninstall")
|
|
@@ -2292,7 +2331,7 @@ export async function main(args = process.argv.slice(2)) {
|
|
|
2292
2331
|
console.log(`spawn_models saved to ${parsed.configPath}: ${picked.join(", ")}`);
|
|
2293
2332
|
injectConfig = { ...config, spawn_models: picked };
|
|
2294
2333
|
}
|
|
2295
|
-
await inject(injectConfig, parsed.v2Off);
|
|
2334
|
+
await inject(injectConfig, parsed.v2Off, parsed.maxContext);
|
|
2296
2335
|
}
|
|
2297
2336
|
else if (parsed.command === "restore")
|
|
2298
2337
|
await restore(config);
|