codex-to-im 1.0.57 → 1.0.59
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 +2 -2
- package/README_EN.md +2 -2
- package/dist/cli.mjs +10 -4
- package/dist/daemon.mjs +141 -19
- package/dist/ui-server.mjs +266 -23
- package/docs/install-windows.md +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -183,7 +183,7 @@ codex-to-im uninstall
|
|
|
183
183
|
- `/new`:在当前正式会话目录下新建线程。
|
|
184
184
|
- `/new <路径或项目名>`:按指定目录新建线程。
|
|
185
185
|
- `/mode <ask|code|plan>`:切换运行模式。
|
|
186
|
-
- `/reasoning <1-5
|
|
186
|
+
- `/reasoning <low|medium|high|xhigh|max|ultra>`:切换思考级别;数字 `1-5` 仍兼容旧映射,`6=max`、`7=ultra` 仅适用于支持这些档位的模型。
|
|
187
187
|
- `/model`:查看当前模型和可选模型。
|
|
188
188
|
- `/model <模型名>`:切换当前 IM 会话模型。
|
|
189
189
|
- `/history`:查看当前线程历史摘要。
|
|
@@ -196,7 +196,7 @@ codex-to-im uninstall
|
|
|
196
196
|
|
|
197
197
|
- 默认工作空间:用于 `/new my-project` 这类相对路径。
|
|
198
198
|
- Codex 文件系统权限:如 `workspace-write`、`danger-full-access`。
|
|
199
|
-
- Codex
|
|
199
|
+
- Codex 思考级别:按当前模型的 Codex catalog 展示,例如 `low`、`medium`、`high`、`xhigh`,部分新模型支持 `max`、`ultra`。
|
|
200
200
|
- 默认模型:从本机可用模型中选择。
|
|
201
201
|
- 反馈使用 markdown:控制 bridge 发到通道里的文本反馈是否走 markdown。
|
|
202
202
|
- 允许局域网访问 Web 控制台:便于手机或局域网设备访问。
|
package/README_EN.md
CHANGED
|
@@ -182,7 +182,7 @@ You can also specify a directory explicitly:
|
|
|
182
182
|
- `/new`: create a new thread under the current formal session directory.
|
|
183
183
|
- `/new <path or project name>`: create a new thread under the specified directory.
|
|
184
184
|
- `/mode <ask|code|plan>`: change the runtime mode.
|
|
185
|
-
- `/reasoning <
|
|
185
|
+
- `/reasoning <low|medium|high|xhigh|max|ultra>`: change the reasoning effort; numeric `1-5` aliases remain compatible, while `6=max` and `7=ultra` only apply to models that support them.
|
|
186
186
|
- `/model`: inspect the current model and available models.
|
|
187
187
|
- `/model <model name>`: change the model for the current IM session.
|
|
188
188
|
- `/history`: inspect the current thread history summary.
|
|
@@ -195,7 +195,7 @@ Common settings in the workbench include:
|
|
|
195
195
|
|
|
196
196
|
- Default workspace root: used for relative paths such as `/new my-project`.
|
|
197
197
|
- Codex filesystem permission: for example `workspace-write` or `danger-full-access`.
|
|
198
|
-
- Codex reasoning effort: `
|
|
198
|
+
- Codex reasoning effort: shown from the selected model's Codex catalog, for example `low`, `medium`, `high`, `xhigh`; some newer models also support `max` and `ultra`.
|
|
199
199
|
- Default model: chosen from the models available on the local machine.
|
|
200
200
|
- Use Markdown for feedback: controls whether bridge text feedback is sent through markdown rendering.
|
|
201
201
|
- Allow LAN access to the Web console: useful when opening the workbench from a phone or another device on the same LAN.
|
package/dist/cli.mjs
CHANGED
|
@@ -17,6 +17,15 @@ import os from "node:os";
|
|
|
17
17
|
import path from "node:path";
|
|
18
18
|
|
|
19
19
|
// src/runtime-options.ts
|
|
20
|
+
var RUNTIME_REASONING_EFFORTS = [
|
|
21
|
+
"minimal",
|
|
22
|
+
"low",
|
|
23
|
+
"medium",
|
|
24
|
+
"high",
|
|
25
|
+
"xhigh",
|
|
26
|
+
"max",
|
|
27
|
+
"ultra"
|
|
28
|
+
];
|
|
20
29
|
function parseSandboxMode(value) {
|
|
21
30
|
if (value === "read-only" || value === "workspace-write" || value === "danger-full-access") {
|
|
22
31
|
return value;
|
|
@@ -24,10 +33,7 @@ function parseSandboxMode(value) {
|
|
|
24
33
|
return void 0;
|
|
25
34
|
}
|
|
26
35
|
function parseReasoningEffort(value) {
|
|
27
|
-
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
return void 0;
|
|
36
|
+
return RUNTIME_REASONING_EFFORTS.includes(value) ? value : void 0;
|
|
31
37
|
}
|
|
32
38
|
function normalizeChannelId(value) {
|
|
33
39
|
return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "channel";
|
package/dist/daemon.mjs
CHANGED
|
@@ -43,10 +43,7 @@ function normalizeSandboxMode(value, fallback = "workspace-write") {
|
|
|
43
43
|
return parseSandboxMode(value) || fallback;
|
|
44
44
|
}
|
|
45
45
|
function parseReasoningEffort(value) {
|
|
46
|
-
|
|
47
|
-
return value;
|
|
48
|
-
}
|
|
49
|
-
return void 0;
|
|
46
|
+
return RUNTIME_REASONING_EFFORTS.includes(value) ? value : void 0;
|
|
50
47
|
}
|
|
51
48
|
function normalizeReasoningEffort(value, fallback = "medium") {
|
|
52
49
|
return parseReasoningEffort(value) || fallback;
|
|
@@ -54,9 +51,19 @@ function normalizeReasoningEffort(value, fallback = "medium") {
|
|
|
54
51
|
function normalizeChannelId(value) {
|
|
55
52
|
return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "channel";
|
|
56
53
|
}
|
|
54
|
+
var RUNTIME_REASONING_EFFORTS;
|
|
57
55
|
var init_runtime_options = __esm({
|
|
58
56
|
"src/runtime-options.ts"() {
|
|
59
57
|
"use strict";
|
|
58
|
+
RUNTIME_REASONING_EFFORTS = [
|
|
59
|
+
"minimal",
|
|
60
|
+
"low",
|
|
61
|
+
"medium",
|
|
62
|
+
"high",
|
|
63
|
+
"xhigh",
|
|
64
|
+
"max",
|
|
65
|
+
"ultra"
|
|
66
|
+
];
|
|
60
67
|
}
|
|
61
68
|
});
|
|
62
69
|
|
|
@@ -11708,7 +11715,7 @@ function validateMode(mode) {
|
|
|
11708
11715
|
}
|
|
11709
11716
|
|
|
11710
11717
|
// src/lib/bridge/command-aliases.ts
|
|
11711
|
-
|
|
11718
|
+
init_runtime_options();
|
|
11712
11719
|
var DEFAULT_DESKTOP_THREAD_LIST_LIMIT = 10;
|
|
11713
11720
|
var MAX_DESKTOP_THREAD_LIST_LIMIT = 200;
|
|
11714
11721
|
function parseListIndex(raw) {
|
|
@@ -11758,9 +11765,8 @@ function parseDesktopThreadListArgs(args) {
|
|
|
11758
11765
|
function normalizeReasoningEffort2(raw) {
|
|
11759
11766
|
const token = raw.trim().toLowerCase();
|
|
11760
11767
|
if (!token) return null;
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
}
|
|
11768
|
+
const named = parseReasoningEffort(token);
|
|
11769
|
+
if (named) return named;
|
|
11764
11770
|
switch (token) {
|
|
11765
11771
|
case "1":
|
|
11766
11772
|
return "minimal";
|
|
@@ -11772,6 +11778,10 @@ function normalizeReasoningEffort2(raw) {
|
|
|
11772
11778
|
return "high";
|
|
11773
11779
|
case "5":
|
|
11774
11780
|
return "xhigh";
|
|
11781
|
+
case "6":
|
|
11782
|
+
return "max";
|
|
11783
|
+
case "7":
|
|
11784
|
+
return "ultra";
|
|
11775
11785
|
default:
|
|
11776
11786
|
return null;
|
|
11777
11787
|
}
|
|
@@ -11809,6 +11819,10 @@ function formatReasoningEffort(reasoning) {
|
|
|
11809
11819
|
return "high (4)";
|
|
11810
11820
|
case "xhigh":
|
|
11811
11821
|
return "xhigh (5)";
|
|
11822
|
+
case "max":
|
|
11823
|
+
return "max (6)";
|
|
11824
|
+
case "ultra":
|
|
11825
|
+
return "ultra (7)";
|
|
11812
11826
|
default:
|
|
11813
11827
|
return reasoning;
|
|
11814
11828
|
}
|
|
@@ -12920,6 +12934,52 @@ import os3 from "node:os";
|
|
|
12920
12934
|
import path9 from "node:path";
|
|
12921
12935
|
var DEFAULT_CODEX_CONFIG_PATH = path9.join(os3.homedir(), ".codex", "config.toml");
|
|
12922
12936
|
var DEFAULT_CODEX_MODELS_CACHE_PATH = path9.join(os3.homedir(), ".codex", "models_cache.json");
|
|
12937
|
+
var REASONING_LEVEL_DESCRIPTIONS = {
|
|
12938
|
+
low: "Fast responses with lighter reasoning",
|
|
12939
|
+
medium: "Balances speed and reasoning depth for everyday tasks",
|
|
12940
|
+
high: "Greater reasoning depth for complex problems",
|
|
12941
|
+
xhigh: "Extra high reasoning depth for complex problems",
|
|
12942
|
+
max: "Maximum reasoning depth for very hard problems",
|
|
12943
|
+
ultra: "Ultra reasoning depth for the hardest problems"
|
|
12944
|
+
};
|
|
12945
|
+
function buildReasoningLevels(efforts) {
|
|
12946
|
+
return efforts.map((effort) => ({
|
|
12947
|
+
effort,
|
|
12948
|
+
description: REASONING_LEVEL_DESCRIPTIONS[effort] || ""
|
|
12949
|
+
}));
|
|
12950
|
+
}
|
|
12951
|
+
function cloneCodexModel(model) {
|
|
12952
|
+
return {
|
|
12953
|
+
...model,
|
|
12954
|
+
supportedReasoningLevels: model.supportedReasoningLevels.map((level) => ({ ...level }))
|
|
12955
|
+
};
|
|
12956
|
+
}
|
|
12957
|
+
var KNOWN_CODEX_MODEL_FALLBACKS = [
|
|
12958
|
+
{
|
|
12959
|
+
slug: "gpt-5.6-sol",
|
|
12960
|
+
displayName: "GPT-5.6-Sol",
|
|
12961
|
+
visibility: "list",
|
|
12962
|
+
supportedInApi: true,
|
|
12963
|
+
defaultReasoningLevel: "low",
|
|
12964
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max", "ultra"])
|
|
12965
|
+
},
|
|
12966
|
+
{
|
|
12967
|
+
slug: "gpt-5.6-terra",
|
|
12968
|
+
displayName: "GPT-5.6-Terra",
|
|
12969
|
+
visibility: "list",
|
|
12970
|
+
supportedInApi: true,
|
|
12971
|
+
defaultReasoningLevel: "medium",
|
|
12972
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max", "ultra"])
|
|
12973
|
+
},
|
|
12974
|
+
{
|
|
12975
|
+
slug: "gpt-5.6-luna",
|
|
12976
|
+
displayName: "GPT-5.6-Luna",
|
|
12977
|
+
visibility: "list",
|
|
12978
|
+
supportedInApi: true,
|
|
12979
|
+
defaultReasoningLevel: "medium",
|
|
12980
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max"])
|
|
12981
|
+
}
|
|
12982
|
+
];
|
|
12923
12983
|
function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
12924
12984
|
try {
|
|
12925
12985
|
const raw = fs6.readFileSync(configPath, "utf-8");
|
|
@@ -12942,6 +13002,28 @@ function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
|
12942
13002
|
return null;
|
|
12943
13003
|
}
|
|
12944
13004
|
}
|
|
13005
|
+
function parseReasoningLevel(value) {
|
|
13006
|
+
if (typeof value !== "string") return void 0;
|
|
13007
|
+
const trimmed = value.trim();
|
|
13008
|
+
return trimmed ? trimmed : void 0;
|
|
13009
|
+
}
|
|
13010
|
+
function parseSupportedReasoningLevels(value) {
|
|
13011
|
+
if (!Array.isArray(value)) return [];
|
|
13012
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13013
|
+
const levels = [];
|
|
13014
|
+
for (const level of value) {
|
|
13015
|
+
if (!level || typeof level !== "object") continue;
|
|
13016
|
+
const raw = level;
|
|
13017
|
+
const effort = parseReasoningLevel(raw.effort);
|
|
13018
|
+
if (!effort || seen.has(effort)) continue;
|
|
13019
|
+
seen.add(effort);
|
|
13020
|
+
levels.push({
|
|
13021
|
+
effort,
|
|
13022
|
+
description: typeof raw.description === "string" ? raw.description.trim() : ""
|
|
13023
|
+
});
|
|
13024
|
+
}
|
|
13025
|
+
return levels;
|
|
13026
|
+
}
|
|
12945
13027
|
function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
12946
13028
|
try {
|
|
12947
13029
|
const raw = fs6.readFileSync(cachePath, "utf-8");
|
|
@@ -12954,11 +13036,14 @@ function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
|
12954
13036
|
const slug = model.slug.trim();
|
|
12955
13037
|
if (seen.has(slug)) continue;
|
|
12956
13038
|
seen.add(slug);
|
|
13039
|
+
const defaultReasoningLevel = parseReasoningLevel(model.default_reasoning_level);
|
|
12957
13040
|
models.push({
|
|
12958
13041
|
slug,
|
|
12959
13042
|
displayName: typeof model.display_name === "string" && model.display_name.trim() ? model.display_name.trim() : slug,
|
|
12960
13043
|
visibility: typeof model.visibility === "string" && model.visibility.trim() ? model.visibility.trim() : "list",
|
|
12961
|
-
supportedInApi: model.supported_in_api === true
|
|
13044
|
+
supportedInApi: model.supported_in_api === true,
|
|
13045
|
+
supportedReasoningLevels: parseSupportedReasoningLevels(model.supported_reasoning_levels),
|
|
13046
|
+
...defaultReasoningLevel ? { defaultReasoningLevel } : {}
|
|
12962
13047
|
});
|
|
12963
13048
|
}
|
|
12964
13049
|
return models;
|
|
@@ -12966,13 +13051,50 @@ function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
|
12966
13051
|
return [];
|
|
12967
13052
|
}
|
|
12968
13053
|
}
|
|
12969
|
-
function
|
|
12970
|
-
|
|
13054
|
+
function buildSyntheticCodexModel(slug) {
|
|
13055
|
+
const normalized = slug.trim();
|
|
13056
|
+
if (!normalized) return null;
|
|
13057
|
+
return {
|
|
13058
|
+
slug: normalized,
|
|
13059
|
+
displayName: normalized,
|
|
13060
|
+
visibility: "list",
|
|
13061
|
+
supportedInApi: true,
|
|
13062
|
+
supportedReasoningLevels: []
|
|
13063
|
+
};
|
|
13064
|
+
}
|
|
13065
|
+
function listAvailableCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH, additionalModelSlugs = []) {
|
|
13066
|
+
const cachedModels = listCachedCodexModels(cachePath);
|
|
13067
|
+
const hiddenCachedSlugs = new Set(
|
|
13068
|
+
cachedModels.filter((model) => model.visibility === "hide").map((model) => model.slug)
|
|
13069
|
+
);
|
|
13070
|
+
const merged = [];
|
|
13071
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13072
|
+
const addModel = (model, force = false) => {
|
|
13073
|
+
if (!force && hiddenCachedSlugs.has(model.slug)) return;
|
|
13074
|
+
if (seen.has(model.slug)) return;
|
|
13075
|
+
seen.add(model.slug);
|
|
13076
|
+
merged.push(cloneCodexModel(model));
|
|
13077
|
+
};
|
|
13078
|
+
for (const model of cachedModels) {
|
|
13079
|
+
if (model.visibility !== "hide") {
|
|
13080
|
+
addModel(model, true);
|
|
13081
|
+
}
|
|
13082
|
+
}
|
|
13083
|
+
for (const model of KNOWN_CODEX_MODEL_FALLBACKS) {
|
|
13084
|
+
addModel(model);
|
|
13085
|
+
}
|
|
13086
|
+
for (const slug of additionalModelSlugs) {
|
|
13087
|
+
const syntheticModel = buildSyntheticCodexModel(slug);
|
|
13088
|
+
if (syntheticModel) {
|
|
13089
|
+
addModel(syntheticModel, true);
|
|
13090
|
+
}
|
|
13091
|
+
}
|
|
13092
|
+
return merged;
|
|
12971
13093
|
}
|
|
12972
|
-
function
|
|
13094
|
+
function findAvailableCodexModel(slug, cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH, additionalModelSlugs = []) {
|
|
12973
13095
|
const normalized = slug.trim();
|
|
12974
13096
|
if (!normalized) return null;
|
|
12975
|
-
return
|
|
13097
|
+
return listAvailableCodexModels(cachePath, additionalModelSlugs).find((model) => model.slug === normalized) || null;
|
|
12976
13098
|
}
|
|
12977
13099
|
function isCliOnlyCodexModel(model) {
|
|
12978
13100
|
return !!model && model.supportedInApi === false;
|
|
@@ -12980,7 +13102,7 @@ function isCliOnlyCodexModel(model) {
|
|
|
12980
13102
|
|
|
12981
13103
|
// src/lib/bridge/bridge-session-support.ts
|
|
12982
13104
|
init_runtime_options();
|
|
12983
|
-
var AVAILABLE_CODEX_MODELS =
|
|
13105
|
+
var AVAILABLE_CODEX_MODELS = listAvailableCodexModels();
|
|
12984
13106
|
var AVAILABLE_CODEX_MODEL_MAP = new Map(AVAILABLE_CODEX_MODELS.map((model) => [model.slug, model]));
|
|
12985
13107
|
function getDisplayedDesktopThreads(limit) {
|
|
12986
13108
|
try {
|
|
@@ -13029,7 +13151,7 @@ function getAvailableModelChoicesText() {
|
|
|
13029
13151
|
return `\u53EF\u9009\u6A21\u578B\uFF1A${AVAILABLE_CODEX_MODELS.map((model) => formatDisplayedModel(model.slug)).join("\u3001")}`;
|
|
13030
13152
|
}
|
|
13031
13153
|
function getSelectableCodexModel(slug) {
|
|
13032
|
-
return AVAILABLE_CODEX_MODEL_MAP.get(slug) ||
|
|
13154
|
+
return AVAILABLE_CODEX_MODEL_MAP.get(slug) || findAvailableCodexModel(slug);
|
|
13033
13155
|
}
|
|
13034
13156
|
function resolveNewWorkingDirectory(rawArgs) {
|
|
13035
13157
|
const trimmed = rawArgs.trim();
|
|
@@ -13276,7 +13398,7 @@ ${attachmentResult.error || "\u672A\u77E5\u9519\u8BEF"}`,
|
|
|
13276
13398
|
|
|
13277
13399
|
// src/lib/bridge/command-dispatch.ts
|
|
13278
13400
|
var MODE_OPTIONS_TEXT = "\u53EF\u9009\uFF1A`code`\uFF08\u76F4\u63A5\u6267\u884C\uFF0C\u9ED8\u8BA4\uFF09 `plan`\uFF08\u5148\u5206\u6790\u518D\u884C\u52A8\uFF09 `ask`\uFF08\u8F7B\u5BF9\u8BDD / \u8349\u7A3F\uFF09";
|
|
13279
|
-
var REASONING_OPTIONS_TEXT = "\u53EF\u9009\uFF1A`1=minimal` `2=low` `3=medium` `4=high` `5=xhigh`";
|
|
13401
|
+
var REASONING_OPTIONS_TEXT = "\u53EF\u9009\uFF1A`low` `medium` `high` `xhigh`\uFF0C\u90E8\u5206\u65B0\u6A21\u578B\u8FD8\u652F\u6301 `max`\u3001`ultra`\uFF1B\u6570\u5B57\u517C\u5BB9\uFF1A`1=minimal` `2=low` `3=medium` `4=high` `5=xhigh` `6=max` `7=ultra`";
|
|
13280
13402
|
function parseForceFlag(args) {
|
|
13281
13403
|
const forcePattern = /(^|\s)--force(?=\s|$)/;
|
|
13282
13404
|
const force = forcePattern.test(args);
|
|
@@ -13596,7 +13718,7 @@ async function handleBridgeCommand(adapter, msg, text2, deps) {
|
|
|
13596
13718
|
response = buildCommandFields(
|
|
13597
13719
|
"\u5F53\u524D\u601D\u8003\u7EA7\u522B",
|
|
13598
13720
|
[["\u7EA7\u522B", formatReasoningEffort(resolveEffectiveReasoningEffort(session))]],
|
|
13599
|
-
[REASONING_OPTIONS_TEXT, "\u53D1\u9001 `/r
|
|
13721
|
+
[REASONING_OPTIONS_TEXT, "\u53D1\u9001 `/r high` \u53EF\u5207\u6362\u3002"],
|
|
13600
13722
|
responseParseMode === "Markdown"
|
|
13601
13723
|
);
|
|
13602
13724
|
break;
|
|
@@ -13605,8 +13727,8 @@ async function handleBridgeCommand(adapter, msg, text2, deps) {
|
|
|
13605
13727
|
if (!reasoning) {
|
|
13606
13728
|
response = buildCommandFields(
|
|
13607
13729
|
"\u601D\u8003\u7EA7\u522B\u7528\u6CD5",
|
|
13608
|
-
[["\u547D\u4EE4", "`/reasoning
|
|
13609
|
-
["\u4E5F\u652F\u6301\
|
|
13730
|
+
[["\u547D\u4EE4", "`/reasoning low|medium|high|xhigh|max|ultra`"]],
|
|
13731
|
+
["\u4E5F\u652F\u6301\u517C\u5BB9\u6570\u5B57\uFF1A`/reasoning 1|2|3|4|5|6|7`", REASONING_OPTIONS_TEXT],
|
|
13610
13732
|
responseParseMode === "Markdown"
|
|
13611
13733
|
);
|
|
13612
13734
|
break;
|
package/dist/ui-server.mjs
CHANGED
|
@@ -4576,6 +4576,15 @@ import os from "node:os";
|
|
|
4576
4576
|
import path from "node:path";
|
|
4577
4577
|
|
|
4578
4578
|
// src/runtime-options.ts
|
|
4579
|
+
var RUNTIME_REASONING_EFFORTS = [
|
|
4580
|
+
"minimal",
|
|
4581
|
+
"low",
|
|
4582
|
+
"medium",
|
|
4583
|
+
"high",
|
|
4584
|
+
"xhigh",
|
|
4585
|
+
"max",
|
|
4586
|
+
"ultra"
|
|
4587
|
+
];
|
|
4579
4588
|
function parseSandboxMode(value) {
|
|
4580
4589
|
if (value === "read-only" || value === "workspace-write" || value === "danger-full-access") {
|
|
4581
4590
|
return value;
|
|
@@ -4583,10 +4592,7 @@ function parseSandboxMode(value) {
|
|
|
4583
4592
|
return void 0;
|
|
4584
4593
|
}
|
|
4585
4594
|
function parseReasoningEffort(value) {
|
|
4586
|
-
|
|
4587
|
-
return value;
|
|
4588
|
-
}
|
|
4589
|
-
return void 0;
|
|
4595
|
+
return RUNTIME_REASONING_EFFORTS.includes(value) ? value : void 0;
|
|
4590
4596
|
}
|
|
4591
4597
|
function normalizeChannelId(value) {
|
|
4592
4598
|
return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "channel";
|
|
@@ -7532,6 +7538,52 @@ import os4 from "node:os";
|
|
|
7532
7538
|
import path9 from "node:path";
|
|
7533
7539
|
var DEFAULT_CODEX_CONFIG_PATH = path9.join(os4.homedir(), ".codex", "config.toml");
|
|
7534
7540
|
var DEFAULT_CODEX_MODELS_CACHE_PATH = path9.join(os4.homedir(), ".codex", "models_cache.json");
|
|
7541
|
+
var REASONING_LEVEL_DESCRIPTIONS = {
|
|
7542
|
+
low: "Fast responses with lighter reasoning",
|
|
7543
|
+
medium: "Balances speed and reasoning depth for everyday tasks",
|
|
7544
|
+
high: "Greater reasoning depth for complex problems",
|
|
7545
|
+
xhigh: "Extra high reasoning depth for complex problems",
|
|
7546
|
+
max: "Maximum reasoning depth for very hard problems",
|
|
7547
|
+
ultra: "Ultra reasoning depth for the hardest problems"
|
|
7548
|
+
};
|
|
7549
|
+
function buildReasoningLevels(efforts) {
|
|
7550
|
+
return efforts.map((effort) => ({
|
|
7551
|
+
effort,
|
|
7552
|
+
description: REASONING_LEVEL_DESCRIPTIONS[effort] || ""
|
|
7553
|
+
}));
|
|
7554
|
+
}
|
|
7555
|
+
function cloneCodexModel(model) {
|
|
7556
|
+
return {
|
|
7557
|
+
...model,
|
|
7558
|
+
supportedReasoningLevels: model.supportedReasoningLevels.map((level) => ({ ...level }))
|
|
7559
|
+
};
|
|
7560
|
+
}
|
|
7561
|
+
var KNOWN_CODEX_MODEL_FALLBACKS = [
|
|
7562
|
+
{
|
|
7563
|
+
slug: "gpt-5.6-sol",
|
|
7564
|
+
displayName: "GPT-5.6-Sol",
|
|
7565
|
+
visibility: "list",
|
|
7566
|
+
supportedInApi: true,
|
|
7567
|
+
defaultReasoningLevel: "low",
|
|
7568
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max", "ultra"])
|
|
7569
|
+
},
|
|
7570
|
+
{
|
|
7571
|
+
slug: "gpt-5.6-terra",
|
|
7572
|
+
displayName: "GPT-5.6-Terra",
|
|
7573
|
+
visibility: "list",
|
|
7574
|
+
supportedInApi: true,
|
|
7575
|
+
defaultReasoningLevel: "medium",
|
|
7576
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max", "ultra"])
|
|
7577
|
+
},
|
|
7578
|
+
{
|
|
7579
|
+
slug: "gpt-5.6-luna",
|
|
7580
|
+
displayName: "GPT-5.6-Luna",
|
|
7581
|
+
visibility: "list",
|
|
7582
|
+
supportedInApi: true,
|
|
7583
|
+
defaultReasoningLevel: "medium",
|
|
7584
|
+
supportedReasoningLevels: buildReasoningLevels(["low", "medium", "high", "xhigh", "max"])
|
|
7585
|
+
}
|
|
7586
|
+
];
|
|
7535
7587
|
function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
7536
7588
|
try {
|
|
7537
7589
|
const raw = fs8.readFileSync(configPath, "utf-8");
|
|
@@ -7554,6 +7606,28 @@ function readConfiguredCodexModel(configPath = DEFAULT_CODEX_CONFIG_PATH) {
|
|
|
7554
7606
|
return null;
|
|
7555
7607
|
}
|
|
7556
7608
|
}
|
|
7609
|
+
function parseReasoningLevel(value) {
|
|
7610
|
+
if (typeof value !== "string") return void 0;
|
|
7611
|
+
const trimmed = value.trim();
|
|
7612
|
+
return trimmed ? trimmed : void 0;
|
|
7613
|
+
}
|
|
7614
|
+
function parseSupportedReasoningLevels(value) {
|
|
7615
|
+
if (!Array.isArray(value)) return [];
|
|
7616
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7617
|
+
const levels = [];
|
|
7618
|
+
for (const level of value) {
|
|
7619
|
+
if (!level || typeof level !== "object") continue;
|
|
7620
|
+
const raw = level;
|
|
7621
|
+
const effort = parseReasoningLevel(raw.effort);
|
|
7622
|
+
if (!effort || seen.has(effort)) continue;
|
|
7623
|
+
seen.add(effort);
|
|
7624
|
+
levels.push({
|
|
7625
|
+
effort,
|
|
7626
|
+
description: typeof raw.description === "string" ? raw.description.trim() : ""
|
|
7627
|
+
});
|
|
7628
|
+
}
|
|
7629
|
+
return levels;
|
|
7630
|
+
}
|
|
7557
7631
|
function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
7558
7632
|
try {
|
|
7559
7633
|
const raw = fs8.readFileSync(cachePath, "utf-8");
|
|
@@ -7566,11 +7640,14 @@ function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
|
7566
7640
|
const slug = model.slug.trim();
|
|
7567
7641
|
if (seen.has(slug)) continue;
|
|
7568
7642
|
seen.add(slug);
|
|
7643
|
+
const defaultReasoningLevel = parseReasoningLevel(model.default_reasoning_level);
|
|
7569
7644
|
models.push({
|
|
7570
7645
|
slug,
|
|
7571
7646
|
displayName: typeof model.display_name === "string" && model.display_name.trim() ? model.display_name.trim() : slug,
|
|
7572
7647
|
visibility: typeof model.visibility === "string" && model.visibility.trim() ? model.visibility.trim() : "list",
|
|
7573
|
-
supportedInApi: model.supported_in_api === true
|
|
7648
|
+
supportedInApi: model.supported_in_api === true,
|
|
7649
|
+
supportedReasoningLevels: parseSupportedReasoningLevels(model.supported_reasoning_levels),
|
|
7650
|
+
...defaultReasoningLevel ? { defaultReasoningLevel } : {}
|
|
7574
7651
|
});
|
|
7575
7652
|
}
|
|
7576
7653
|
return models;
|
|
@@ -7578,16 +7655,52 @@ function listCachedCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH) {
|
|
|
7578
7655
|
return [];
|
|
7579
7656
|
}
|
|
7580
7657
|
}
|
|
7581
|
-
function
|
|
7582
|
-
|
|
7658
|
+
function buildSyntheticCodexModel(slug) {
|
|
7659
|
+
const normalized = slug.trim();
|
|
7660
|
+
if (!normalized) return null;
|
|
7661
|
+
return {
|
|
7662
|
+
slug: normalized,
|
|
7663
|
+
displayName: normalized,
|
|
7664
|
+
visibility: "list",
|
|
7665
|
+
supportedInApi: true,
|
|
7666
|
+
supportedReasoningLevels: []
|
|
7667
|
+
};
|
|
7668
|
+
}
|
|
7669
|
+
function listAvailableCodexModels(cachePath = DEFAULT_CODEX_MODELS_CACHE_PATH, additionalModelSlugs = []) {
|
|
7670
|
+
const cachedModels = listCachedCodexModels(cachePath);
|
|
7671
|
+
const hiddenCachedSlugs = new Set(
|
|
7672
|
+
cachedModels.filter((model) => model.visibility === "hide").map((model) => model.slug)
|
|
7673
|
+
);
|
|
7674
|
+
const merged = [];
|
|
7675
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7676
|
+
const addModel = (model, force = false) => {
|
|
7677
|
+
if (!force && hiddenCachedSlugs.has(model.slug)) return;
|
|
7678
|
+
if (seen.has(model.slug)) return;
|
|
7679
|
+
seen.add(model.slug);
|
|
7680
|
+
merged.push(cloneCodexModel(model));
|
|
7681
|
+
};
|
|
7682
|
+
for (const model of cachedModels) {
|
|
7683
|
+
if (model.visibility !== "hide") {
|
|
7684
|
+
addModel(model, true);
|
|
7685
|
+
}
|
|
7686
|
+
}
|
|
7687
|
+
for (const model of KNOWN_CODEX_MODEL_FALLBACKS) {
|
|
7688
|
+
addModel(model);
|
|
7689
|
+
}
|
|
7690
|
+
for (const slug of additionalModelSlugs) {
|
|
7691
|
+
const syntheticModel = buildSyntheticCodexModel(slug);
|
|
7692
|
+
if (syntheticModel) {
|
|
7693
|
+
addModel(syntheticModel, true);
|
|
7694
|
+
}
|
|
7695
|
+
}
|
|
7696
|
+
return merged;
|
|
7583
7697
|
}
|
|
7584
7698
|
|
|
7585
7699
|
// src/ui-server.ts
|
|
7586
7700
|
var port = 4781;
|
|
7587
7701
|
var serverStartTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
7588
7702
|
var AUTH_COOKIE_NAME = "cti_ui_auth";
|
|
7589
|
-
var
|
|
7590
|
-
var availableCodexModelSlugs = new Set(availableCodexModels.map((model) => model.slug));
|
|
7703
|
+
var FALLBACK_REASONING_EFFORTS = ["low", "medium", "high", "xhigh"];
|
|
7591
7704
|
var FEISHU_CHAT_LABEL_TTL_MS = 5 * 60 * 1e3;
|
|
7592
7705
|
var feishuChatLabelCache = /* @__PURE__ */ new Map();
|
|
7593
7706
|
var feishuTenantTokenCache = /* @__PURE__ */ new Map();
|
|
@@ -7596,6 +7709,34 @@ function parsePreferredPort() {
|
|
|
7596
7709
|
if (!Number.isInteger(raw) || raw <= 0 || raw > 65535) return 4781;
|
|
7597
7710
|
return raw;
|
|
7598
7711
|
}
|
|
7712
|
+
function getAvailableCodexModels(additionalModelSlugs = []) {
|
|
7713
|
+
return listAvailableCodexModels(void 0, additionalModelSlugs);
|
|
7714
|
+
}
|
|
7715
|
+
function getAvailableCodexModelSlugs(models = getAvailableCodexModels()) {
|
|
7716
|
+
return new Set(models.map((model) => model.slug));
|
|
7717
|
+
}
|
|
7718
|
+
function getCodexModelMetadata(modelSlug, models = getAvailableCodexModels()) {
|
|
7719
|
+
if (!modelSlug) return null;
|
|
7720
|
+
return models.find((model) => model.slug === modelSlug) || null;
|
|
7721
|
+
}
|
|
7722
|
+
function getSupportedReasoningEfforts(modelSlug, models = getAvailableCodexModels()) {
|
|
7723
|
+
const metadata = getCodexModelMetadata(modelSlug, models);
|
|
7724
|
+
const levels = metadata?.supportedReasoningLevels.map((level) => parseReasoningEffort(level.effort)).filter((level) => Boolean(level)) || [];
|
|
7725
|
+
return levels.length > 0 ? levels : FALLBACK_REASONING_EFFORTS;
|
|
7726
|
+
}
|
|
7727
|
+
function getDefaultReasoningEffort(modelSlug, models = getAvailableCodexModels()) {
|
|
7728
|
+
const metadata = getCodexModelMetadata(modelSlug, models);
|
|
7729
|
+
const supported = getSupportedReasoningEfforts(modelSlug, models);
|
|
7730
|
+
const catalogDefault = parseReasoningEffort(metadata?.defaultReasoningLevel);
|
|
7731
|
+
if (catalogDefault && supported.includes(catalogDefault)) return catalogDefault;
|
|
7732
|
+
if (supported.includes("medium")) return "medium";
|
|
7733
|
+
return supported[0] || "medium";
|
|
7734
|
+
}
|
|
7735
|
+
function isReasoningEffortSupportedByModel(value, modelSlug, models = getAvailableCodexModels()) {
|
|
7736
|
+
const metadata = getCodexModelMetadata(modelSlug, models);
|
|
7737
|
+
if (!metadata || metadata.supportedReasoningLevels.length === 0) return true;
|
|
7738
|
+
return getSupportedReasoningEfforts(modelSlug, models).includes(value);
|
|
7739
|
+
}
|
|
7599
7740
|
async function canListen(portToCheck) {
|
|
7600
7741
|
return await new Promise((resolve) => {
|
|
7601
7742
|
const probe = net.createServer();
|
|
@@ -7796,12 +7937,16 @@ function isRemoteAuthenticated(request, config) {
|
|
|
7796
7937
|
return timingSafeMatch(parseCookies(request).get(AUTH_COOKIE_NAME), config.uiAccessToken);
|
|
7797
7938
|
}
|
|
7798
7939
|
function configToPayload(config) {
|
|
7940
|
+
const codexDefaultModel = readConfiguredCodexModel() || "";
|
|
7941
|
+
const availableModels = getAvailableCodexModels([config.defaultModel || "", codexDefaultModel]);
|
|
7942
|
+
const effectiveModel = config.defaultModel || codexDefaultModel;
|
|
7799
7943
|
return {
|
|
7800
7944
|
runtime: config.runtime,
|
|
7801
7945
|
defaultWorkspaceRoot: config.defaultWorkspaceRoot || "",
|
|
7802
7946
|
defaultModel: config.defaultModel || "",
|
|
7803
|
-
codexDefaultModel
|
|
7804
|
-
availableModels
|
|
7947
|
+
codexDefaultModel,
|
|
7948
|
+
availableModels,
|
|
7949
|
+
availableReasoningEfforts: getSupportedReasoningEfforts(effectiveModel, availableModels),
|
|
7805
7950
|
defaultMode: config.defaultMode,
|
|
7806
7951
|
historyMessageLimit: config.historyMessageLimit ?? 8,
|
|
7807
7952
|
streamStatusIdleStartSeconds: config.streamStatusIdleStartSeconds ?? 180,
|
|
@@ -7816,7 +7961,21 @@ function configToPayload(config) {
|
|
|
7816
7961
|
}
|
|
7817
7962
|
function mergeConfig(payload) {
|
|
7818
7963
|
const current = loadConfig();
|
|
7964
|
+
const codexDefaultModel = readConfiguredCodexModel() || "";
|
|
7819
7965
|
const rawDefaultModel = typeof payload.defaultModel === "string" ? payload.defaultModel.trim() : void 0;
|
|
7966
|
+
const availableCodexModels = getAvailableCodexModels([
|
|
7967
|
+
current.defaultModel || "",
|
|
7968
|
+
codexDefaultModel,
|
|
7969
|
+
rawDefaultModel || ""
|
|
7970
|
+
]);
|
|
7971
|
+
const availableCodexModelSlugs = getAvailableCodexModelSlugs(availableCodexModels);
|
|
7972
|
+
const nextDefaultModel = rawDefaultModel === void 0 ? current.defaultModel : rawDefaultModel === "" ? void 0 : availableCodexModelSlugs.has(rawDefaultModel) ? rawDefaultModel : current.defaultModel;
|
|
7973
|
+
const currentEffectiveModel = current.defaultModel || codexDefaultModel;
|
|
7974
|
+
const nextEffectiveModel = nextDefaultModel || codexDefaultModel;
|
|
7975
|
+
const rawReasoningEffort = asString(payload.codexReasoningEffort);
|
|
7976
|
+
const parsedReasoningEffort = parseReasoningEffort(rawReasoningEffort);
|
|
7977
|
+
const preserveCurrentReasoning = parsedReasoningEffort && parsedReasoningEffort === current.codexReasoningEffort && nextEffectiveModel === currentEffectiveModel;
|
|
7978
|
+
const nextReasoningEffort = parsedReasoningEffort && (isReasoningEffortSupportedByModel(parsedReasoningEffort, nextEffectiveModel, availableCodexModels) || preserveCurrentReasoning) ? parsedReasoningEffort : getDefaultReasoningEffort(nextEffectiveModel, availableCodexModels);
|
|
7820
7979
|
const uiAllowLan = payload.uiAllowLan === true;
|
|
7821
7980
|
const requestedUiAccessToken = asString(payload.uiAccessToken);
|
|
7822
7981
|
const uiAccessToken = requestedUiAccessToken || current.uiAccessToken || (uiAllowLan ? generateAccessToken() : void 0);
|
|
@@ -7825,14 +7984,14 @@ function mergeConfig(payload) {
|
|
|
7825
7984
|
runtime: "codex",
|
|
7826
7985
|
enabledChannels: current.enabledChannels,
|
|
7827
7986
|
defaultWorkspaceRoot: asString(payload.defaultWorkspaceRoot),
|
|
7828
|
-
defaultModel:
|
|
7987
|
+
defaultModel: nextDefaultModel,
|
|
7829
7988
|
defaultMode: payload.defaultMode === "plan" || payload.defaultMode === "ask" ? payload.defaultMode : "code",
|
|
7830
7989
|
historyMessageLimit: asPositiveInt(payload.historyMessageLimit) || current.historyMessageLimit || 8,
|
|
7831
7990
|
streamStatusIdleStartSeconds: asPositiveInt(payload.streamStatusIdleStartSeconds) || current.streamStatusIdleStartSeconds || 180,
|
|
7832
7991
|
streamStatusCheckIntervalSeconds: asPositiveInt(payload.streamStatusCheckIntervalSeconds) || current.streamStatusCheckIntervalSeconds || 10,
|
|
7833
7992
|
codexSkipGitRepoCheck: payload.codexSkipGitRepoCheck === true,
|
|
7834
7993
|
codexSandboxMode: payload.codexSandboxMode === "read-only" || payload.codexSandboxMode === "danger-full-access" ? payload.codexSandboxMode : "workspace-write",
|
|
7835
|
-
codexReasoningEffort:
|
|
7994
|
+
codexReasoningEffort: nextReasoningEffort,
|
|
7836
7995
|
uiAllowLan,
|
|
7837
7996
|
uiAccessToken,
|
|
7838
7997
|
channels: current.channels
|
|
@@ -9692,16 +9851,10 @@ function renderHtml() {
|
|
|
9692
9851
|
</label>
|
|
9693
9852
|
<label>
|
|
9694
9853
|
Codex \u601D\u8003\u7EA7\u522B
|
|
9695
|
-
<select id="codexReasoningEffort">
|
|
9696
|
-
<option value="medium">medium</option>
|
|
9697
|
-
<option value="minimal">minimal</option>
|
|
9698
|
-
<option value="low">low</option>
|
|
9699
|
-
<option value="high">high</option>
|
|
9700
|
-
<option value="xhigh">xhigh</option>
|
|
9701
|
-
</select>
|
|
9854
|
+
<select id="codexReasoningEffort"></select>
|
|
9702
9855
|
</label>
|
|
9703
9856
|
</div>
|
|
9704
|
-
<div class="small">\u672A\u7ED1\u5B9A\u7684 IM \u804A\u5929\u4F1A\u5148\u8FDB\u5165\u4E34\u65F6\u8349\u7A3F\u7EBF\u7A0B\uFF08\u7B49\u540C <code>/t 0</code>\uFF09\uFF1B\u201C\u9ED8\u8BA4\u5DE5\u4F5C\u7A7A\u95F4\u201D\u53EA\u7528\u4E8E <code>/new proj1</code> \u8FD9\u7C7B\u76F8\u5BF9\u9879\u76EE\u540D\u3002\u7559\u7A7A\u65F6\u4F1A\u6309\u5F53\u524D\u7CFB\u7EDF\u81EA\u52A8\u56DE\u9000\u5230 <code>~/cx2im</code>\u3002\u9ED8\u8BA4\u6A21\u578B\u5019\u9009\u9879\u6765\u81EA\
|
|
9857
|
+
<div class="small">\u672A\u7ED1\u5B9A\u7684 IM \u804A\u5929\u4F1A\u5148\u8FDB\u5165\u4E34\u65F6\u8349\u7A3F\u7EBF\u7A0B\uFF08\u7B49\u540C <code>/t 0</code>\uFF09\uFF1B\u201C\u9ED8\u8BA4\u5DE5\u4F5C\u7A7A\u95F4\u201D\u53EA\u7528\u4E8E <code>/new proj1</code> \u8FD9\u7C7B\u76F8\u5BF9\u9879\u76EE\u540D\u3002\u7559\u7A7A\u65F6\u4F1A\u6309\u5F53\u524D\u7CFB\u7EDF\u81EA\u52A8\u56DE\u9000\u5230 <code>~/cx2im</code>\u3002\u9ED8\u8BA4\u6A21\u578B\u5019\u9009\u9879\u6765\u81EA\u6309\u9700\u8BFB\u53D6\u7684 Codex \u6A21\u578B\u7F13\u5B58\uFF1A\u9690\u85CF\u6A21\u578B\u4E0D\u4F1A\u5C55\u793A\uFF0CCLI only \u6A21\u578B\u4F1A\u6807\u6210\u201C\u4EC5 IM / CLI\u201D\u3002\u7559\u7A7A\u5219\u7EE7\u7EED\u8DDF\u968F Codex \u5F53\u524D\u9ED8\u8BA4\u6A21\u578B\u3002\u6587\u4EF6\u7CFB\u7EDF\u6743\u9650\u662F\u5168\u5C40\u9ED8\u8BA4\u503C\uFF0C\u601D\u8003\u7EA7\u522B\u53EF\u5728 IM \u4F1A\u8BDD\u91CC\u518D\u5355\u72EC\u8986\u76D6\u3002\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA\u914D\u7F6E\u53EA\u5F71\u54CD\u98DE\u4E66\u957F\u4EFB\u52A1\u5E95\u90E8\u201C\u4E0A\u6B21\u54CD\u5E94\u8DDD\u4ECA X\u201D\u7684\u51FA\u73B0\u65F6\u673A\u3002</div>
|
|
9705
9858
|
<div class="small">\u5F53\u524D\u9700\u8981\u91CD\u542F Bridge \u7684\u914D\u7F6E\uFF1A<code>Runtime</code>\u3001<code>\u5141\u8BB8\u5728\u672A\u4FE1\u4EFB Git \u76EE\u5F55\u8FD0\u884C Codex</code>\u3002\u901A\u9053\u5B9E\u4F8B\u7684\u63A5\u5165\u914D\u7F6E\u8BF7\u5728\u201C\u901A\u9053\u201D\u9875\u7EF4\u62A4\u3002</div>
|
|
9706
9859
|
<div class="checkbox-row">
|
|
9707
9860
|
<label class="checkbox"><input id="codexSkipGitRepoCheck" type="checkbox" checked /> \u5141\u8BB8\u5728\u672A\u4FE1\u4EFB Git \u76EE\u5F55\u8FD0\u884C Codex</label>
|
|
@@ -9776,7 +9929,7 @@ function renderHtml() {
|
|
|
9776
9929
|
<div class="command-list">
|
|
9777
9930
|
<div class="command-list-head"><div>\u547D\u4EE4</div><div>\u539F\u59CB\u547D\u4EE4</div><div>\u8BF4\u660E</div></div>
|
|
9778
9931
|
<div class="command-item"><div class="command-col-command"><code>/m</code></div><div class="command-col-original"><code>/mode</code></div><div class="command-col-desc">\u67E5\u770B\u5F53\u524D\u6A21\u5F0F\uFF1B\u53EF\u9009 <code>code</code>\u3001<code>plan</code>\u3001<code>ask</code>\u3002</div></div>
|
|
9779
|
-
<div class="command-item"><div class="command-col-command"><code>/r</code></div><div class="command-col-original"><code>/reasoning</code></div><div class="command-col-desc">\u67E5\u770B\u5F53\u524D\u601D\u8003\u7EA7\u522B\uFF1B\u53EF\u9009 <code>
|
|
9932
|
+
<div class="command-item"><div class="command-col-command"><code>/r</code></div><div class="command-col-original"><code>/reasoning</code></div><div class="command-col-desc">\u67E5\u770B\u5F53\u524D\u601D\u8003\u7EA7\u522B\uFF1B\u53EF\u9009 <code>low</code>\u3001<code>medium</code>\u3001<code>high</code>\u3001<code>xhigh</code>\uFF0C\u90E8\u5206\u65B0\u6A21\u578B\u8FD8\u652F\u6301 <code>max</code>\u3001<code>ultra</code>\u3002</div></div>
|
|
9780
9933
|
<div class="command-item"><div class="command-col-command"><code>/model [slug|default]</code></div><div class="command-col-original"><code>/model [slug|default]</code></div><div class="command-col-desc">\u67E5\u770B\u6216\u5207\u6362\u5F53\u524D IM \u4F1A\u8BDD\u4F7F\u7528\u7684\u6A21\u578B\uFF1BCLI only \u6A21\u578B\u4F1A\u6807\u6CE8\u201C\u4EC5 IM / CLI\u201D\uFF0C\u5171\u4EAB\u684C\u9762\u7EBF\u7A0B\u53EA\u5141\u8BB8\u67E5\u770B\u4E0D\u5141\u8BB8\u5207\u6362\u3002</div></div>
|
|
9781
9934
|
<div class="command-item"><div class="command-col-command"><code>/t 0</code></div><div class="command-col-original"><code>/thread 0</code></div><div class="command-col-desc">\u5207\u6362\u5230\u5F53\u524D\u804A\u5929\u7684\u4E34\u65F6\u8349\u7A3F\u7EBF\u7A0B\u3002</div></div>
|
|
9782
9935
|
<div class="command-item"><div class="command-col-command"><code>/t 0 reset</code></div><div class="command-col-original"><code>/thread 0 reset</code></div><div class="command-col-desc">\u4E22\u5F03\u5F53\u524D\u8349\u7A3F\u4E0A\u4E0B\u6587\u5E76\u91CD\u5EFA\u4E00\u6761\u65B0\u7684\u8349\u7A3F\u7EBF\u7A0B\u3002</div></div>
|
|
@@ -9930,6 +10083,89 @@ function renderHtml() {
|
|
|
9930
10083
|
select.value = currentValue;
|
|
9931
10084
|
}
|
|
9932
10085
|
|
|
10086
|
+
function findAvailableModel(slug) {
|
|
10087
|
+
if (!slug) return null;
|
|
10088
|
+
return (state.availableModels || []).find((model) => model && model.slug === slug) || null;
|
|
10089
|
+
}
|
|
10090
|
+
|
|
10091
|
+
function fallbackReasoningLevels(config) {
|
|
10092
|
+
const efforts = Array.isArray(config && config.availableReasoningEfforts)
|
|
10093
|
+
? config.availableReasoningEfforts
|
|
10094
|
+
: ['low', 'medium', 'high', 'xhigh'];
|
|
10095
|
+
return efforts
|
|
10096
|
+
.filter((effort) => typeof effort === 'string' && effort)
|
|
10097
|
+
.map((effort) => ({ effort, description: '' }));
|
|
10098
|
+
}
|
|
10099
|
+
|
|
10100
|
+
function reasoningLevelsForModel(config, modelSlug) {
|
|
10101
|
+
const model = findAvailableModel(modelSlug);
|
|
10102
|
+
const levels = model && Array.isArray(model.supportedReasoningLevels)
|
|
10103
|
+
? model.supportedReasoningLevels
|
|
10104
|
+
: [];
|
|
10105
|
+
if (levels.length === 0) return fallbackReasoningLevels(config);
|
|
10106
|
+
return levels
|
|
10107
|
+
.filter((level) => level && typeof level.effort === 'string' && level.effort)
|
|
10108
|
+
.map((level) => ({
|
|
10109
|
+
effort: level.effort,
|
|
10110
|
+
description: typeof level.description === 'string' ? level.description : '',
|
|
10111
|
+
}));
|
|
10112
|
+
}
|
|
10113
|
+
|
|
10114
|
+
function defaultReasoningForModel(config, modelSlug, levels) {
|
|
10115
|
+
const model = findAvailableModel(modelSlug);
|
|
10116
|
+
const catalogDefault = model && typeof model.defaultReasoningLevel === 'string'
|
|
10117
|
+
? model.defaultReasoningLevel
|
|
10118
|
+
: '';
|
|
10119
|
+
if (catalogDefault && levels.some((level) => level.effort === catalogDefault)) {
|
|
10120
|
+
return catalogDefault;
|
|
10121
|
+
}
|
|
10122
|
+
if (levels.some((level) => level.effort === 'medium')) return 'medium';
|
|
10123
|
+
return levels[0] ? levels[0].effort : (config.codexReasoningEffort || 'medium');
|
|
10124
|
+
}
|
|
10125
|
+
|
|
10126
|
+
function selectedDefaultModel(config) {
|
|
10127
|
+
const select = document.getElementById('defaultModel');
|
|
10128
|
+
const selected = select ? select.value : '';
|
|
10129
|
+
return selected || (config && config.codexDefaultModel) || '';
|
|
10130
|
+
}
|
|
10131
|
+
|
|
10132
|
+
function renderReasoningEffortOptions(config, options) {
|
|
10133
|
+
const opts = options || {};
|
|
10134
|
+
const select = document.getElementById('codexReasoningEffort');
|
|
10135
|
+
const modelSlug = selectedDefaultModel(config || {});
|
|
10136
|
+
const levels = reasoningLevelsForModel(config || {}, modelSlug);
|
|
10137
|
+
const currentValue = typeof opts.currentValue === 'string'
|
|
10138
|
+
? opts.currentValue
|
|
10139
|
+
: (config && typeof config.codexReasoningEffort === 'string' ? config.codexReasoningEffort : 'medium');
|
|
10140
|
+
const preserveUnsupported = opts.preserveUnsupported !== false;
|
|
10141
|
+
const modelDefault = defaultReasoningForModel(config || {}, modelSlug, levels);
|
|
10142
|
+
const items = [];
|
|
10143
|
+
const seen = new Set();
|
|
10144
|
+
|
|
10145
|
+
for (const level of levels) {
|
|
10146
|
+
if (seen.has(level.effort)) continue;
|
|
10147
|
+
seen.add(level.effort);
|
|
10148
|
+
const labelParts = [level.effort];
|
|
10149
|
+
if (level.effort === modelDefault) labelParts.push('\u6A21\u578B\u9ED8\u8BA4');
|
|
10150
|
+
if (level.description) labelParts.push(level.description);
|
|
10151
|
+
items.push(
|
|
10152
|
+
'<option value="' + escapeHtml(level.effort) + '">' + escapeHtml(labelParts.join(' \xB7 ')) + '</option>'
|
|
10153
|
+
);
|
|
10154
|
+
}
|
|
10155
|
+
|
|
10156
|
+
if (currentValue && !seen.has(currentValue) && preserveUnsupported) {
|
|
10157
|
+
items.push(
|
|
10158
|
+
'<option value="' + escapeHtml(currentValue) + '">\u5F53\u524D\u914D\u7F6E\u503C\uFF08\u5F53\u524D\u6A21\u578B\u672A\u5217\u51FA\uFF09\uFF1A' + escapeHtml(currentValue) + '</option>'
|
|
10159
|
+
);
|
|
10160
|
+
}
|
|
10161
|
+
|
|
10162
|
+
select.innerHTML = items.join('');
|
|
10163
|
+
select.value = seen.has(currentValue) || preserveUnsupported ? currentValue : modelDefault;
|
|
10164
|
+
if (!select.value && items.length > 0) {
|
|
10165
|
+
select.value = modelDefault;
|
|
10166
|
+
}
|
|
10167
|
+
}
|
|
10168
|
+
|
|
9933
10169
|
function shortId(value) {
|
|
9934
10170
|
if (!value) return '-';
|
|
9935
10171
|
return value.length > 14 ? value.slice(0, 8) + '...' + value.slice(-4) : value;
|
|
@@ -10794,9 +11030,9 @@ function renderHtml() {
|
|
|
10794
11030
|
document.getElementById('streamStatusCheckIntervalSeconds').value = String(config.streamStatusCheckIntervalSeconds || 10);
|
|
10795
11031
|
document.getElementById('defaultWorkspaceRoot').value = config.defaultWorkspaceRoot || '';
|
|
10796
11032
|
renderDefaultModelOptions(config);
|
|
11033
|
+
renderReasoningEffortOptions(config);
|
|
10797
11034
|
document.getElementById('codexSkipGitRepoCheck').checked = config.codexSkipGitRepoCheck === true;
|
|
10798
11035
|
document.getElementById('codexSandboxMode').value = config.codexSandboxMode || 'workspace-write';
|
|
10799
|
-
document.getElementById('codexReasoningEffort').value = config.codexReasoningEffort || 'medium';
|
|
10800
11036
|
document.getElementById('uiAllowLan').checked = config.uiAllowLan === true;
|
|
10801
11037
|
document.getElementById('uiAccessToken').value = config.uiAccessToken || '';
|
|
10802
11038
|
renderUiAccess();
|
|
@@ -11204,6 +11440,13 @@ function renderHtml() {
|
|
|
11204
11440
|
showMessage('configMessage', 'success', '\u5DF2\u751F\u6210\u65B0\u7684\u8BBF\u95EE token\uFF0C\u70B9\u51FB\u201C\u4FDD\u5B58\u914D\u7F6E\u201D\u540E\u751F\u6548\u3002');
|
|
11205
11441
|
});
|
|
11206
11442
|
|
|
11443
|
+
document.getElementById('defaultModel').addEventListener('change', () => {
|
|
11444
|
+
renderReasoningEffortOptions(state.config || {}, {
|
|
11445
|
+
currentValue: document.getElementById('codexReasoningEffort').value,
|
|
11446
|
+
preserveUnsupported: false,
|
|
11447
|
+
});
|
|
11448
|
+
});
|
|
11449
|
+
|
|
11207
11450
|
document.getElementById('saveConfigBtn').addEventListener('click', async () => {
|
|
11208
11451
|
try {
|
|
11209
11452
|
await saveConfig({ messageId: 'configMessage', scope: 'all' });
|
package/docs/install-windows.md
CHANGED
|
@@ -234,7 +234,7 @@ Web 工作台现在只展示自动启动状态;真正的启用和关闭请使
|
|
|
234
234
|
- 另外,当前 `codex` runtime 下正文通常不是逐字流式输出;更常见的效果是先显示 `Thinking / Tool Progress`,正文在回答完成时一次性落到卡片里。
|
|
235
235
|
- IM 里发送 `/history` 可以查看当前会话最近 N 条消息,N 由“基础配置”中的返回条数控制。
|
|
236
236
|
- IM 里发送 `/history` 默认返回整理后的摘要;发送 `/history raw` 才会查看最近 N 条原始消息。
|
|
237
|
-
- IM 里发送 `/reasoning high` 或 `/reasoning 4`
|
|
237
|
+
- IM 里发送 `/reasoning high`、`/reasoning max` 或 `/reasoning 4` 之类命令,可以只对当前会话覆盖思考级别;具体可用档位取决于当前模型。
|
|
238
238
|
- IM 里发送 `/thread 0` 会进入临时草稿线程,适合短讨论或临时想法。
|
|
239
239
|
- “通道”页现在管理的是多个通道实例,而不是固定的一组飞书/微信配置。
|
|
240
240
|
- 每个实例都可以有自己的别名;别名只用于区分不同聊天入口,不会改变 Codex 会话语义。
|
|
@@ -249,7 +249,7 @@ Web 工作台现在只展示自动启动状态;真正的启用和关闭请使
|
|
|
249
249
|
- `/n` / `/new` 在当前正式会话目录下新建线程;这类线程当前只保证在 IM 中可继续,不会自动出现在 Codex Desktop 会话列表中
|
|
250
250
|
- `/n proj1` / `/new proj1` 新建项目会话
|
|
251
251
|
- `/m` / `/mode` 查看或切换模式,可选 `code` / `plan` / `ask`
|
|
252
|
-
- `/r` / `/reasoning`
|
|
252
|
+
- `/r` / `/reasoning` 查看或切换思考级别,支持 `low|medium|high|xhigh|max|ultra`,数字 `1|2|3|4|5|6|7` 作为兼容别名
|
|
253
253
|
- `/his` / `/history` 历史摘要,`/his raw` / `/history raw` 原始记录
|
|
254
254
|
- `/t 0` / `/thread 0` 临时草稿线程
|
|
255
255
|
- 如果 `测试 Codex` 失败,优先检查当前 Windows 用户下是否已经存在可用的 Codex 登录态或 API Key。
|
package/package.json
CHANGED