chatccc 0.2.95 → 0.2.96
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/package.json +1 -1
- package/src/cards.ts +60 -0
- package/src/config.ts +5 -0
- package/src/index.ts +1 -1
- package/src/orchestrator.ts +116 -6
- package/src/session.ts +37 -11
package/package.json
CHANGED
package/src/cards.ts
CHANGED
|
@@ -407,3 +407,63 @@ export function buildStatusCard(statusText: string, template = "blue"): string {
|
|
|
407
407
|
],
|
|
408
408
|
});
|
|
409
409
|
}
|
|
410
|
+
|
|
411
|
+
export interface ModelSwitchOption {
|
|
412
|
+
label: string;
|
|
413
|
+
model: string;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/** 模型切换卡片(/model 命令,飞书专用,含切换按钮) */
|
|
417
|
+
export function buildModelCard(
|
|
418
|
+
currentModel: string,
|
|
419
|
+
available: ModelSwitchOption[],
|
|
420
|
+
): string {
|
|
421
|
+
const currentLine = currentModel
|
|
422
|
+
? `**当前模型:** \`${currentModel}\``
|
|
423
|
+
: "**当前模型:** 未指定";
|
|
424
|
+
const hasPro = available.some(o => o.label === "pro");
|
|
425
|
+
const hasFlash = available.some(o => o.label === "flash");
|
|
426
|
+
|
|
427
|
+
const lines: string[] = [currentLine];
|
|
428
|
+
if (available.length > 0) {
|
|
429
|
+
lines.push("", "**可切换模型:**");
|
|
430
|
+
for (const opt of available) {
|
|
431
|
+
lines.push(`- ${opt.label}: \`${opt.model}\``);
|
|
432
|
+
}
|
|
433
|
+
} else {
|
|
434
|
+
lines.push("", "没有可切换的模型。");
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const buttons: { text: string; value: string; type?: "primary" | "default" | "danger" }[] = [];
|
|
438
|
+
if (hasPro) {
|
|
439
|
+
buttons.push({
|
|
440
|
+
text: "/model pro",
|
|
441
|
+
value: JSON.stringify({ action: "model_pro" }),
|
|
442
|
+
type: "primary",
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
if (hasFlash) {
|
|
446
|
+
buttons.push({
|
|
447
|
+
text: "/model flash",
|
|
448
|
+
value: JSON.stringify({ action: "model_flash" }),
|
|
449
|
+
type: "primary",
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
if (!hasPro && !hasFlash) {
|
|
453
|
+
buttons.push({
|
|
454
|
+
text: "/model clear",
|
|
455
|
+
value: JSON.stringify({ action: "model_clear" }),
|
|
456
|
+
type: "default",
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return JSON.stringify({
|
|
461
|
+
config: { wide_screen_mode: true },
|
|
462
|
+
header: { template: "blue", title: { content: "模型切换", tag: "plain_text" } },
|
|
463
|
+
elements: [
|
|
464
|
+
{ tag: "div", text: { tag: "lark_md", content: lines.join("\n") } },
|
|
465
|
+
{ tag: "hr" },
|
|
466
|
+
buildButtons(buttons),
|
|
467
|
+
],
|
|
468
|
+
});
|
|
469
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -511,6 +511,11 @@ export let CLAUDE_API_KEY = config.claude.apiKey;
|
|
|
511
511
|
/** Anthropic 兼容网关的 base URL(仅经 SDK 子进程 env 传递,从不写入主进程 process.env) */
|
|
512
512
|
export let CLAUDE_BASE_URL = config.claude.baseUrl;
|
|
513
513
|
|
|
514
|
+
/** 返回当前生效的 Claude 模型(per-session 覆盖由 session.ts 管理,此处仅返回全局配置) */
|
|
515
|
+
export function getEffectiveClaudeModel(): string {
|
|
516
|
+
return CLAUDE_MODEL;
|
|
517
|
+
}
|
|
518
|
+
|
|
514
519
|
// ---------------------------------------------------------------------------
|
|
515
520
|
// /git 超时配置(实际值来自 config.json,纯函数与常量见 ./config-utils.ts)
|
|
516
521
|
// ---------------------------------------------------------------------------
|
package/src/index.ts
CHANGED
|
@@ -285,7 +285,7 @@ function parseCardAction(data: unknown): CardActionResult | null {
|
|
|
285
285
|
}
|
|
286
286
|
if (!cmd) return null;
|
|
287
287
|
|
|
288
|
-
const CMD_MAP: Record<string, string> = { stop: "/stop", cancel: "/cancel", new: "/new", "new claude": "/new claude", "new cursor": "/new cursor", "new codex": "/new codex", restart: "/restart", status: "/status", cd: "/cd", sessions: "/sessions", newh: "/newh" };
|
|
288
|
+
const CMD_MAP: Record<string, string> = { stop: "/stop", cancel: "/cancel", new: "/new", "new claude": "/new claude", "new cursor": "/new cursor", "new codex": "/new codex", restart: "/restart", status: "/status", cd: "/cd", sessions: "/sessions", newh: "/newh", model_pro: "/model pro", model_flash: "/model flash", model_clear: "/model clear" };
|
|
289
289
|
let text = CMD_MAP[cmd] ?? "";
|
|
290
290
|
if (cmd === "cd" && typeof action.value === "object" && action.value !== null) {
|
|
291
291
|
const path = (action.value as Record<string, string>).path;
|
package/src/orchestrator.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { makeTraceId, logTrace } from "./trace.ts";
|
|
|
13
13
|
import {
|
|
14
14
|
CLAUDE_EFFORT,
|
|
15
15
|
CLAUDE_MODEL,
|
|
16
|
+
CLAUDE_SUBAGENT_MODEL,
|
|
16
17
|
GIT_TIMEOUT_MS,
|
|
17
18
|
PROJECT_ROOT,
|
|
18
19
|
anthropicConfigDisplay,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
} from "./config.ts";
|
|
29
30
|
import {
|
|
30
31
|
buildHelpCard,
|
|
32
|
+
buildModelCard,
|
|
31
33
|
buildStatusCard,
|
|
32
34
|
buildCdContent,
|
|
33
35
|
buildCdCard,
|
|
@@ -41,12 +43,14 @@ import {
|
|
|
41
43
|
runGitCommand,
|
|
42
44
|
} from "./git-command.ts";
|
|
43
45
|
import {
|
|
46
|
+
clearSessionModelOverride,
|
|
44
47
|
getSessionStatus,
|
|
45
48
|
getAllSessionsStatus,
|
|
46
49
|
initClaudeSession,
|
|
47
50
|
lastMsgTimestamps,
|
|
48
51
|
resumeAndPrompt,
|
|
49
52
|
sessionInfoMap,
|
|
53
|
+
setSessionModelOverride,
|
|
50
54
|
switchChatBinding,
|
|
51
55
|
recordSessionRegistry,
|
|
52
56
|
getAdapterForTool,
|
|
@@ -141,7 +145,7 @@ export async function handleCommand(
|
|
|
141
145
|
chatInfo.description,
|
|
142
146
|
);
|
|
143
147
|
if (sessionInfoResult) {
|
|
144
|
-
const adapter = getAdapterForTool(sessionInfoResult.tool);
|
|
148
|
+
const adapter = getAdapterForTool(sessionInfoResult.tool, sessionInfoResult.sessionId);
|
|
145
149
|
const info = await adapter.getSessionInfo(sessionInfoResult.sessionId);
|
|
146
150
|
sessionCwd = info?.cwd;
|
|
147
151
|
}
|
|
@@ -243,6 +247,54 @@ export async function handleCommand(
|
|
|
243
247
|
return;
|
|
244
248
|
}
|
|
245
249
|
|
|
250
|
+
if (textLower === "/model") {
|
|
251
|
+
logTrace(tid, "BRANCH", { cmd: "/model" });
|
|
252
|
+
|
|
253
|
+
const isDeepSeek = CLAUDE_MODEL.toLowerCase().includes("deepseek")
|
|
254
|
+
|| CLAUDE_SUBAGENT_MODEL.toLowerCase().includes("deepseek");
|
|
255
|
+
if (!isDeepSeek) {
|
|
256
|
+
const msg = "当前配置不支持模型切换(模型名中未找到 DeepSeek 相关内容)。";
|
|
257
|
+
await (platform.kind === "wechat"
|
|
258
|
+
? platform.sendText(chatId, msg)
|
|
259
|
+
: platform.sendCard(chatId, "模型切换", msg, "red")
|
|
260
|
+
).catch(() => {});
|
|
261
|
+
logTrace(tid, "DONE", { outcome: "model_unsupported" });
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const findModel = (keyword: string): string | null => {
|
|
266
|
+
for (const name of [CLAUDE_MODEL.trim(), CLAUDE_SUBAGENT_MODEL.trim()]) {
|
|
267
|
+
if (!name) continue;
|
|
268
|
+
const nl = name.toLowerCase();
|
|
269
|
+
if (nl.includes("deepseek") && nl.includes(keyword)) return name;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const available: { label: string; model: string }[] = [];
|
|
275
|
+
const pm = findModel("pro");
|
|
276
|
+
if (pm) available.push({ label: "pro", model: pm });
|
|
277
|
+
const fm = findModel("flash");
|
|
278
|
+
if (fm) available.push({ label: "flash", model: fm });
|
|
279
|
+
|
|
280
|
+
if (platform.kind === "wechat") {
|
|
281
|
+
const lines = [CLAUDE_MODEL ? `当前模型: ${CLAUDE_MODEL}` : "当前模型: 未指定"];
|
|
282
|
+
if (available.length > 0) {
|
|
283
|
+
lines.push("", "可切换模型:");
|
|
284
|
+
for (const o of available) lines.push(` ${o.label}: ${o.model}`);
|
|
285
|
+
lines.push("", "输入 /model pro 或 /model flash 切换模型");
|
|
286
|
+
} else {
|
|
287
|
+
lines.push("", "没有可切换的模型。请在 config.json 的 claude.model 或 claude.subagentModel 中配置含 pro/flash 与 deepseek 关键字的模型名。");
|
|
288
|
+
}
|
|
289
|
+
await platform.sendText(chatId, lines.join("\n")).catch(() => {});
|
|
290
|
+
} else {
|
|
291
|
+
const card = buildModelCard(CLAUDE_MODEL, available);
|
|
292
|
+
await platform.sendRawCard(chatId, card);
|
|
293
|
+
}
|
|
294
|
+
logTrace(tid, "DONE", { outcome: "model_query" });
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
246
298
|
if (textLower === "/new" || textLower.startsWith("/new ")) {
|
|
247
299
|
const toolArg = text.slice(5).trim().toLowerCase();
|
|
248
300
|
const tool = toolArg || resolveDefaultAgentTool();
|
|
@@ -510,7 +562,7 @@ export async function handleCommand(
|
|
|
510
562
|
) {
|
|
511
563
|
const MAX_PREFIX = 10;
|
|
512
564
|
const prefix = text.slice(0, MAX_PREFIX);
|
|
513
|
-
const adapter = getAdapterForTool(descriptionTool);
|
|
565
|
+
const adapter = getAdapterForTool(descriptionTool, sessionId);
|
|
514
566
|
const info = await adapter
|
|
515
567
|
.getSessionInfo(sessionId)
|
|
516
568
|
.catch(() => undefined);
|
|
@@ -553,7 +605,7 @@ export async function handleCommand(
|
|
|
553
605
|
) {
|
|
554
606
|
const MAX_PREFIX = 10;
|
|
555
607
|
const prefix = text.slice(0, MAX_PREFIX);
|
|
556
|
-
const adapter = getAdapterForTool(descriptionTool
|
|
608
|
+
const adapter = getAdapterForTool(descriptionTool!, sessionId);
|
|
557
609
|
const info = await adapter
|
|
558
610
|
.getSessionInfo(sessionId)
|
|
559
611
|
.catch(() => undefined);
|
|
@@ -674,7 +726,7 @@ export async function handleCommand(
|
|
|
674
726
|
|
|
675
727
|
if (textLower === "/newh") {
|
|
676
728
|
logTrace(tid, "BRANCH", { cmd: "/newh" });
|
|
677
|
-
const adapter = getAdapterForTool(descriptionTool);
|
|
729
|
+
const adapter = getAdapterForTool(descriptionTool, sessionId);
|
|
678
730
|
let cwd: string;
|
|
679
731
|
try {
|
|
680
732
|
const info = await adapter.getSessionInfo(sessionId);
|
|
@@ -849,7 +901,7 @@ export async function handleCommand(
|
|
|
849
901
|
return;
|
|
850
902
|
}
|
|
851
903
|
|
|
852
|
-
const targetAdapter = getAdapterForTool(target.tool);
|
|
904
|
+
const targetAdapter = getAdapterForTool(target.tool, target.sessionId);
|
|
853
905
|
let cwd2: string;
|
|
854
906
|
try {
|
|
855
907
|
const targetInfo = await targetAdapter.getSessionInfo(
|
|
@@ -920,6 +972,64 @@ export async function handleCommand(
|
|
|
920
972
|
return;
|
|
921
973
|
}
|
|
922
974
|
|
|
975
|
+
// /model pro、/model flash、/model clear(仅对当前 session 生效)
|
|
976
|
+
if (textLower === "/model pro" || textLower === "/model flash" || textLower === "/model clear") {
|
|
977
|
+
const modelArg = textLower === "/model clear" ? "clear" : textLower.slice(7).trim();
|
|
978
|
+
logTrace(tid, "BRANCH", { cmd: "/model", arg: modelArg, sessionId });
|
|
979
|
+
|
|
980
|
+
// 仅 Claude Code 支持模型切换
|
|
981
|
+
if (descriptionTool !== "claude") {
|
|
982
|
+
const msg = "模型切换仅支持 Claude Code 会话。";
|
|
983
|
+
await (platform.kind === "wechat"
|
|
984
|
+
? platform.sendText(chatId, msg)
|
|
985
|
+
: platform.sendCard(chatId, "模型切换", msg, "red")
|
|
986
|
+
).catch(() => {});
|
|
987
|
+
logTrace(tid, "DONE", { outcome: "model_wrong_tool", tool: descriptionTool });
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
const findModel = (keyword: string): string | null => {
|
|
992
|
+
for (const name of [CLAUDE_MODEL.trim(), CLAUDE_SUBAGENT_MODEL.trim()]) {
|
|
993
|
+
if (!name) continue;
|
|
994
|
+
const nl = name.toLowerCase();
|
|
995
|
+
if (nl.includes("deepseek") && nl.includes(keyword)) return name;
|
|
996
|
+
}
|
|
997
|
+
return null;
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
if (modelArg === "clear") {
|
|
1001
|
+
clearSessionModelOverride(sessionId);
|
|
1002
|
+
const restored = CLAUDE_MODEL.trim() || "(未指定)";
|
|
1003
|
+
const msg = `已清除当前会话的模型覆盖,恢复使用: \`${restored}\``;
|
|
1004
|
+
await (platform.kind === "wechat"
|
|
1005
|
+
? platform.sendText(chatId, msg)
|
|
1006
|
+
: platform.sendCard(chatId, "模型切换", msg, "green")
|
|
1007
|
+
).catch(() => {});
|
|
1008
|
+
logTrace(tid, "DONE", { outcome: "model_cleared", sessionId });
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
const target = findModel(modelArg);
|
|
1013
|
+
if (!target) {
|
|
1014
|
+
const msg = `未找到同时含 "${modelArg}" 和 "deepseek" 关键字的模型。请在 config.json 的 claude.model 或 claude.subagentModel 中配置。`;
|
|
1015
|
+
await (platform.kind === "wechat"
|
|
1016
|
+
? platform.sendText(chatId, msg)
|
|
1017
|
+
: platform.sendCard(chatId, "模型切换", msg, "red")
|
|
1018
|
+
).catch(() => {});
|
|
1019
|
+
logTrace(tid, "DONE", { outcome: "model_not_found", arg: modelArg });
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
setSessionModelOverride(sessionId, target);
|
|
1024
|
+
const msg = `已切换当前会话模型为 ${modelArg}: \`${target}\``;
|
|
1025
|
+
await (platform.kind === "wechat"
|
|
1026
|
+
? platform.sendText(chatId, msg)
|
|
1027
|
+
: platform.sendCard(chatId, "模型切换", msg, "green")
|
|
1028
|
+
).catch(() => {});
|
|
1029
|
+
logTrace(tid, "DONE", { outcome: "model_switched", arg: modelArg, target, sessionId });
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
923
1033
|
// /git <args>:在「当前会话工作目录」执行 git 命令
|
|
924
1034
|
if (textLower.startsWith("/git ") || textLower === "/git") {
|
|
925
1035
|
const args = text === "/git" ? "" : text.slice(5).trim();
|
|
@@ -935,7 +1045,7 @@ export async function handleCommand(
|
|
|
935
1045
|
return;
|
|
936
1046
|
}
|
|
937
1047
|
|
|
938
|
-
const adapter = getAdapterForTool(descriptionTool);
|
|
1048
|
+
const adapter = getAdapterForTool(descriptionTool, sessionId);
|
|
939
1049
|
let cwd: string | undefined;
|
|
940
1050
|
try {
|
|
941
1051
|
const info = await adapter.getSessionInfo(sessionId);
|
package/src/session.ts
CHANGED
|
@@ -307,13 +307,39 @@ export function resetState(): void {
|
|
|
307
307
|
// 是 onReady/onReconnected 取代 resetState 的正确入口。
|
|
308
308
|
|
|
309
309
|
// ---------------------------------------------------------------------------
|
|
310
|
-
// Adapter: 按 tool 创建并缓存
|
|
310
|
+
// Adapter: 按 tool + effectiveModel 创建并缓存
|
|
311
311
|
// ---------------------------------------------------------------------------
|
|
312
312
|
|
|
313
313
|
const adapterCache = new Map<string, ToolAdapter>();
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
// Per-session 模型覆盖(/model 命令设置,不持久化)
|
|
316
|
+
const sessionModelOverrides = new Map<string, string>();
|
|
317
|
+
|
|
318
|
+
/** 返回 session 的生效模型:优先 per-session 覆盖,其次全局配置 */
|
|
319
|
+
function getModelForSession(sessionId?: string): string {
|
|
320
|
+
if (sessionId) {
|
|
321
|
+
const override = sessionModelOverrides.get(sessionId);
|
|
322
|
+
if (override) return override;
|
|
323
|
+
}
|
|
324
|
+
return CLAUDE_MODEL;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** 为指定 session 设置模型覆盖(/model pro、/model flash) */
|
|
328
|
+
export function setSessionModelOverride(sessionId: string, model: string): void {
|
|
329
|
+
sessionModelOverrides.set(sessionId, model);
|
|
330
|
+
adapterCache.clear();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** 清除指定 session 的模型覆盖(/model clear) */
|
|
334
|
+
export function clearSessionModelOverride(sessionId: string): void {
|
|
335
|
+
sessionModelOverrides.delete(sessionId);
|
|
336
|
+
adapterCache.clear();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function getAdapterForTool(tool: string, sessionId?: string): ToolAdapter {
|
|
340
|
+
const effectiveModel = tool === "claude" ? getModelForSession(sessionId) : "";
|
|
341
|
+
const cacheKey = tool === "claude" ? `${tool}:${effectiveModel}` : tool;
|
|
342
|
+
const cached = adapterCache.get(cacheKey);
|
|
317
343
|
if (cached) return cached;
|
|
318
344
|
|
|
319
345
|
let adapter: ToolAdapter;
|
|
@@ -323,7 +349,7 @@ export function getAdapterForTool(tool: string): ToolAdapter {
|
|
|
323
349
|
adapter = createCodexAdapter();
|
|
324
350
|
} else {
|
|
325
351
|
adapter = createClaudeAdapter({
|
|
326
|
-
model:
|
|
352
|
+
model: effectiveModel,
|
|
327
353
|
subagentModel: CLAUDE_SUBAGENT_MODEL,
|
|
328
354
|
effort: CLAUDE_EFFORT,
|
|
329
355
|
isEmpty: isAnthropicConfigEmpty,
|
|
@@ -331,7 +357,7 @@ export function getAdapterForTool(tool: string): ToolAdapter {
|
|
|
331
357
|
baseUrl: CLAUDE_BASE_URL,
|
|
332
358
|
});
|
|
333
359
|
}
|
|
334
|
-
adapterCache.set(
|
|
360
|
+
adapterCache.set(cacheKey, adapter);
|
|
335
361
|
return adapter;
|
|
336
362
|
}
|
|
337
363
|
|
|
@@ -748,7 +774,7 @@ export async function switchChatBinding(args: SwitchChatBindingArgs): Promise<Sw
|
|
|
748
774
|
* Claude 显示 model/effort(来自环境变量);Cursor 显示 model(运行时由
|
|
749
775
|
* cursor-agent 决定,初次创建时尚未学习到,故显示占位)。
|
|
750
776
|
*/
|
|
751
|
-
function formatToolConfigForLog(tool: string, sessionModel?: string): string {
|
|
777
|
+
function formatToolConfigForLog(tool: string, sessionModel?: string, sessionId?: string): string {
|
|
752
778
|
if (tool === "cursor") {
|
|
753
779
|
return `model=${sessionModel ?? "(由 cursor-agent 决定,init 事件后学习)"}`;
|
|
754
780
|
}
|
|
@@ -761,7 +787,7 @@ function formatToolConfigForLog(tool: string, sessionModel?: string): string {
|
|
|
761
787
|
: "effort=(由 codex config.toml 决定)";
|
|
762
788
|
return `model=${modelStr}, ${effortStr}`;
|
|
763
789
|
}
|
|
764
|
-
return `model=${anthropicConfigDisplay(
|
|
790
|
+
return `model=${anthropicConfigDisplay(getModelForSession(sessionId))}, subagentModel=${anthropicConfigDisplay(CLAUDE_SUBAGENT_MODEL)}, effort=${anthropicConfigDisplay(CLAUDE_EFFORT)}`;
|
|
765
791
|
}
|
|
766
792
|
|
|
767
793
|
export async function initClaudeSession(tool: string, overrideCwd?: string, chatId?: string): Promise<{ sessionId: string; cwd: string }> {
|
|
@@ -841,12 +867,12 @@ export async function runAgentSession(
|
|
|
841
867
|
let info: Awaited<ReturnType<ToolAdapter["getSessionInfo"]>>;
|
|
842
868
|
let cwd: string;
|
|
843
869
|
try {
|
|
844
|
-
adapter = getAdapterForTool(tool);
|
|
870
|
+
adapter = getAdapterForTool(tool, sessionId);
|
|
845
871
|
info = await adapter.getSessionInfo(sessionId);
|
|
846
872
|
cwd = info?.cwd ?? (await getDefaultCwd(_chatId));
|
|
847
873
|
if (tid) logTrace(tid, "SESSION_START", { sessionId, tool, cwd, turn: (sessionInfoMap.get(_chatId)?.turnCount ?? 0) + 1 });
|
|
848
874
|
console.log(
|
|
849
|
-
`[${ts()}] Running ${adapter.displayName} session: ${sessionId} (${formatToolConfigForLog(tool, info?.model)}, cwd=${cwd})`
|
|
875
|
+
`[${ts()}] Running ${adapter.displayName} session: ${sessionId} (${formatToolConfigForLog(tool, info?.model, sessionId)}, cwd=${cwd})`
|
|
850
876
|
);
|
|
851
877
|
|
|
852
878
|
// 构建 IM skills prompt(sessionId 方式,无 token)
|
|
@@ -1541,7 +1567,7 @@ async function resolveModelEffort(
|
|
|
1541
1567
|
if (tool === "cursor") {
|
|
1542
1568
|
let model = UNKNOWN_MODEL_PLACEHOLDER;
|
|
1543
1569
|
try {
|
|
1544
|
-
const adapter = getAdapterForTool(tool);
|
|
1570
|
+
const adapter = getAdapterForTool(tool, sessionId);
|
|
1545
1571
|
const info = await adapter.getSessionInfo(sessionId);
|
|
1546
1572
|
if (info?.model) model = info.model;
|
|
1547
1573
|
} catch {
|
|
@@ -1558,7 +1584,7 @@ async function resolveModelEffort(
|
|
|
1558
1584
|
};
|
|
1559
1585
|
}
|
|
1560
1586
|
return {
|
|
1561
|
-
model: anthropicConfigDisplay(
|
|
1587
|
+
model: anthropicConfigDisplay(getModelForSession(sessionId)),
|
|
1562
1588
|
effort: anthropicConfigDisplay(CLAUDE_EFFORT),
|
|
1563
1589
|
};
|
|
1564
1590
|
}
|