@modelzen/feishu-codex-bridge 0.4.2 → 0.4.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/dist/cli.js +233 -75
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -127,6 +127,13 @@ function secretKeyForApp(appId) {
|
|
|
127
127
|
function getShowToolCalls(cfg) {
|
|
128
128
|
return cfg.preferences?.showToolCalls !== false;
|
|
129
129
|
}
|
|
130
|
+
function getModelDisplay(cfg) {
|
|
131
|
+
const v = cfg.preferences?.showModel;
|
|
132
|
+
if (v === "running" || v === "always" || v === "off") return v;
|
|
133
|
+
if (v === true) return "always";
|
|
134
|
+
if (v === false) return "off";
|
|
135
|
+
return "running";
|
|
136
|
+
}
|
|
130
137
|
function getMaxConcurrentRuns(cfg) {
|
|
131
138
|
const raw = cfg.preferences?.maxConcurrentRuns;
|
|
132
139
|
if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 1) return 10;
|
|
@@ -3347,6 +3354,7 @@ var DM = {
|
|
|
3347
3354
|
rmDo: "dm.rmDo",
|
|
3348
3355
|
rmCancel: "dm.rmCancel",
|
|
3349
3356
|
setTools: "dm.set.tools",
|
|
3357
|
+
setShowModel: "dm.set.showModel",
|
|
3350
3358
|
setWatchdog: "dm.set.watchdog",
|
|
3351
3359
|
// 假死超时「自定义…」:watchdogCustom 打开输入卡,watchdogCustomSubmit 保存任意秒数
|
|
3352
3360
|
watchdogCustom: "dm.set.watchdog.custom",
|
|
@@ -3503,6 +3511,17 @@ function buildUpdateCard(state) {
|
|
|
3503
3511
|
);
|
|
3504
3512
|
}
|
|
3505
3513
|
}
|
|
3514
|
+
function buildReconnectCard(conn) {
|
|
3515
|
+
const template = conn === "connected" ? "green" : "orange";
|
|
3516
|
+
return card(
|
|
3517
|
+
[
|
|
3518
|
+
md(`\u957F\u8FDE\u63A5\u72B6\u6001\uFF1A**${conn}**`),
|
|
3519
|
+
note("SDK \u4F1A\u81EA\u52A8\u91CD\u8FDE\uFF1B\u82E5\u957F\u671F\u65AD\u5F00\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u91CD\u8DD1 `feishu-codex-bridge run`\uFF08\u524D\u53F0\uFF09\u6216 `feishu-codex-bridge restart`\uFF08\u540E\u53F0\u5B88\u62A4\uFF09\u3002"),
|
|
3520
|
+
backToMenu()
|
|
3521
|
+
],
|
|
3522
|
+
{ header: { title: "\u{1F504} \u957F\u8FDE\u63A5", template } }
|
|
3523
|
+
);
|
|
3524
|
+
}
|
|
3506
3525
|
function connLabel(state) {
|
|
3507
3526
|
switch (state) {
|
|
3508
3527
|
case "connected":
|
|
@@ -3809,38 +3828,78 @@ function optionRow(label, actionId, current, opts) {
|
|
|
3809
3828
|
actions(opts.map((o) => button(o.label, { a: actionId, v: o.value }, o.value === current ? "primary" : "default")))
|
|
3810
3829
|
];
|
|
3811
3830
|
}
|
|
3831
|
+
function settingSection(title) {
|
|
3832
|
+
return { tag: "markdown", content: `**${title}**`, text_size: "notation", text_color: "grey" };
|
|
3833
|
+
}
|
|
3834
|
+
function settingItem(name, desc, actionId, current, opts) {
|
|
3835
|
+
return [
|
|
3836
|
+
md(`**${name}**`),
|
|
3837
|
+
note(desc),
|
|
3838
|
+
actions(opts.map((o) => button(o.label, { a: actionId, v: o.value }, o.value === current ? "primary" : "default")))
|
|
3839
|
+
];
|
|
3840
|
+
}
|
|
3812
3841
|
function buildSettingsCard(cfg) {
|
|
3813
3842
|
const watchdogSec = cfg.preferences?.runIdleTimeoutSeconds ?? 120;
|
|
3814
3843
|
return card(
|
|
3815
3844
|
[
|
|
3816
|
-
|
|
3817
|
-
...
|
|
3818
|
-
{
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3845
|
+
settingSection("\u{1F4E4} \u8F93\u51FA\u5C55\u793A"),
|
|
3846
|
+
...settingItem(
|
|
3847
|
+
"\u{1F527} \u5DE5\u5177\u8C03\u7528",
|
|
3848
|
+
"\u8F93\u51FA\u65F6\u663E\u793A\u6267\u884C\u7684\u547D\u4EE4 / \u5DE5\u5177\u8C03\u7528\uFF1B\u5173\u6389\u53EA\u770B\u6700\u7EC8\u56DE\u7B54\u3002",
|
|
3849
|
+
DM.setTools,
|
|
3850
|
+
getShowToolCalls(cfg) ? "on" : "off",
|
|
3851
|
+
[
|
|
3852
|
+
{ label: "\u663E\u793A", value: "on" },
|
|
3853
|
+
{ label: "\u9690\u85CF", value: "off" }
|
|
3854
|
+
]
|
|
3855
|
+
),
|
|
3856
|
+
...settingItem(
|
|
3857
|
+
"\u{1F9E0} \u6A21\u578B\u663E\u793A",
|
|
3858
|
+
"\u6BCF\u6761\u56DE\u590D\u53F3\u4E0B\u89D2\u663E\u793A\u300C\u6A21\u578B \xB7 \u63A8\u7406\u5F3A\u5EA6\u300D\u3002\u4EC5\u8F93\u51FA\u65F6\uFF1D\u53EA\u5728\u751F\u6210\u4E2D\u663E\u793A\uFF1B\u59CB\u7EC8\uFF1D\u751F\u6210\u5B8C\u540E\u5361\u7247\u4E5F\u4FDD\u7559\u3002",
|
|
3859
|
+
DM.setShowModel,
|
|
3860
|
+
getModelDisplay(cfg),
|
|
3861
|
+
[
|
|
3862
|
+
{ label: "\u5173\u95ED", value: "off" },
|
|
3863
|
+
{ label: "\u4EC5\u8F93\u51FA\u65F6", value: "running" },
|
|
3864
|
+
{ label: "\u59CB\u7EC8", value: "always" }
|
|
3865
|
+
]
|
|
3866
|
+
),
|
|
3867
|
+
hr(),
|
|
3868
|
+
settingSection("\u23F1 \u8FD0\u884C\u63A7\u5236"),
|
|
3869
|
+
md(`**\u23F1 \u5047\u6B7B\u8D85\u65F6** \xB7 \u5F53\u524D **${watchdogSec === 0 ? "\u5173\u95ED" : `${watchdogSec} \u79D2`}**`),
|
|
3870
|
+
note("\u591A\u4E45\u6CA1\u6709\u4EFB\u4F55\u8F93\u51FA\u5C31\u81EA\u52A8\u7EC8\u6B62\u672C\u8F6E\uFF08\u9632\u5361\u6B7B\uFF09\u3002"),
|
|
3822
3871
|
actions([
|
|
3823
3872
|
...[0, 120, 300].map(
|
|
3824
3873
|
(v) => button(v === 0 ? "\u5173\u95ED" : `${v}\u79D2`, { a: DM.setWatchdog, v: String(v) }, v === watchdogSec ? "primary" : "default")
|
|
3825
3874
|
),
|
|
3826
3875
|
button("\u81EA\u5B9A\u4E49\u2026", { a: DM.watchdogCustom })
|
|
3827
3876
|
]),
|
|
3828
|
-
...
|
|
3829
|
-
{
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3877
|
+
...settingItem(
|
|
3878
|
+
"\u{1F4E5} \u8FD0\u884C\u4E2D\u6765\u65B0\u6D88\u606F",
|
|
3879
|
+
"\u6B63\u5728\u8DD1\u65F6\u4F60\u53C8\u53D1\u6D88\u606F\uFF1A\u5F15\u5BFC\uFF1D\u63D2\u8FDB\u5F53\u524D\u8F6E\u7EA0\u504F\uFF1B\u6392\u961F\uFF1D\u7B49\u8FD9\u8F6E\u8DD1\u5B8C\u518D\u5904\u7406\u3002",
|
|
3880
|
+
DM.setPending,
|
|
3881
|
+
getPendingPolicy(cfg),
|
|
3882
|
+
[
|
|
3883
|
+
{ label: "\u5F15\u5BFC", value: "steer" },
|
|
3884
|
+
{ label: "\u6392\u961F", value: "queue" }
|
|
3885
|
+
]
|
|
3886
|
+
),
|
|
3887
|
+
...settingItem(
|
|
3888
|
+
"\u26A1 \u5E76\u53D1\u4E0A\u9650",
|
|
3889
|
+
"\u6240\u6709\u7FA4 / \u8BDD\u9898\u5168\u5C40\u540C\u65F6\u6700\u591A\u8DD1\u51E0\u4E2A\uFF0C\u6EE1\u4E86\u6392\u961F\uFF08\u6392\u961F\u5361\u53EF \u23F9 \u53D6\u6D88\uFF09\u3002\u6539\u540E\u9700\u91CD\u542F\u751F\u6548\u3002",
|
|
3890
|
+
DM.setConcurrency,
|
|
3891
|
+
String(getMaxConcurrentRuns(cfg)),
|
|
3892
|
+
[
|
|
3893
|
+
{ label: "1", value: "1" },
|
|
3894
|
+
{ label: "5", value: "5" },
|
|
3895
|
+
{ label: "10", value: "10" },
|
|
3896
|
+
{ label: "20", value: "20" }
|
|
3897
|
+
]
|
|
3898
|
+
),
|
|
3840
3899
|
hr(),
|
|
3841
3900
|
actions([button("\u{1F46E} \u7BA1\u7406\u5458", { a: DM.admins }), button("\u2B05\uFE0F \u83DC\u5355", { a: DM.menu })])
|
|
3842
3901
|
],
|
|
3843
|
-
{ header: { title: "\u2699\uFE0F \u8BBE\u7F6E", template: "blue" } }
|
|
3902
|
+
{ header: { title: "\u2699\uFE0F \u5168\u5C40\u8BBE\u7F6E", template: "blue" } }
|
|
3844
3903
|
);
|
|
3845
3904
|
}
|
|
3846
3905
|
function buildWatchdogCustomCard(cfg) {
|
|
@@ -4904,24 +4963,6 @@ function buildRunCard(rc) {
|
|
|
4904
4963
|
}
|
|
4905
4964
|
function renderRunning(state, rc) {
|
|
4906
4965
|
const elements = [];
|
|
4907
|
-
if (rc.cardKey && rc.goalControls) {
|
|
4908
|
-
if (rc.goalEnding) {
|
|
4909
|
-
elements.push(actions([button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger")], CONTROLS_EID));
|
|
4910
|
-
elements.push(noteMd("_\u{1F3AF} \u76EE\u6807\u5DF2\u89E3\u9664\uFF0C\u672C\u8F6E\u8F93\u51FA\u5B8C\u6210\u540E\u505C\u6B62_"));
|
|
4911
|
-
} else {
|
|
4912
|
-
elements.push(
|
|
4913
|
-
actions(
|
|
4914
|
-
[
|
|
4915
|
-
button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger"),
|
|
4916
|
-
button("\u{1F3AF} \u7ED3\u675F\u76EE\u6807", { a: RC.endGoal, m: rc.cardKey }, "default")
|
|
4917
|
-
],
|
|
4918
|
-
CONTROLS_EID
|
|
4919
|
-
)
|
|
4920
|
-
);
|
|
4921
|
-
}
|
|
4922
|
-
} else if (rc.cardKey && !rc.hideStop) {
|
|
4923
|
-
elements.push(actions([button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger")], CONTROLS_EID));
|
|
4924
|
-
}
|
|
4925
4966
|
const reasoning = reasoningContent(state);
|
|
4926
4967
|
if (reasoning) elements.push(reasoningPanel(reasoning, state.reasoningActive));
|
|
4927
4968
|
const showTools = rc.showTools !== false;
|
|
@@ -4937,9 +4978,30 @@ function renderRunning(state, rc) {
|
|
|
4937
4978
|
if (tools.length > 0) elements.push(...renderToolGroup(tools, false));
|
|
4938
4979
|
const answer = textParts.join("\n\n");
|
|
4939
4980
|
if (answer) elements.push(mdStream(answer, ANSWER_EID));
|
|
4940
|
-
|
|
4981
|
+
const mEl = modelEl(rc);
|
|
4982
|
+
if (state.footer && mEl) elements.push(splitRow(footerStatus(state.footer), mEl));
|
|
4983
|
+
else if (state.footer) elements.push(footerStatus(state.footer));
|
|
4984
|
+
else if (mEl) elements.push(mEl);
|
|
4941
4985
|
const gauge = gaugeEl(state);
|
|
4942
4986
|
if (gauge) elements.push(gauge);
|
|
4987
|
+
if (rc.cardKey && rc.goalControls) {
|
|
4988
|
+
if (rc.goalEnding) {
|
|
4989
|
+
elements.push(noteMd("_\u{1F3AF} \u76EE\u6807\u5DF2\u89E3\u9664\uFF0C\u672C\u8F6E\u8F93\u51FA\u5B8C\u6210\u540E\u505C\u6B62_"));
|
|
4990
|
+
elements.push(actions([button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger")], CONTROLS_EID));
|
|
4991
|
+
} else {
|
|
4992
|
+
elements.push(
|
|
4993
|
+
actions(
|
|
4994
|
+
[
|
|
4995
|
+
button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger"),
|
|
4996
|
+
button("\u{1F3AF} \u7ED3\u675F\u76EE\u6807", { a: RC.endGoal, m: rc.cardKey }, "default")
|
|
4997
|
+
],
|
|
4998
|
+
CONTROLS_EID
|
|
4999
|
+
)
|
|
5000
|
+
);
|
|
5001
|
+
}
|
|
5002
|
+
} else if (rc.cardKey && !rc.hideStop) {
|
|
5003
|
+
elements.push(actions([button("\u23F9 \u7EC8\u6B62", { a: RC.stop, m: rc.cardKey }, "danger")], CONTROLS_EID));
|
|
5004
|
+
}
|
|
4943
5005
|
return elements;
|
|
4944
5006
|
}
|
|
4945
5007
|
function renderTerminal(state, rc) {
|
|
@@ -4977,6 +5039,8 @@ function renderTerminal(state, rc) {
|
|
|
4977
5039
|
}
|
|
4978
5040
|
const gauge = gaugeEl(state);
|
|
4979
5041
|
if (gauge) elements.push(gauge);
|
|
5042
|
+
const mEl = rc.modelOnTerminal ? modelEl(rc) : null;
|
|
5043
|
+
if (mEl) elements.push(mEl);
|
|
4980
5044
|
return elements;
|
|
4981
5045
|
}
|
|
4982
5046
|
function errorAdvice(msg) {
|
|
@@ -5098,9 +5162,35 @@ function collapsedToolSummary(tools, finalized) {
|
|
|
5098
5162
|
body: tools.map((t) => `- ${toolHeaderText(t)}`).join("\n")
|
|
5099
5163
|
});
|
|
5100
5164
|
}
|
|
5165
|
+
function footerStatusText(status) {
|
|
5166
|
+
return status === "thinking" ? "\u{1F9E0} \u6B63\u5728\u601D\u8003" : status === "tool_running" ? "\u{1F9F0} \u6B63\u5728\u8C03\u7528\u5DE5\u5177" : status === "retrying" ? "\u26A0\uFE0F \u77AC\u65AD\uFF0C\u81EA\u52A8\u91CD\u8BD5\u4E2D\u2026" : "\u270D\uFE0F \u6B63\u5728\u8F93\u51FA";
|
|
5167
|
+
}
|
|
5101
5168
|
function footerStatus(status) {
|
|
5102
|
-
|
|
5103
|
-
|
|
5169
|
+
return noteMd(footerStatusText(status));
|
|
5170
|
+
}
|
|
5171
|
+
var EFFORT_TIER = {
|
|
5172
|
+
none: { label: "\u65E0", color: "grey" },
|
|
5173
|
+
minimal: { label: "\u6781\u7B80", color: "grey" },
|
|
5174
|
+
low: { label: "\u4F4E", color: "yellow" },
|
|
5175
|
+
medium: { label: "\u4E2D", color: "green" },
|
|
5176
|
+
high: { label: "\u9AD8", color: "violet" },
|
|
5177
|
+
xhigh: { label: "\u6781\u9AD8", color: "purple" }
|
|
5178
|
+
};
|
|
5179
|
+
function modelEffortMd(model, effort) {
|
|
5180
|
+
if (!effort) return model;
|
|
5181
|
+
const t = EFFORT_TIER[effort];
|
|
5182
|
+
if (!t) return `${model} \xB7 ${effort}`;
|
|
5183
|
+
return `${model} \xB7 <font color='${t.color}'>${t.label}</font>`;
|
|
5184
|
+
}
|
|
5185
|
+
function modelEl(rc) {
|
|
5186
|
+
if (!rc.model) return null;
|
|
5187
|
+
return {
|
|
5188
|
+
tag: "markdown",
|
|
5189
|
+
content: modelEffortMd(rc.model, rc.effort),
|
|
5190
|
+
text_size: "notation",
|
|
5191
|
+
text_color: "grey",
|
|
5192
|
+
text_align: "right"
|
|
5193
|
+
};
|
|
5104
5194
|
}
|
|
5105
5195
|
function summaryText(state) {
|
|
5106
5196
|
if (state.terminal === "interrupted") return "\u5DF2\u4E2D\u65AD";
|
|
@@ -9034,6 +9124,35 @@ function createOrchestrator(channel, cfg, fallbackCwd) {
|
|
|
9034
9124
|
}
|
|
9035
9125
|
return buildProjectListCard(projects, byChat);
|
|
9036
9126
|
};
|
|
9127
|
+
const buildDoctorInfo = async () => {
|
|
9128
|
+
const codexProbe = await backend.doctor({ force: true });
|
|
9129
|
+
const app = cfg.accounts.app;
|
|
9130
|
+
const secret = await getSecret(secretKeyForApp(app.id)).catch(() => void 0);
|
|
9131
|
+
const scopeCheck = secret ? await validateAppCredentials(app.id, secret, app.tenant).catch(() => void 0) : void 0;
|
|
9132
|
+
const missingScopes = scopeCheck?.missingScopes;
|
|
9133
|
+
const missingJoinScopes = scopeCheck?.missingJoinScopes;
|
|
9134
|
+
return {
|
|
9135
|
+
codexOk: codexProbe.ok,
|
|
9136
|
+
codexVer: codexProbe.version,
|
|
9137
|
+
conn: channel.getConnectionStatus?.()?.state ?? "unknown",
|
|
9138
|
+
bridgeVer: bridgeVersion(),
|
|
9139
|
+
node: process.version,
|
|
9140
|
+
platform: `${process.platform}-${process.arch}`,
|
|
9141
|
+
logStdout: serviceStdoutPath(),
|
|
9142
|
+
logStderr: serviceStderrPath(),
|
|
9143
|
+
configFile: paths.configFile,
|
|
9144
|
+
missingScopes,
|
|
9145
|
+
// 缺失时预选缺失项(精准开通);查不到/全开通时预选全部必需 scope 供核对。
|
|
9146
|
+
scopeGrantUrl: buildScopeGrantUrl(
|
|
9147
|
+
app.id,
|
|
9148
|
+
app.tenant,
|
|
9149
|
+
missingScopes && missingScopes.length ? missingScopes : void 0
|
|
9150
|
+
),
|
|
9151
|
+
missingJoinScopes,
|
|
9152
|
+
// 「加入存量群」按钮恒预选这两项 opt-in scope(它们不在必需清单里)。
|
|
9153
|
+
joinScopeGrantUrl: buildScopeGrantUrl(app.id, app.tenant, JOIN_GROUP_SCOPES)
|
|
9154
|
+
};
|
|
9155
|
+
};
|
|
9037
9156
|
dispatcher.on(DM.menu, ({ evt }) => {
|
|
9038
9157
|
if (dmAdmin(evt.operator?.openId)) freshMenu(evt);
|
|
9039
9158
|
}).on(DM.newProject, ({ evt }) => {
|
|
@@ -9098,41 +9217,15 @@ function createOrchestrator(channel, cfg, fallbackCwd) {
|
|
|
9098
9217
|
if (dmAdmin(evt.operator?.openId)) await patch(evt, buildSettingsCard(cfg));
|
|
9099
9218
|
}).on(DM.doctor, async ({ evt }) => {
|
|
9100
9219
|
if (!dmAdmin(evt.operator?.openId)) return;
|
|
9101
|
-
|
|
9102
|
-
const app = cfg.accounts.app;
|
|
9103
|
-
const secret = await getSecret(secretKeyForApp(app.id)).catch(() => void 0);
|
|
9104
|
-
const scopeCheck = secret ? await validateAppCredentials(app.id, secret, app.tenant).catch(() => void 0) : void 0;
|
|
9105
|
-
const missingScopes = scopeCheck?.missingScopes;
|
|
9106
|
-
const missingJoinScopes = scopeCheck?.missingJoinScopes;
|
|
9107
|
-
const info = {
|
|
9108
|
-
codexOk: codexProbe.ok,
|
|
9109
|
-
codexVer: codexProbe.version,
|
|
9110
|
-
conn: channel.getConnectionStatus?.()?.state ?? "unknown",
|
|
9111
|
-
bridgeVer: bridgeVersion(),
|
|
9112
|
-
node: process.version,
|
|
9113
|
-
platform: `${process.platform}-${process.arch}`,
|
|
9114
|
-
logStdout: serviceStdoutPath(),
|
|
9115
|
-
logStderr: serviceStderrPath(),
|
|
9116
|
-
configFile: paths.configFile,
|
|
9117
|
-
missingScopes,
|
|
9118
|
-
// 缺失时预选缺失项(精准开通);查不到/全开通时预选全部必需 scope 供核对。
|
|
9119
|
-
scopeGrantUrl: buildScopeGrantUrl(
|
|
9120
|
-
app.id,
|
|
9121
|
-
app.tenant,
|
|
9122
|
-
missingScopes && missingScopes.length ? missingScopes : void 0
|
|
9123
|
-
),
|
|
9124
|
-
missingJoinScopes,
|
|
9125
|
-
// 「加入存量群」按钮恒预选这两项 opt-in scope(它们不在必需清单里)。
|
|
9126
|
-
joinScopeGrantUrl: buildScopeGrantUrl(app.id, app.tenant, JOIN_GROUP_SCOPES)
|
|
9127
|
-
};
|
|
9128
|
-
await sendManagedCard(channel, evt.chatId, buildDoctorCard(info), evt.messageId).catch(
|
|
9220
|
+
await sendManagedCard(channel, evt.chatId, buildDoctorCard(await buildDoctorInfo()), evt.messageId).catch(
|
|
9129
9221
|
(err) => log.fail("console", err, { cmd: "doctor" })
|
|
9130
9222
|
);
|
|
9131
9223
|
}).on(DM.reconnect, async ({ evt }) => {
|
|
9132
9224
|
if (!dmAdmin(evt.operator?.openId)) return;
|
|
9133
9225
|
const conn = channel.getConnectionStatus?.()?.state ?? "unknown";
|
|
9134
|
-
await channel
|
|
9135
|
-
|
|
9226
|
+
await sendManagedCard(channel, evt.chatId, buildReconnectCard(conn), evt.messageId).catch(
|
|
9227
|
+
(err) => log.fail("console", err, { cmd: "reconnect" })
|
|
9228
|
+
);
|
|
9136
9229
|
}).on(DM.update, ({ evt }) => {
|
|
9137
9230
|
if (!dmAdmin(evt.operator?.openId)) return;
|
|
9138
9231
|
void (async () => {
|
|
@@ -9239,6 +9332,10 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
|
|
|
9239
9332
|
});
|
|
9240
9333
|
}).on(DM.setTools, ({ evt, value }) => {
|
|
9241
9334
|
applyPref(evt, (p) => p.showToolCalls = value.v === "on");
|
|
9335
|
+
}).on(DM.setShowModel, ({ evt, value }) => {
|
|
9336
|
+
applyPref(evt, (p) => {
|
|
9337
|
+
p.showModel = value.v === "running" ? "running" : value.v === "always" ? "always" : "off";
|
|
9338
|
+
});
|
|
9242
9339
|
}).on(DM.setWatchdog, ({ evt, value }) => {
|
|
9243
9340
|
const n = Number(value.v);
|
|
9244
9341
|
if (Number.isFinite(n)) applyPref(evt, (p) => p.runIdleTimeoutSeconds = n);
|
|
@@ -9553,6 +9650,7 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
|
|
|
9553
9650
|
firstRec = void 0;
|
|
9554
9651
|
const turnModel = rec?.model ?? opts.model;
|
|
9555
9652
|
const turnEffort = rec?.effort ?? opts.effort;
|
|
9653
|
+
const modelDisp = getModelDisplay(cfg);
|
|
9556
9654
|
const run = opts.thread.runStreamed(turnInput, { model: turnModel, effort: turnEffort });
|
|
9557
9655
|
const turnStartAt = Date.now();
|
|
9558
9656
|
state.run = run;
|
|
@@ -9562,7 +9660,9 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
|
|
|
9562
9660
|
const rc = {
|
|
9563
9661
|
rs: render.snapshot(),
|
|
9564
9662
|
requesterOpenId: opts.requesterOpenId,
|
|
9565
|
-
showTools: render.showTools
|
|
9663
|
+
showTools: render.showTools,
|
|
9664
|
+
// 模型显示档位:footnote 本轮 model·推理强度;always 档终态卡也保留。
|
|
9665
|
+
...modelDisp !== "off" && turnModel ? { model: turnModel, effort: turnEffort, modelOnTerminal: modelDisp === "always" } : {}
|
|
9566
9666
|
};
|
|
9567
9667
|
const adoptThreadId = async (messageId) => {
|
|
9568
9668
|
if (activeKey.startsWith("pending:")) {
|
|
@@ -9841,7 +9941,14 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
|
|
|
9841
9941
|
const startTurn = () => {
|
|
9842
9942
|
const render = new RunRender();
|
|
9843
9943
|
render.showTools = getShowToolCalls(cfg);
|
|
9844
|
-
const
|
|
9944
|
+
const goalModelDisp = getModelDisplay(cfg);
|
|
9945
|
+
const rc = {
|
|
9946
|
+
rs: render.snapshot(),
|
|
9947
|
+
requesterOpenId: opts.requesterOpenId,
|
|
9948
|
+
showTools: render.showTools,
|
|
9949
|
+
goalControls: true,
|
|
9950
|
+
...goalModelDisp !== "off" && opts.model ? { model: opts.model, effort: opts.effort, modelOnTerminal: goalModelDisp === "always" } : {}
|
|
9951
|
+
};
|
|
9845
9952
|
return { render, rc, stream: null, cardMsgId: null };
|
|
9846
9953
|
};
|
|
9847
9954
|
const ensureCard = async (ctx) => {
|
|
@@ -10208,9 +10315,60 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
|
|
|
10208
10315
|
}).catch(() => void 0);
|
|
10209
10316
|
return;
|
|
10210
10317
|
}
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10318
|
+
const sendDm = (c) => sendManagedCard(channel, op, c, void 0, false, "open_id");
|
|
10319
|
+
try {
|
|
10320
|
+
switch (evt.eventKey) {
|
|
10321
|
+
case DM.newProject:
|
|
10322
|
+
await sendDm(buildNewProjectFormCard({ backends: backendOptionsFor("full") }));
|
|
10323
|
+
break;
|
|
10324
|
+
case DM.projects:
|
|
10325
|
+
await sendDm(await renderProjectList());
|
|
10326
|
+
break;
|
|
10327
|
+
case DM.settings:
|
|
10328
|
+
await sendDm(buildSettingsCard(cfg));
|
|
10329
|
+
break;
|
|
10330
|
+
case DM.doctor:
|
|
10331
|
+
await sendDm(buildDoctorCard(await buildDoctorInfo()));
|
|
10332
|
+
break;
|
|
10333
|
+
case DM.reconnect:
|
|
10334
|
+
await sendDm(buildReconnectCard(channel.getConnectionStatus?.()?.state ?? "unknown"));
|
|
10335
|
+
break;
|
|
10336
|
+
case DM.usage: {
|
|
10337
|
+
const { messageId } = await sendDm(buildUsageCard({ phase: "loading" }));
|
|
10338
|
+
let state;
|
|
10339
|
+
try {
|
|
10340
|
+
state = { phase: "ready", data: await fetchUsageBundle(false) };
|
|
10341
|
+
} catch (e) {
|
|
10342
|
+
log.fail("console", e, { phase: "usage", via: "menu" });
|
|
10343
|
+
state = {
|
|
10344
|
+
phase: "error",
|
|
10345
|
+
kind: e instanceof UsageError ? e.kind : "transient",
|
|
10346
|
+
message: e instanceof Error ? e.message : String(e)
|
|
10347
|
+
};
|
|
10348
|
+
}
|
|
10349
|
+
const ok = await updateManagedCard(channel, messageId, buildUsageCard(state)).catch(() => false);
|
|
10350
|
+
if (!ok) await sendDm(buildUsageCard(state));
|
|
10351
|
+
break;
|
|
10352
|
+
}
|
|
10353
|
+
case DM.update: {
|
|
10354
|
+
const { messageId } = await sendDm(buildUpdateCard({ phase: "checking" }));
|
|
10355
|
+
const current = currentVersion();
|
|
10356
|
+
const latest = await latestVersion().catch(() => null);
|
|
10357
|
+
const hasUpdate = !!latest && isNewer(latest, current);
|
|
10358
|
+
log.info("console", "update-check", { current, latest, hasUpdate, via: "menu" });
|
|
10359
|
+
await updateManagedCard(
|
|
10360
|
+
channel,
|
|
10361
|
+
messageId,
|
|
10362
|
+
buildUpdateCard({ phase: "checked", current, latest, hasUpdate, dev: isDevSource() })
|
|
10363
|
+
).catch((e) => log.fail("console", e, { phase: "update-check", via: "menu" }));
|
|
10364
|
+
break;
|
|
10365
|
+
}
|
|
10366
|
+
default:
|
|
10367
|
+
await sendDm(buildDmMenuCard({ webConsoleUrl: webConsoleUrl(), version: bridgeVersion() }));
|
|
10368
|
+
}
|
|
10369
|
+
} catch (err) {
|
|
10370
|
+
log.fail("console", err, { cmd: "menu-card", key: evt.eventKey });
|
|
10371
|
+
}
|
|
10214
10372
|
};
|
|
10215
10373
|
const reaper = setInterval(() => {
|
|
10216
10374
|
const now = Date.now();
|