lark-remote 0.5.7 → 0.5.9
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/CHANGELOG.md +35 -0
- package/dist/bridge/index.d.ts +47 -7
- package/dist/bridge/index.js +300 -129
- package/dist/bridge/queue-manager.d.ts +6 -0
- package/dist/bridge/queue-manager.js +61 -63
- package/dist/card/approval-render.js +2 -1
- package/dist/card/bash-card-session.d.ts +0 -1
- package/dist/card/bash-card-session.js +0 -8
- package/dist/card/bash-renderer.js +2 -1
- package/dist/card/card-budget.js +15 -19
- package/dist/card/card-session.d.ts +3 -13
- package/dist/card/card-session.js +4 -18
- package/dist/card/card-shared.d.ts +11 -0
- package/dist/card/card-shared.js +23 -13
- package/dist/card/run-card-session.d.ts +0 -1
- package/dist/card/run-card-session.js +0 -6
- package/dist/card/run-renderer.d.ts +11 -10
- package/dist/card/run-renderer.js +198 -35
- package/dist/card/run-state.d.ts +29 -2
- package/dist/card/run-state.js +23 -4
- package/dist/card/text-truncate.d.ts +3 -5
- package/dist/card/text-truncate.js +3 -5
- package/dist/card/tool-render.js +7 -21
- package/dist/common/tool-summary.d.ts +8 -0
- package/dist/common/tool-summary.js +38 -20
- package/dist/common/turn-failure.d.ts +13 -0
- package/dist/common/turn-failure.js +18 -0
- package/dist/index.js +13 -14
- package/dist/order/index.d.ts +2 -0
- package/dist/order/index.js +2 -0
- package/dist/router/card-helpers.js +23 -42
- package/dist/router/config/codex.js +2 -3
- package/dist/router/config/common/model-patch.d.ts +8 -0
- package/dist/router/config/common/model-patch.js +13 -0
- package/dist/router/config/common/render.js +30 -77
- package/dist/router/config/dsh.js +2 -1
- package/dist/router/config/kimi.js +3 -3
- package/dist/router/index.d.ts +0 -11
- package/dist/router/index.js +119 -360
- package/dist/router/order-exec-dispatch.js +2 -1
- package/dist/router/usage-format.d.ts +5 -0
- package/dist/router/usage-format.js +1 -1
- package/dist/runner/common/defaults.d.ts +2 -0
- package/dist/runner/common/defaults.js +3 -0
- package/dist/runner/common/jsonrpc/connection-manager.js +1 -1
- package/dist/runner/dsh/client.d.ts +15 -0
- package/dist/runner/dsh/client.js +28 -2
- package/dist/runner/dsh/goal-view.d.ts +36 -0
- package/dist/runner/dsh/goal-view.js +106 -0
- package/dist/runner/dsh/runner.js +51 -2
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/types.d.ts +59 -1
- package/dist/runner/types.js +9 -0
- package/dist/session/claude/session-index.d.ts +0 -4
- package/dist/session/claude/session-index.js +0 -8
- package/dist/session/dsh/sessions.js +58 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { parseCliArgs, resolveConfigDir, setConfigDir, printHelp, printVersion,
|
|
|
5
5
|
import { FeishuConnector } from './connector/index.js';
|
|
6
6
|
import { ClaudeRunner, CodexAppServerRunner, OpencodeAcpRunner, PiRpcRunner, KimiAcpRunner, DshRunner, } from './runner/index.js';
|
|
7
7
|
import { AgentRegistry } from './runner/registry.js';
|
|
8
|
+
import { AGENT_DISPLAY_NAMES, AGENT_KINDS } from './runner/types.js';
|
|
8
9
|
import { probeAllAgents } from './runner/probe.js';
|
|
9
10
|
import { warmCodexCatalogCache } from './config/codex-config.js';
|
|
10
11
|
import { SessionReaderRegistry, SessionStore } from './session/index.js';
|
|
@@ -316,13 +317,10 @@ function initializeRunner(config, configDir, cliArgs) {
|
|
|
316
317
|
getLogger().warn(`[dsh] startup probe failed: ${error.message}`);
|
|
317
318
|
});
|
|
318
319
|
}
|
|
319
|
-
//
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
agentRegistry.registerDisplayName('pi', 'Pi');
|
|
324
|
-
agentRegistry.registerDisplayName('kimi', 'Kimi');
|
|
325
|
-
agentRegistry.registerDisplayName('dsh', 'DSH');
|
|
320
|
+
// 显示名单源在 runner/types.ts 的 AGENT_DISPLAY_NAMES(启动注册与回退共用)
|
|
321
|
+
for (const kind of AGENT_KINDS) {
|
|
322
|
+
agentRegistry.registerDisplayName(kind, AGENT_DISPLAY_NAMES[kind]);
|
|
323
|
+
}
|
|
326
324
|
// 设置全局 registry,供 agentDisplayName 等全局函数使用
|
|
327
325
|
AgentRegistry.setGlobalInstance(agentRegistry);
|
|
328
326
|
// Probe agent CLI availability (fire-and-forget, populates cache for /config card).
|
|
@@ -534,16 +532,17 @@ function setupMessageHandlers(connector, router, bridge, sessionStore, workspace
|
|
|
534
532
|
const content = router.expandAliasMessage(msg.content);
|
|
535
533
|
if (isStopCommand(content)) {
|
|
536
534
|
void (async () => {
|
|
537
|
-
const
|
|
535
|
+
const interrupt = await bridge.interruptCurrentRunDetailed({
|
|
538
536
|
userId: msg.userId,
|
|
539
537
|
chatId: msg.chatId,
|
|
540
538
|
});
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
539
|
+
const ctx = { userId: msg.userId, chatId: msg.chatId, messageId: msg.messageId };
|
|
540
|
+
if (!interrupt.stopped) {
|
|
541
|
+
await bridge.sendResult({ text: '当前没有运行中的进程' }, ctx);
|
|
542
|
+
}
|
|
543
|
+
else if ((interrupt.stoppedCount ?? 1) > 1) {
|
|
544
|
+
// 并行 workspace 时 /stop 停全部,必须让用户看到数量。
|
|
545
|
+
await bridge.sendResult({ text: `✅ 已停止 ${interrupt.stoppedCount} 个运行中的任务` }, ctx);
|
|
547
546
|
}
|
|
548
547
|
})().catch((err) => logger.error('[control] /stop failed:', err));
|
|
549
548
|
return;
|
package/dist/order/index.d.ts
CHANGED
package/dist/order/index.js
CHANGED
|
@@ -2,6 +2,8 @@ import path from 'node:path';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { atomicWriteJson } from '../persistence/atomic-write.js';
|
|
4
4
|
import { loadJsonFile } from '../persistence/load-json-file.js';
|
|
5
|
+
/** 指令已被删除/不存在时的统一用户提示。 */
|
|
6
|
+
export const ORDER_NOT_FOUND_TEXT = '指令不存在或已被删除';
|
|
5
7
|
const MAX_TEXT_LENGTH = 200;
|
|
6
8
|
const MAX_ORDERS = 50;
|
|
7
9
|
/** 别名名称规则:`[A-Za-z_][A-Za-z0-9_]*`,≤20 字符,不能数字开头。 */
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* specific builders (e.g. `sessionEventPanel`) so `router/index.ts` can fold
|
|
7
7
|
* long session histories into collapsible panels without duplicating logic.
|
|
8
8
|
*/
|
|
9
|
-
import { agentDisplayName } from '../card/card-shared.js';
|
|
9
|
+
import { agentDisplayName, cardButton } from '../card/card-shared.js';
|
|
10
10
|
import { collapsibleMarkdownPanel, markdownDiv } from '../card/collapsible.js';
|
|
11
11
|
import { formatMonthDayClock } from '../card/time.js';
|
|
12
12
|
import { displayWidth, truncateMiddleToDisplayWidth } from '../common/text-width.js';
|
|
@@ -142,18 +142,7 @@ export function paginationBar(opts) {
|
|
|
142
142
|
width: 'auto',
|
|
143
143
|
vertical_align: 'center',
|
|
144
144
|
elements: [
|
|
145
|
-
{
|
|
146
|
-
tag: 'button',
|
|
147
|
-
text: { tag: 'plain_text', content: prevText },
|
|
148
|
-
type: 'default',
|
|
149
|
-
size: 'small',
|
|
150
|
-
behaviors: [
|
|
151
|
-
{
|
|
152
|
-
type: 'callback',
|
|
153
|
-
value: { cmd: opts.cmd, offset: opts.offset - opts.pageSize, ...opts.extra },
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
},
|
|
145
|
+
cardButton(prevText, { cmd: opts.cmd, offset: opts.offset - opts.pageSize, ...opts.extra }, { type: 'default', size: 'small' }),
|
|
157
146
|
],
|
|
158
147
|
});
|
|
159
148
|
}
|
|
@@ -185,18 +174,7 @@ export function paginationBar(opts) {
|
|
|
185
174
|
width: 'auto',
|
|
186
175
|
vertical_align: 'center',
|
|
187
176
|
elements: [
|
|
188
|
-
{
|
|
189
|
-
tag: 'button',
|
|
190
|
-
text: { tag: 'plain_text', content: nextText },
|
|
191
|
-
type: 'default',
|
|
192
|
-
size: 'small',
|
|
193
|
-
behaviors: [
|
|
194
|
-
{
|
|
195
|
-
type: 'callback',
|
|
196
|
-
value: { cmd: opts.cmd, offset: opts.offset + opts.pageSize, ...opts.extra },
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
},
|
|
177
|
+
cardButton(nextText, { cmd: opts.cmd, offset: opts.offset + opts.pageSize, ...opts.extra }, { type: 'default', size: 'small' }),
|
|
200
178
|
],
|
|
201
179
|
});
|
|
202
180
|
}
|
|
@@ -264,18 +242,7 @@ export function searchBar(opts) {
|
|
|
264
242
|
width: 'auto',
|
|
265
243
|
vertical_align: 'center',
|
|
266
244
|
elements: [
|
|
267
|
-
{
|
|
268
|
-
tag: 'button',
|
|
269
|
-
text: { tag: 'plain_text', content: '清除筛选' },
|
|
270
|
-
type: 'default',
|
|
271
|
-
size: 'small',
|
|
272
|
-
behaviors: [
|
|
273
|
-
{
|
|
274
|
-
type: 'callback',
|
|
275
|
-
value: { cmd: opts.cmd, clearQuery: true, ...opts.extra },
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
|
-
},
|
|
245
|
+
cardButton('清除筛选', { cmd: opts.cmd, clearQuery: true, ...opts.extra }, { type: 'default', size: 'small' }),
|
|
279
246
|
],
|
|
280
247
|
});
|
|
281
248
|
}
|
|
@@ -339,15 +306,29 @@ export function buildSessionHistoryCard(state, opts) {
|
|
|
339
306
|
const { displayTitle, aiTitle, recap, events, usage } = state;
|
|
340
307
|
let header = opts.headerText;
|
|
341
308
|
const sections = [];
|
|
309
|
+
const preview = (text) => (text.length > 200 ? text.slice(0, 197) + '...' : text);
|
|
342
310
|
// Reader 层不再截断 displayTitle/summary;统一在消费侧这里截到 200 字符。
|
|
311
|
+
//
|
|
312
|
+
// `aiTitle` 与 `displayTitle` 是两种东西:前者是 agent 自己起的会话标题
|
|
313
|
+
// (DSH 的 projections.title / claude 的 ai-title),后者是最近一条用户输入。
|
|
314
|
+
// claude 的 displayTitle 本身就取 aiTitle,两者相等 → 保持旧的「AI 标题」
|
|
315
|
+
// 单段文案;DSH 两者都有(标题 + 末轮 prompt)→ 各占一段,别把用户那句话
|
|
316
|
+
// 挂在「AI 标题」下面(2026-10-21)。
|
|
343
317
|
if (displayTitle) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
318
|
+
if (aiTitle && aiTitle !== displayTitle) {
|
|
319
|
+
sections.push(`🏷️ **标题**\n${preview(aiTitle)}`);
|
|
320
|
+
sections.push(`✏️ **最近输入**\n${preview(displayTitle)}`);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
const label = aiTitle ? 'AI 标题' : '最近输入';
|
|
324
|
+
sections.push(`🏷️ **${label}**\n${preview(displayTitle)}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
else if (aiTitle) {
|
|
328
|
+
sections.push(`🏷️ **AI 标题**\n${preview(aiTitle)}`);
|
|
347
329
|
}
|
|
348
330
|
if (recap) {
|
|
349
|
-
|
|
350
|
-
sections.push(`📝 **Recap**\n${recapPreview}`);
|
|
331
|
+
sections.push(`📝 **Recap**\n${preview(recap)}`);
|
|
351
332
|
}
|
|
352
333
|
if (sections.length > 0) {
|
|
353
334
|
header += '\n\n' + sections.join('\n\n──\n\n');
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { loadCodexConfig, getReasoningEffortOptions, getDefaultReasoningEffort, } from '../../config/codex-config.js';
|
|
5
5
|
import { DEFAULT_TURN_IDLE_TIMEOUT_MINUTES } from '../../config/index.js';
|
|
6
|
-
import { resetModelPatch } from './common/model-patch.js';
|
|
6
|
+
import { pickMiddleValue, resetModelPatch } from './common/model-patch.js';
|
|
7
7
|
export class CodexConfigBuilder {
|
|
8
8
|
buildFields(displayConfig) {
|
|
9
9
|
const fields = [];
|
|
@@ -116,8 +116,7 @@ export class CodexConfigBuilder {
|
|
|
116
116
|
const isCurrentEffortValid = currentReasoningEffort && newModelSupportedEfforts.includes(currentReasoningEffort);
|
|
117
117
|
if (isCurrentEffortValid)
|
|
118
118
|
return null;
|
|
119
|
-
const
|
|
120
|
-
const newEffort = middle ?? getDefaultReasoningEffort(newModel);
|
|
119
|
+
const newEffort = pickMiddleValue(newModelSupportedEfforts) ?? getDefaultReasoningEffort(newModel);
|
|
121
120
|
return { key: 'agents.codex.reasoningEffort', value: newEffort };
|
|
122
121
|
}
|
|
123
122
|
}
|
|
@@ -19,3 +19,11 @@ export declare function resetModelPatch(modelKey: string, currentModel: string |
|
|
|
19
19
|
key: string;
|
|
20
20
|
value: unknown;
|
|
21
21
|
} | null;
|
|
22
|
+
/**
|
|
23
|
+
* 取档位列表的中位值(切换模型后当前档位不受支持时的兜底)。
|
|
24
|
+
*
|
|
25
|
+
* 偶数长度的中位口径由调用方显式选择,避免各 builder 各写一套公式后漂移:
|
|
26
|
+
* - `lower`:`(len-1)/2`,kimi/codex 既有口径;
|
|
27
|
+
* - `upper`:`len/2`,DSH 需要偏高的一档(off/low → low)。
|
|
28
|
+
*/
|
|
29
|
+
export declare function pickMiddleValue<T>(values: readonly T[], bias?: 'lower' | 'upper'): T | undefined;
|
|
@@ -22,4 +22,17 @@ export function resetModelPatch(modelKey, currentModel, newModelOptions) {
|
|
|
22
22
|
}
|
|
23
23
|
return null;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* 取档位列表的中位值(切换模型后当前档位不受支持时的兜底)。
|
|
27
|
+
*
|
|
28
|
+
* 偶数长度的中位口径由调用方显式选择,避免各 builder 各写一套公式后漂移:
|
|
29
|
+
* - `lower`:`(len-1)/2`,kimi/codex 既有口径;
|
|
30
|
+
* - `upper`:`len/2`,DSH 需要偏高的一档(off/low → low)。
|
|
31
|
+
*/
|
|
32
|
+
export function pickMiddleValue(values, bias = 'lower') {
|
|
33
|
+
if (values.length === 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
const index = bias === 'upper' ? Math.floor(values.length / 2) : Math.floor((values.length - 1) / 2);
|
|
36
|
+
return values[index];
|
|
37
|
+
}
|
|
25
38
|
//# sourceMappingURL=model-patch.js.map
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Used by all agent config builders and the shared tabs (idle, logging).
|
|
6
6
|
*/
|
|
7
7
|
import { getConfigValue } from '../../../config/index.js';
|
|
8
|
+
import { cardButton } from '../../../card/card-shared.js';
|
|
8
9
|
/** Build CardKit 2.0 elements for a list of config fields. */
|
|
9
10
|
function buildFieldElements(fields, displayConfig) {
|
|
10
11
|
const elements = [];
|
|
@@ -29,8 +30,8 @@ function buildFieldElements(fields, displayConfig) {
|
|
|
29
30
|
}
|
|
30
31
|
return elements;
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
/** 配置项统一行:左 label(2 份宽)+ 右控件(3 份宽)。 */
|
|
34
|
+
function fieldRow(label, control) {
|
|
34
35
|
return {
|
|
35
36
|
tag: 'column_set',
|
|
36
37
|
flex_mode: 'none',
|
|
@@ -40,25 +41,24 @@ function buildBooleanElement(field, isOn) {
|
|
|
40
41
|
width: 'weighted',
|
|
41
42
|
weight: 2,
|
|
42
43
|
vertical_align: 'center',
|
|
43
|
-
elements: [{ tag: 'div', text: { tag: 'lark_md', content:
|
|
44
|
+
elements: [{ tag: 'div', text: { tag: 'lark_md', content: label } }],
|
|
44
45
|
},
|
|
45
46
|
{
|
|
46
47
|
tag: 'column',
|
|
47
48
|
width: 'weighted',
|
|
48
49
|
weight: 3,
|
|
49
50
|
vertical_align: 'center',
|
|
50
|
-
elements: [
|
|
51
|
-
{
|
|
52
|
-
tag: 'button',
|
|
53
|
-
text: { tag: 'plain_text', content: displayVal },
|
|
54
|
-
type: isOn ? 'primary' : 'default',
|
|
55
|
-
behaviors: [{ type: 'callback', value: { cmd: 'config.toggle', key: field.key } }],
|
|
56
|
-
},
|
|
57
|
-
],
|
|
51
|
+
elements: [control],
|
|
58
52
|
},
|
|
59
53
|
],
|
|
60
54
|
};
|
|
61
55
|
}
|
|
56
|
+
function buildBooleanElement(field, isOn) {
|
|
57
|
+
const displayVal = isOn ? '✅ 已开启' : '⚪ 已关闭';
|
|
58
|
+
return fieldRow(field.label, cardButton(displayVal, { cmd: 'config.toggle', key: field.key }, {
|
|
59
|
+
type: isOn ? 'primary' : 'default',
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
62
|
function buildSelectElement(field, currentValue) {
|
|
63
63
|
// 优先使用 field.currentValue(卡片显示用覆盖值),否则使用 config 中的值
|
|
64
64
|
const selectedValue = field.currentValue != null
|
|
@@ -66,38 +66,17 @@ function buildSelectElement(field, currentValue) {
|
|
|
66
66
|
: currentValue == null
|
|
67
67
|
? undefined
|
|
68
68
|
: String(currentValue);
|
|
69
|
-
return {
|
|
70
|
-
tag: '
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
{
|
|
81
|
-
tag: 'column',
|
|
82
|
-
width: 'weighted',
|
|
83
|
-
weight: 3,
|
|
84
|
-
vertical_align: 'center',
|
|
85
|
-
elements: [
|
|
86
|
-
{
|
|
87
|
-
tag: 'select_static',
|
|
88
|
-
placeholder: { tag: 'plain_text', content: '请选择' },
|
|
89
|
-
options: field.options.map((opt) => {
|
|
90
|
-
const text = typeof opt === 'string' ? opt : opt.text;
|
|
91
|
-
const value = typeof opt === 'string' ? opt : opt.value;
|
|
92
|
-
return { text: { tag: 'plain_text', content: text }, value };
|
|
93
|
-
}),
|
|
94
|
-
initial_option: selectedValue,
|
|
95
|
-
behaviors: [{ type: 'callback', value: { cmd: 'config.set', key: field.key } }],
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
};
|
|
69
|
+
return fieldRow(field.label, {
|
|
70
|
+
tag: 'select_static',
|
|
71
|
+
placeholder: { tag: 'plain_text', content: '请选择' },
|
|
72
|
+
options: field.options.map((opt) => {
|
|
73
|
+
const text = typeof opt === 'string' ? opt : opt.text;
|
|
74
|
+
const value = typeof opt === 'string' ? opt : opt.value;
|
|
75
|
+
return { text: { tag: 'plain_text', content: text }, value };
|
|
76
|
+
}),
|
|
77
|
+
initial_option: selectedValue,
|
|
78
|
+
behaviors: [{ type: 'callback', value: { cmd: 'config.set', key: field.key } }],
|
|
79
|
+
});
|
|
101
80
|
}
|
|
102
81
|
function buildInputElement(field, currentValue) {
|
|
103
82
|
// 优先使用 field.currentValue(允许覆盖 displayConfig 中的值)
|
|
@@ -106,34 +85,13 @@ function buildInputElement(field, currentValue) {
|
|
|
106
85
|
: currentValue == null
|
|
107
86
|
? ''
|
|
108
87
|
: String(currentValue);
|
|
109
|
-
return {
|
|
110
|
-
tag: '
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
weight: 2,
|
|
117
|
-
vertical_align: 'center',
|
|
118
|
-
elements: [{ tag: 'div', text: { tag: 'lark_md', content: field.label } }],
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
tag: 'column',
|
|
122
|
-
width: 'weighted',
|
|
123
|
-
weight: 3,
|
|
124
|
-
vertical_align: 'center',
|
|
125
|
-
elements: [
|
|
126
|
-
{
|
|
127
|
-
tag: 'input',
|
|
128
|
-
name: field.key,
|
|
129
|
-
placeholder: { tag: 'plain_text', content: '请输入值' },
|
|
130
|
-
default_value: currentStr,
|
|
131
|
-
behaviors: [{ type: 'callback', value: { cmd: 'config.input', key: field.key } }],
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
};
|
|
88
|
+
return fieldRow(field.label, {
|
|
89
|
+
tag: 'input',
|
|
90
|
+
name: field.key,
|
|
91
|
+
placeholder: { tag: 'plain_text', content: '请输入值' },
|
|
92
|
+
default_value: currentStr,
|
|
93
|
+
behaviors: [{ type: 'callback', value: { cmd: 'config.input', key: field.key } }],
|
|
94
|
+
});
|
|
137
95
|
}
|
|
138
96
|
/** Build the full CardKit 2.0 card from tabs. */
|
|
139
97
|
export function buildConfigCardFromTabs(tabs, displayConfig) {
|
|
@@ -147,12 +105,7 @@ export function buildConfigCardFromTabs(tabs, displayConfig) {
|
|
|
147
105
|
elements.push({ tag: 'hr' });
|
|
148
106
|
}
|
|
149
107
|
// 底部保存按钮
|
|
150
|
-
elements.push({
|
|
151
|
-
tag: 'button',
|
|
152
|
-
text: { tag: 'plain_text', content: '💾 保存所有修改' },
|
|
153
|
-
type: 'primary',
|
|
154
|
-
behaviors: [{ type: 'callback', value: { cmd: 'config.save' } }],
|
|
155
|
-
});
|
|
108
|
+
elements.push(cardButton('💾 保存所有修改', { cmd: 'config.save' }, { type: 'primary' }));
|
|
156
109
|
return {
|
|
157
110
|
schema: '2.0',
|
|
158
111
|
config: { wide_screen_mode: true, update_multi: true },
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* 与 runner 的兼容规则一致。provider 清单不硬编码,来自服务端目录。
|
|
17
17
|
*/
|
|
18
18
|
import { DEFAULT_DSH_HOST } from '../../config/index.js';
|
|
19
|
+
import { pickMiddleValue } from './common/model-patch.js';
|
|
19
20
|
import { DshClient } from '../../runner/dsh/client.js';
|
|
20
21
|
import { getLogger } from '../../logger/index.js';
|
|
21
22
|
/** 旧配置没有 provider 时的生效值(与 DshRunner 的兼容规则一致)。 */
|
|
@@ -361,7 +362,7 @@ export class DshConfigBuilder {
|
|
|
361
362
|
if (currentEffort && supported.includes(currentEffort))
|
|
362
363
|
return null;
|
|
363
364
|
// 新模型目录中位档位;偶数长度取偏高位(off/low → low,符合 DSH 默认 high 语义)
|
|
364
|
-
const middle =
|
|
365
|
+
const middle = pickMiddleValue(supported, 'upper');
|
|
365
366
|
return { key: 'agents.dsh.reasoningEffort', value: middle };
|
|
366
367
|
}
|
|
367
368
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { loadKimiConfig, KIMI_THINKING_EFFORTS, FALLBACK_EFFORTS, } from '../../config/kimi-config.js';
|
|
8
8
|
import { DEFAULT_TURN_IDLE_TIMEOUT_MINUTES } from '../../config/index.js';
|
|
9
|
+
import { pickMiddleValue } from './common/model-patch.js';
|
|
9
10
|
const PERMISSION_MODE_OPTIONS = [
|
|
10
11
|
// kimi 0.40.0(2026-09-02)起官方语义:manual=始终询问 / yolo=必要时询问 / auto=完全自动
|
|
11
12
|
{ text: 'manual(始终询问)', value: 'manual' },
|
|
@@ -79,12 +80,11 @@ export class KimiConfigBuilder {
|
|
|
79
80
|
const supported = kimiCfg.modelEfforts[newModel] ?? [...FALLBACK_EFFORTS];
|
|
80
81
|
if (currentEffort && supported.includes(currentEffort))
|
|
81
82
|
return null;
|
|
82
|
-
|
|
83
|
-
let newEffort = middle;
|
|
83
|
+
let newEffort = pickMiddleValue(supported);
|
|
84
84
|
if (!newEffort)
|
|
85
85
|
newEffort = kimiCfg.modelDefaultEfforts?.[newModel];
|
|
86
86
|
if (!newEffort)
|
|
87
|
-
newEffort =
|
|
87
|
+
newEffort = pickMiddleValue(FALLBACK_EFFORTS);
|
|
88
88
|
return { key: 'agents.kimi.thinkingEffort', value: newEffort };
|
|
89
89
|
}
|
|
90
90
|
}
|
package/dist/router/index.d.ts
CHANGED
|
@@ -641,17 +641,6 @@ export declare class CommandRouter {
|
|
|
641
641
|
* 不敏感。省略/空 = 无筛选。
|
|
642
642
|
*/
|
|
643
643
|
cmdWs(args: string[], ctx: CommandContext, offset?: number, q?: string): CommandResult;
|
|
644
|
-
/**
|
|
645
|
-
* degraded card when a session's export is non-empty but unparseable
|
|
646
|
-
* (truncated by opencode's pipe cap on huge sessions, or otherwise corrupt).
|
|
647
|
-
* The session exists, so reuse listSessions metadata (title) instead of the
|
|
648
|
-
* misleading "未找到". Reuses the same card-builder helpers (markdownDiv) as
|
|
649
|
-
* the normal resume card; enforceCardBudget still applies at send time.
|
|
650
|
-
*/
|
|
651
|
-
/**
|
|
652
|
-
* /resume 核心实现(public:handleResumePage / handle / resume.use 共用,
|
|
653
|
-
* 也是测试的直接 seam,避免测试用 @ts-expect-error 摸私有方法)。
|
|
654
|
-
*/
|
|
655
644
|
/**
|
|
656
645
|
* DSH /resume preset 一致性校验:返回 mismatch 详情,或 undefined(一致/不可判定)。
|
|
657
646
|
*
|