deepseeker-code 1.0.50 → 1.0.51

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.
Files changed (3) hide show
  1. package/README.md +6 -6
  2. package/dist/cli.mjs +73 -59
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -96,8 +96,8 @@ DeepSeeker-Code 支持三种配置来源,优先级 **环境变量 > config.jso
96
96
  // ~/.deepseeker-code/config.json
97
97
  {
98
98
  "apiKey": "sk-你的key", // 不必再 export DEEP_SEEK_API_KEY
99
- "model": "deepseek-v4-flash",
100
- "auxModel": "deepseek-v4-flash",
99
+ "model": "deepseek-flash",
100
+ "auxModel": "deepseek-flash",
101
101
  "apiUrl": "https://api.deepseek.com",
102
102
  "reasoningEffort": "high", // high | max
103
103
  "thinking": true, // 默认开;false 关闭深度思考
@@ -112,8 +112,8 @@ DeepSeeker-Code 支持三种配置来源,优先级 **环境变量 > config.jso
112
112
  | --- | --- | --- | --- |
113
113
  | `apiKey` | string | — | `DEEP_SEEK_API_KEY` |
114
114
  | `apiUrl` | string | `https://api.deepseek.com` | `DEEP_SEEK_API_URL` |
115
- | `model` | string | `deepseek-v4-flash` | `DEEP_SEEK_MODEL` |
116
- | `auxModel` | string | `deepseek-v4-flash` | `DEEP_SEEK_AUX_MODEL` |
115
+ | `model` | string | `deepseek-flash` | `DEEP_SEEK_MODEL` |
116
+ | `auxModel` | string | `deepseek-flash` | `DEEP_SEEK_AUX_MODEL` |
117
117
  | `reasoningEffort` | `high`\|`max` | `high` | `DEEP_SEEK_REASONING_EFFORT` |
118
118
  | `thinking` | boolean | `true` | `DEEP_SEEK_THINKING`(false→`0`) |
119
119
  | `parallelSafeTools` | boolean | `true` | `DEEP_SEEK_PARALLEL_SAFE_TOOLS`(false→`0`) |
@@ -134,8 +134,8 @@ DeepSeeker-Code 支持三种配置来源,优先级 **环境变量 > config.jso
134
134
  | --- | --- | --- |
135
135
  | `DEEP_SEEK_API_KEY` | DeepSeek API Key(**必填**) | — |
136
136
  | `DEEP_SEEK_API_URL` | API 基址(兼容 OpenAI 协议的代理可改此项) | `https://api.deepseek.com` |
137
- | `DEEP_SEEK_MODEL` | 主模型 | `deepseek-v4-flash` |
138
- | `DEEP_SEEK_AUX_MODEL` | 辅助模型(摘要 / 风险分类) | `deepseek-v4-flash` |
137
+ | `DEEP_SEEK_MODEL` | 主模型 | `deepseek-flash` |
138
+ | `DEEP_SEEK_AUX_MODEL` | 辅助模型(摘要 / 风险分类) | `deepseek-flash` |
139
139
  | `DEEP_SEEK_REASONING_EFFORT` | 推理强度,仅 `high` / `max` | `high` |
140
140
  | `DEEP_SEEK_THINKING` | 深度思考开关,设 `0` 关闭 | 开 |
141
141
  | `DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS` | 流式 idle 超时(ms) | `120000` |
package/dist/cli.mjs CHANGED
@@ -130,6 +130,7 @@ var init_strings = __esm({
130
130
  approvalDeny: "\u62D2\u7EDD",
131
131
  errAborted: "\u5DF2\u4E2D\u6B62\u5F53\u524D\u8F6E\u3002",
132
132
  busyBlockSend: "\u23F3 \u6B63\u5728\u751F\u6210\uFF0C\u8BF7\u7B49\u5F85\u6216\u6309 Esc \u4E2D\u6B62\u540E\u518D\u53D1\u9001\u3002",
133
+ escInterrupt: "Esc \u4E2D\u6B62",
133
134
  inboxQueued: "\u{1F4EE} \u5DF2\u6392\u961F\uFF0C\u5C06\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\u6A21\u578B\uFF08Esc \u4ECD\u53EF\u4E2D\u6B62\uFF09\u3002",
134
135
  inboxClaimed: (n) => `\u{1F4EC} \u5DF2\u9001\u8FBE\u6A21\u578B\uFF08${n} \u6761\u8865\u5145\u8F93\u5165\uFF09`,
135
136
  inboxCarryover: (n) => `\u{1F4EC} \u672C\u8F6E\u7ED3\u675F\u65F6 ${n} \u6761\u8865\u5145\u8F93\u5165\u672A\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\uFF0C\u5DF2\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\uFF0C\u4E0B\u8F6E\u5BF9\u8BDD\u81EA\u52A8\u5E26\u5165\u3002`,
@@ -220,10 +221,10 @@ ${cwd}
220
221
  DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u548C\u6267\u884C\u6587\u4EF6\u3002`,
221
222
  optTrust: "\u4FE1\u4EFB\u6B64\u76EE\u5F55",
222
223
  optExit: "\u9000\u51FA",
223
- helpText: (model2, thinking, locale2) => [
224
+ helpText: (model, thinking, locale2) => [
224
225
  "/help \xB7 /status \xB7 /clear \xB7 /exit",
225
226
  "/plan \u2014 \u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814 \u2192 \u65B9\u6848\u5BA1\u6279 \u2192 \u5B9E\u73B0\uFF09",
226
- `/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${model2}\uFF09`,
227
+ `/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${model}\uFF09`,
227
228
  "/switch \u2014 \u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668",
228
229
  `/thinking [off|high|max] \u2014 \u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF08\u5F53\u524D ${thinking}\uFF09`,
229
230
  `/lang [zh|en] \u2014 \u5207\u6362\u754C\u9762\u8BED\u8A00\uFF08\u5F53\u524D ${locale2}\uFF09`,
@@ -232,8 +233,8 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
232
233
  "/trust \u2014 \u7BA1\u7406\u5DF2\u4FE1\u4EFB\u76EE\u5F55\uFF08\u9879\u76EE\u7EA7 hooks/skills \u7B49\u4EC5\u5728\u4FE1\u4EFB\u76EE\u5F55\u52A0\u8F7D\uFF1BCI \u7528 --trust \u663E\u5F0F\u4FE1\u4EFB\uFF09",
233
234
  "Ctrl+C \u9000\u51FA \xB7 Esc \u4E2D\u6B62/\u6E05\u8F93\u5165 \xB7 Ctrl+G \u4E2D\u6B62 \xB7 Ctrl+T \u5C55\u5F00/\u6536\u8D77\u601D\u8003"
234
235
  ].join("\n"),
235
- statusText: (model2, thinking, planOn, locale2, cwd) => [
236
- `\u6A21\u578B\uFF1A${model2}`,
236
+ statusText: (model, thinking, planOn, locale2, cwd) => [
237
+ `\u6A21\u578B\uFF1A${model}`,
237
238
  `\u601D\u8003\u7B49\u7EA7\uFF1A${thinking}`,
238
239
  `\u8BA1\u5212\u6A21\u5F0F\uFF1A${planOn ? "\u5F00" : "\u5173"}`,
239
240
  `\u754C\u9762\u8BED\u8A00\uFF1A${locale2}`,
@@ -278,6 +279,7 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
278
279
  approvalDeny: "Deny",
279
280
  errAborted: "Aborted current turn.",
280
281
  busyBlockSend: "\u23F3 Still generating\u2014wait or press Esc to abort before sending.",
282
+ escInterrupt: "esc to interrupt",
281
283
  inboxQueued: "\u{1F4EE} Queued\u2014will reach the model at the next round boundary (Esc still aborts).",
282
284
  inboxClaimed: (n) => `\u{1F4EC} Delivered to the model (${n} supplemental input${n > 1 ? "s" : ""})`,
283
285
  inboxCarryover: (n) => `\u{1F4EC} ${n} supplemental input${n > 1 ? "s" : ""} not claimed at a round boundary before this run ended; saved to session history and carried into the next turn.`,
@@ -368,10 +370,10 @@ ${cwd}
368
370
  DeepSeeker-Code will read, edit, and execute files here.`,
369
371
  optTrust: "Yes, I trust this folder",
370
372
  optExit: "No, exit",
371
- helpText: (model2, thinking, locale2) => [
373
+ helpText: (model, thinking, locale2) => [
372
374
  "/help \xB7 /status \xB7 /clear \xB7 /exit",
373
375
  "/plan \u2014 Toggle plan mode (read-only research \u2192 review \u2192 implement)",
374
- `/model <model-id> \u2014 Switch model (direct input; current ${model2})`,
376
+ `/model <model-id> \u2014 Switch model (direct input; current ${model})`,
375
377
  "/switch \u2014 Open the model picker",
376
378
  `/thinking [off|high|max] \u2014 Switch thinking level (current ${thinking})`,
377
379
  `/lang [zh|en] \u2014 Switch interface language (current ${locale2})`,
@@ -380,8 +382,8 @@ DeepSeeker-Code will read, edit, and execute files here.`,
380
382
  "/trust \u2014 Manage trusted dirs (project hooks/skills load only when trusted; CI uses --trust)",
381
383
  "Ctrl+C exit \xB7 Esc abort/clear input \xB7 Ctrl+G abort \xB7 Ctrl+T toggle thinking"
382
384
  ].join("\n"),
383
- statusText: (model2, thinking, planOn, locale2, cwd) => [
384
- `Model: ${model2}`,
385
+ statusText: (model, thinking, planOn, locale2, cwd) => [
386
+ `Model: ${model}`,
385
387
  `Thinking: ${thinking}`,
386
388
  `Plan mode: ${planOn ? "on" : "off"}`,
387
389
  `Language: ${locale2}`,
@@ -718,8 +720,8 @@ var init_prefs = __esm({
718
720
  return p && typeof p === "object" ? p : {};
719
721
  };
720
722
  readModelPref = async () => {
721
- const { model: model2 } = await readPrefs();
722
- return typeof model2 === "string" && model2.trim() ? model2.trim() : null;
723
+ const { model } = await readPrefs();
724
+ return typeof model === "string" && model.trim() ? model.trim() : null;
723
725
  };
724
726
  readLocale = async () => {
725
727
  const { locale: locale2 } = await readPrefs();
@@ -804,11 +806,11 @@ var init_type = __esm({
804
806
 
805
807
  // ../core/src/llm/providers/deepseek/client.ts
806
808
  import OpenAI from "openai";
807
- var model, MODEL_NAME, AUX_MODEL_NAME, REASONING_EFFORTS, clampReasoningEffort, MODEL_REASONING_EFFORT, MODEL_THINKING_ENABLED;
809
+ var _model, getModel, MODEL_NAME, AUX_MODEL_NAME, REASONING_EFFORTS, clampReasoningEffort, MODEL_REASONING_EFFORT, MODEL_THINKING_ENABLED;
808
810
  var init_client = __esm({
809
811
  "../core/src/llm/providers/deepseek/client.ts"() {
810
812
  "use strict";
811
- model = new OpenAI({
813
+ getModel = () => _model ??= new OpenAI({
812
814
  baseURL: process.env.DEEP_SEEK_API_URL || "https://api.deepseek.com",
813
815
  apiKey: process.env.DEEP_SEEK_API_KEY,
814
816
  // ★ 瞬态错误自动指数退避重试(SDK 内置:408/409/429/500/502/503/504 + 连接错误),
@@ -819,8 +821,8 @@ var init_client = __esm({
819
821
  timeout: 12e4
820
822
  // 单次请求 120s 兜底(长上下文 / 长生成场景)
821
823
  });
822
- MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-v4-flash";
823
- AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-v4-flash";
824
+ MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-flash";
825
+ AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-flash";
824
826
  REASONING_EFFORTS = ["high", "max"];
825
827
  clampReasoningEffort = (raw) => raw && REASONING_EFFORTS.includes(raw) ? raw : "high";
826
828
  MODEL_REASONING_EFFORT = clampReasoningEffort(process.env.DEEP_SEEK_REASONING_EFFORT);
@@ -875,7 +877,7 @@ var init_stream = __esm({
875
877
  const idleAc = new AbortController();
876
878
  const extSignal = opts.signal;
877
879
  const combinedSignal = extSignal ? AbortSignal.any([idleAc.signal, extSignal]) : idleAc.signal;
878
- const stream = await model.chat.completions.create(requestBody, {
880
+ const stream = await getModel().chat.completions.create(requestBody, {
879
881
  signal: combinedSignal,
880
882
  maxRetries: 0
881
883
  });
@@ -953,7 +955,7 @@ var init_deepseek = __esm({
953
955
  thinking: { type: "disabled" },
954
956
  stream: false
955
957
  };
956
- const completion = await model.chat.completions.create(requestBody, {
958
+ const completion = await getModel().chat.completions.create(requestBody, {
957
959
  signal: opts.signal
958
960
  });
959
961
  if (completion && "choices" in completion) return completion;
@@ -968,7 +970,7 @@ var init_deepseek = __esm({
968
970
  const timer = setTimeout(() => ac.abort(), 1e4);
969
971
  if (signal) signal.addEventListener("abort", () => ac.abort(), { once: true });
970
972
  try {
971
- const completion = await model.chat.completions.create({
973
+ const completion = await getModel().chat.completions.create({
972
974
  messages: [
973
975
  { role: "system", content: "\u4F60\u662F\u5DE5\u5177\u8C03\u7528\u98CE\u9669\u5206\u7C7B\u5668\u3002\u53EA\u56DE SAFE \u6216 RISKY\uFF0C\u4E0D\u8981\u4EFB\u4F55\u89E3\u91CA\u3002\u6309\u5DE5\u5177\u7C7B\u578B\u5224\u5B9A\uFF1A\u2460\u6587\u4EF6(edit/write/create/move_file/delete_path)\u2014\u2014\u5DE5\u4F5C\u533A\u5185\u5E38\u89C4\u6587\u4EF6\u64CD\u4F5C(\u542B\u79FB\u52A8/\u91CD\u547D\u540D)=SAFE\uFF0C\u8986\u76D6/\u5220\u9664/\u79FB\u52A8\u654F\u611F\u6587\u4EF6(.env/.git/.ssh/.aws/\u5BC6\u94A5/credentials/settings.json)\u6216\u5DE5\u4F5C\u533A\u5916=RISKY\uFF1B\u2461\u547D\u4EE4(run_command/run_in_background)\u2014\u2014\u53EA\u8BFB/\u6784\u5EFA/\u6D4B\u8BD5/\u67E5\u770B\u7C7B(ls/cat/git status/npm test/pnpm build/node -v/tsc/lint)=SAFE\uFF0C\u7834\u574F\u6027/\u5916\u5411/\u63D0\u6743(rm -rf\u3001\u683C\u5F0F\u5316\u3001curl|sh\u3001\u5916\u4F20\u6587\u4EF6\u3001chmod 777\u3001shutdown\u3001\u5199\u7CFB\u7EDF\u76EE\u5F55\u3001\u5B89\u88C5\u964C\u751F\u5305)=RISKY\uFF1B\u2462\u7F51\u7EDC(web_fetch/web_search)\u2014\u2014\u6293\u53D6\u516C\u5F00\u6587\u6863/\u5E38\u89C4 URL=SAFE\uFF0C\u5185\u7F51/\u53EF\u7591/\u672A\u77E5 URL=RISKY\uFF1B\u2463git_commit\u2014\u2014\u5E38\u89C4\u63D0\u4EA4=SAFE\uFF0C\u542B\u6076\u610F\u811A\u672C/\u5F02\u5E38\u6539\u52A8=RISKY\uFF1B\u2464MCP(mcp__*)\u2014\u2014\u9ED8\u8BA4 RISKY(\u9ED1\u76D2\u5DE5\u5177\u65E0\u6CD5\u5224\u5B9A\u5185\u90E8\u884C\u4E3A)\u3002\u4EFB\u4F55\u4E0D\u786E\u5B9A\u4E00\u5F8B RISKY\u3002" },
974
976
  { role: "user", content: `\u5DE5\u5177:${toolName}
@@ -1028,7 +1030,7 @@ var init_createModel = __esm({
1028
1030
  "../core/src/llm/createModel.ts"() {
1029
1031
  "use strict";
1030
1032
  init_client();
1031
- SELECTABLE_MODELS = ["deepseek-v4-flash", "deepseek-v4-pro", "deepseek-v4-flash-vision-exp"];
1033
+ SELECTABLE_MODELS = ["deepseek-flash", "deepseek-v4-pro", "deepseek-flash-vision-exp"];
1032
1034
  }
1033
1035
  });
1034
1036
 
@@ -2015,7 +2017,7 @@ function microcompactTextContent(raw) {
2015
2017
  function isAsyncGenerator(x) {
2016
2018
  return x != null && typeof x[Symbol.asyncIterator] === "function";
2017
2019
  }
2018
- var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, batchSummaryPrompt, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, CHECKPOINT_MAX_CHARS, SLOT_PLACEHOLDER, CHECKPOINT_FORMAT, checkpointRules, checkpointPrompt, checkpointDirectPrompt, assembleSlot, parseSlotNarrativeState, synthesizeSlotNarrative, synthesizeSlotNarrativeFromBatch, compactSlotNarrative, splitIntoBatches, compactBatches, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, ensureFitsWindow, collectToolResult;
2020
+ var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, batchSummaryPrompt, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, CHECKPOINT_MAX_CHARS, SLOT_PLACEHOLDER, CHECKPOINT_FORMAT, checkpointRules, checkpointPrompt, checkpointDirectPrompt, assembleSlot, parseSlotNarrativeState, synthesizeSlotNarrative, synthesizeSlotNarrativeFromBatch, compactSlotNarrative, splitIntoBatches, compactBatches, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, persistCompaction, ensureFitsWindow, collectToolResult;
2019
2021
  var init_truncate = __esm({
2020
2022
  "../core/src/agent/truncate.ts"() {
2021
2023
  "use strict";
@@ -2232,6 +2234,19 @@ ${lines}
2232
2234
  }
2233
2235
  };
2234
2236
  SUMMARY_SELF_COMPACT_THRESHOLD = 2e3;
2237
+ persistCompaction = async (sessionId, archivedMessageCount, summary) => {
2238
+ await setRollingState(sessionId, {
2239
+ archivedMessageCount,
2240
+ rollingSummary: summary,
2241
+ consecutiveFailures: 0,
2242
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2243
+ });
2244
+ await appendEvent(sessionId, {
2245
+ dscEvent: "compaction",
2246
+ archivedMessageCount,
2247
+ summary
2248
+ });
2249
+ };
2235
2250
  ensureFitsWindow = async (event) => {
2236
2251
  const correctionRatio = event.correctionRatio ?? 1.4;
2237
2252
  const toolsTokens = event.toolsTokens ?? 0;
@@ -2283,17 +2298,7 @@ ${lines}
2283
2298
  });
2284
2299
  const store = await getRollingState(event.sessionId);
2285
2300
  store.archivedMessageCount = (store.archivedMessageCount || 0) + toCompact.length;
2286
- await setRollingState(event.sessionId, {
2287
- archivedMessageCount: store.archivedMessageCount,
2288
- rollingSummary: summaryMsg.content,
2289
- consecutiveFailures: 0,
2290
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2291
- });
2292
- await appendEvent(event.sessionId, {
2293
- dscEvent: "compaction",
2294
- archivedMessageCount: store.archivedMessageCount,
2295
- summary: summaryMsg.content
2296
- });
2301
+ await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
2297
2302
  } else if (keep > 1) {
2298
2303
  keep--;
2299
2304
  continue;
@@ -2302,17 +2307,7 @@ ${lines}
2302
2307
  event.messageArr.length = 0;
2303
2308
  event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
2304
2309
  const store = await getRollingState(event.sessionId);
2305
- await setRollingState(event.sessionId, {
2306
- archivedMessageCount: store.archivedMessageCount,
2307
- rollingSummary: summaryMsg.content,
2308
- consecutiveFailures: 0,
2309
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2310
- });
2311
- await appendEvent(event.sessionId, {
2312
- dscEvent: "compaction",
2313
- archivedMessageCount: store.archivedMessageCount,
2314
- summary: summaryMsg.content
2315
- });
2310
+ await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
2316
2311
  } else {
2317
2312
  break;
2318
2313
  }
@@ -5399,7 +5394,7 @@ var init_fs = __esm({
5399
5394
  return lines.map((l) => l.length === 0 ? l : l.replace(re, "")).join("\n");
5400
5395
  };
5401
5396
  maskSecretsInContent = (_args, output) => {
5402
- return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*['"]?)[A-Za-z0-9_\-+/=.]{8,}(['"]?)/gi, "$1[MASKED_SECRET]$2").replace(/-----BEGIN [A-Z ]+PRIVATE KEY-----[\s\S]*?-----END [A-Z ]+PRIVATE KEY-----/g, "[MASKED_SECRET (private key block)]");
5397
+ return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*)(['"])[A-Za-z0-9_\-+/=.]{8,}\2/gi, "$1$2[MASKED_SECRET]$2").replace(/((?:authorization|auth[_-]?token)\s*[:=]\s*Bearer\s+)[A-Za-z0-9_\-+/=.]{8,}/gi, "$1[MASKED_SECRET]").replace(/-----BEGIN [A-Z ]+PRIVATE KEY-----[\s\S]*?-----END [A-Z ]+PRIVATE KEY-----/g, "[MASKED_SECRET (private key block)]");
5403
5398
  };
5404
5399
  makeTmpPath = (absPath) => `${absPath}.${Date.now()}.${Math.random().toString(36).slice(2, 7)}.tmp`;
5405
5400
  ATOMIC_TMP_RE = /\.\d+\.[a-z0-9]{1,12}\.tmp$/i;
@@ -10236,7 +10231,7 @@ var init_toolExecution = __esm({
10236
10231
  return false;
10237
10232
  }
10238
10233
  };
10239
- const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd);
10234
+ const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd ?? process.cwd());
10240
10235
  const scriptRunnerBlocked = cmdIsScriptRunner && (perm === null || scriptRunnerCwdDrift);
10241
10236
  if (scriptRunnerCwdDrift) needApproval = true;
10242
10237
  if (perm === null && needApproval && !denied && !scriptRunnerBlocked && calledName === "run_command" && isReadOnlyCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
@@ -10537,7 +10532,7 @@ var init_streamInference = __esm({
10537
10532
  llmDecisionSource,
10538
10533
  signal,
10539
10534
  cleanedToolSchemas,
10540
- model: model2,
10535
+ model,
10541
10536
  thinkingLevel,
10542
10537
  events,
10543
10538
  keepRecentUnits,
@@ -10557,7 +10552,7 @@ var init_streamInference = __esm({
10557
10552
  events({
10558
10553
  sessionId,
10559
10554
  eventType: "llm.request",
10560
- metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, ...prefixFingerprint },
10555
+ metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model, ...prefixFingerprint },
10561
10556
  // ★ P2 口径:估算加上工具 schema 常数项(与 API 真实 prompt_tokens 同口径,trace 里 est/real 才可比)
10562
10557
  usage: { prompt_tokens: estimateTokens(inferenceMessages) + toolsTokens },
10563
10558
  payload: { input: msgText(message[message.length - 1].content) }
@@ -10574,7 +10569,7 @@ var init_streamInference = __esm({
10574
10569
  let compactedThisRound = false;
10575
10570
  for (let streamAttempt = 0; ; streamAttempt++) {
10576
10571
  try {
10577
- for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model: model2, thinkingLevel })) {
10572
+ for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model, thinkingLevel })) {
10578
10573
  if (signal?.aborted) break;
10579
10574
  switch (chunk.kind) {
10580
10575
  case "text":
@@ -10691,7 +10686,7 @@ var init_streamInference = __esm({
10691
10686
  events({
10692
10687
  sessionId,
10693
10688
  eventType: "llm.response",
10694
- metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
10689
+ metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model },
10695
10690
  usage: {
10696
10691
  prompt_tokens: lastUsage?.prompt_tokens,
10697
10692
  completion_tokens: lastUsage?.completion_tokens,
@@ -12015,7 +12010,7 @@ var init_loader6 = __esm({
12015
12010
  console.warn(`\u26A0\uFE0F [agents] frontmatter \u683C\u5F0F\u65E0\u6548\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
12016
12011
  return null;
12017
12012
  }
12018
- const { name, description, role, tools, model: model2 } = parsed.frontmatter;
12013
+ const { name, description, role, tools, model } = parsed.frontmatter;
12019
12014
  if (!name || !description) {
12020
12015
  console.warn(`\u26A0\uFE0F [agents] \u7F3A\u5C11 name \u6216 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
12021
12016
  return null;
@@ -12030,7 +12025,7 @@ var init_loader6 = __esm({
12030
12025
  description,
12031
12026
  role: role || void 0,
12032
12027
  tools: toolList,
12033
- model: model2 || void 0,
12028
+ model: model || void 0,
12034
12029
  body: parsed.body,
12035
12030
  source,
12036
12031
  dir
@@ -13811,9 +13806,9 @@ ${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
13811
13806
  modelRef.current = m;
13812
13807
  void writePrefs({ model: m });
13813
13808
  }, []);
13814
- const resolveModel = useCallback((model2) => {
13809
+ const resolveModel = useCallback((model) => {
13815
13810
  setPendingModel((prev) => {
13816
- prev?.resolve(model2);
13811
+ prev?.resolve(model);
13817
13812
  return null;
13818
13813
  });
13819
13814
  }, []);
@@ -13823,6 +13818,7 @@ ${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
13823
13818
  setModelOverride(picked);
13824
13819
  pushInfo(S.modelSwitched(picked));
13825
13820
  }
13821
+ return picked;
13826
13822
  }, [pushInfo, setModelOverride]);
13827
13823
  const setPlanMode = useCallback((on) => {
13828
13824
  planModeRef.current = on;
@@ -14865,11 +14861,11 @@ var init_StatusStrip = __esm({
14865
14861
  "use strict";
14866
14862
  init_theme();
14867
14863
  init_strings();
14868
- StatusStrip = ({ model: model2, busy, aborting, planMode, autoMode, sessionShort, customLine }) => {
14864
+ StatusStrip = ({ model, busy, aborting, planMode, autoMode, sessionShort, customLine }) => {
14869
14865
  const stateText = aborting ? S.statusAborting : busy ? S.statusStreaming : S.statusIdle;
14870
14866
  const stateColor = busy ? THEME.coralBright : THEME.gray;
14871
14867
  const bits = [
14872
- model2 ? `model: ${model2}` : "",
14868
+ model ? `model: ${model}` : "",
14873
14869
  planMode ? S.statusPlan : "",
14874
14870
  autoMode ? S.statusAuto : "",
14875
14871
  `state: ${stateText}`,
@@ -15088,7 +15084,7 @@ __export(App_exports, {
15088
15084
  import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState4 } from "react";
15089
15085
  import { Box as Box16, Static, Text as Text18, useApp, useInput as useInput2, useStdout } from "ink";
15090
15086
  import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
15091
- var CWD2, RowView, isDynamicRow, App;
15087
+ var CWD2, RowView, isDynamicRow, SPINNER_FRAMES, App;
15092
15088
  var init_App = __esm({
15093
15089
  "src/App.tsx"() {
15094
15090
  "use strict";
@@ -15133,6 +15129,7 @@ var init_App = __esm({
15133
15129
  return /* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail });
15134
15130
  };
15135
15131
  isDynamicRow = (r) => r.kind === "assistant" && !!r.streaming || r.kind === "thinking" && !!r.streaming || r.kind === "tool" && r.status === "running" || r.kind === "todos" && !!r.active;
15132
+ SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
15136
15133
  App = ({ resumeSessionId, initialPlanMode, initialAutoMode, initialIncludeProject, engineReady }) => {
15137
15134
  const state = useChatState(resumeSessionId, initialPlanMode, initialAutoMode);
15138
15135
  const { exit } = useApp();
@@ -15286,6 +15283,24 @@ var init_App = __esm({
15286
15283
  return menuEntries.filter((c) => c.name.toLowerCase().startsWith(q));
15287
15284
  }, [input, menuEntries]);
15288
15285
  const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null || state.pendingModel != null;
15286
+ const [busyClock, setBusyClock] = useState4({ frame: 0, sec: 0 });
15287
+ const busyStartRef = useRef2(0);
15288
+ useEffect4(() => {
15289
+ if (!state.busy) {
15290
+ busyStartRef.current = 0;
15291
+ setBusyClock((c) => c.frame === 0 && c.sec === 0 ? c : { frame: 0, sec: 0 });
15292
+ return;
15293
+ }
15294
+ if (busyStartRef.current === 0) busyStartRef.current = Date.now();
15295
+ if (menuActive) return;
15296
+ const drive = () => setBusyClock({
15297
+ frame: Math.floor(Date.now() / 120) % SPINNER_FRAMES.length,
15298
+ sec: Math.floor((Date.now() - busyStartRef.current) / 1e3)
15299
+ });
15300
+ drive();
15301
+ const t = setInterval(drive, 120);
15302
+ return () => clearInterval(t);
15303
+ }, [state.busy, menuActive]);
15289
15304
  const slashVisible = !menuActive && input.startsWith("/") && filteredCommands.length > 0;
15290
15305
  const inputActive = !menuActive;
15291
15306
  useEffect4(() => {
@@ -15386,7 +15401,9 @@ ${list}
15386
15401
  state.pushInfo(S.modelSwitched(arg));
15387
15402
  return true;
15388
15403
  case "/switch":
15389
- void state.openModelPicker();
15404
+ void state.openModelPicker().then((picked) => {
15405
+ if (picked) setModelDisplay(picked);
15406
+ });
15390
15407
  return true;
15391
15408
  case "/thinking": {
15392
15409
  const lvl = arg.toLowerCase();
@@ -15632,10 +15649,7 @@ ${listText}`);
15632
15649
  /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
15633
15650
  menuActive ? null : /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, children: [
15634
15651
  dynamicRows.map((row) => /* @__PURE__ */ jsx18(RowView, { row, wrapW, streamTail, showThinking: state.showThinkingText }, row.id)),
15635
- state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */ jsxs16(Text18, { color: THEME.coralBright, children: [
15636
- "\u25CF ",
15637
- S.generating
15638
- ] }) }) : null
15652
+ state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */ jsx18(Text18, { color: THEME.coralBright, children: `${SPINNER_FRAMES[busyClock.frame]} ${S.generating} (${busyClock.sec}s \xB7 ${S.escInterrupt})` }) }) : null
15639
15653
  ] }),
15640
15654
  /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, flexShrink: 0, children: [
15641
15655
  state.pendingApproval ? /* @__PURE__ */ jsx18(ApprovalModal, { toolName: state.pendingApproval.toolName, detail: state.pendingApproval.detail, selectedIndex: selectIdx, wrapW }) : null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepseeker-code",
3
- "version": "1.0.50",
3
+ "version": "1.0.51",
4
4
  "description": "DeepSeeker-Code 终端客户端(React Ink,in-process 直驱 runAgent)",
5
5
  "homepage": "https://github.com/xknk/deepSeekCode#readme",
6
6
  "repository": {