jinzd-ai-cli 0.4.273 → 0.4.276
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/LICENSE +21 -21
- package/README.md +610 -610
- package/README.zh-CN.md +559 -559
- package/dist/agent-client-6GX6QQDU.js +0 -0
- package/dist/auth-PE3Z5OHS.js +0 -0
- package/dist/{batch-LOW3GM26.js → batch-F7SKIBI3.js} +2 -2
- package/dist/chat-index-2D5GK2DB.js +0 -0
- package/dist/chunk-23SJVOQD.js +0 -0
- package/dist/chunk-3FEZSLGI.js +0 -0
- package/dist/chunk-4BKXL7SM.js +0 -0
- package/dist/{chunk-AUEX6RNY.js → chunk-4KTK2OYU.js} +54 -21
- package/dist/{chunk-M3NXF4GD.js → chunk-4NH4Q7QK.js} +1 -1
- package/dist/chunk-5C76XDDF.js +0 -0
- package/dist/chunk-6YZEZFX5.js +0 -0
- package/dist/{chunk-FHXLAJJG.js → chunk-AOISQVXS.js} +1 -1
- package/dist/{chunk-FNLWPYP5.js → chunk-ATD2Y3PB.js} +1 -1
- package/dist/chunk-BXP6YZ2P.js +0 -0
- package/dist/chunk-CGDYO52A.js +0 -0
- package/dist/chunk-CKH4KQ4E.js +0 -0
- package/dist/{chunk-JT6UN5C6.js → chunk-DPTEC6AQ.js} +3 -0
- package/dist/{chunk-EDAUDILT.js → chunk-FLDYAXJR.js} +1 -1
- package/dist/chunk-GHWZVPUV.js +0 -0
- package/dist/chunk-GLSR2NR3.js +0 -0
- package/dist/chunk-HLWUDRBO.js +0 -0
- package/dist/chunk-HOSJZMQS.js +0 -0
- package/dist/chunk-IW3Q7AE5.js +0 -0
- package/dist/chunk-KHYD3WXE.js +0 -0
- package/dist/{chunk-Z3UXZ5EI.js → chunk-KWSGSSWN.js} +1 -1
- package/dist/{chunk-4FIDMC2K.js → chunk-MCKUGWOY.js} +69 -4
- package/dist/chunk-MX75TNE5.js +0 -0
- package/dist/{chunk-FN7DE4HA.js → chunk-MXPUOF5K.js} +4 -4
- package/dist/chunk-NR5U6LVG.js +0 -0
- package/dist/{chunk-ZWCQQZT5.js → chunk-NXAHXWPF.js} +1 -1
- package/dist/{chunk-R4YGDJPL.js → chunk-NXNXWM6H.js} +5 -5
- package/dist/chunk-NYNSYLFY.js +0 -0
- package/dist/{chunk-WSCZRQDR.js → chunk-OMBKLWLJ.js} +1 -1
- package/dist/chunk-RYQBBEMM.js +0 -0
- package/dist/{chunk-3OBY7WSS.js → chunk-TEXT4DAT.js} +7 -1
- package/dist/chunk-TU3L3PW7.js +0 -0
- package/dist/{chunk-LEK5WGKV.js → chunk-UNL7NR55.js} +1 -1
- package/dist/chunk-UUSRWSSX.js +0 -0
- package/dist/{chunk-T65VFCID.js → chunk-VF7DMSKF.js} +1 -1
- package/dist/chunk-VOIOUJXI.js +0 -0
- package/dist/{chunk-MTQBSOZW.js → chunk-WYDP2WEQ.js} +4 -4
- package/dist/chunk-XNFIYS7G.js +0 -0
- package/dist/{ci-C5YMQXCS.js → ci-VURFRMWQ.js} +6 -6
- package/dist/{ci-format-R6EMNOGZ.js → ci-format-AFJJIURF.js} +2 -2
- package/dist/config-command-E5DHADEV.js +0 -0
- package/dist/{constants-QJCNMBPJ.js → constants-WO7ERENL.js} +1 -1
- package/dist/{doctor-cli-5CM2I6OF.js → doctor-cli-BGGILTHE.js} +6 -6
- package/dist/electron-server.js +167 -57
- package/dist/file-checkpoint-NKBHGC7L.js +0 -0
- package/dist/git-context-EXOEHQSF.js +0 -0
- package/dist/{hub-7JBSZOSD.js → hub-Z73RLNJI.js} +1 -1
- package/dist/hub-server-RF6LURXY.js +0 -0
- package/dist/index.js +57 -43
- package/dist/indexer-VZETNE4H.js +0 -0
- package/dist/persist-PQM4BRI4.js +0 -0
- package/dist/{persistent-memory-4E53HW3U.js → persistent-memory-5QMARQJF.js} +2 -2
- package/dist/{persistent-memory-KYRY56PG.js → persistent-memory-CI544RLT.js} +2 -2
- package/dist/{pr-NPUGZSXB.js → pr-24REDMGV.js} +6 -6
- package/dist/project-trust-NKYHL3VZ.js +0 -0
- package/dist/{run-tests-5FHQ5IBX.js → run-tests-72VNZXNT.js} +2 -2
- package/dist/{run-tests-SU5CDQKF.js → run-tests-JJ3KOY5E.js} +2 -2
- package/dist/semantic-HLAE2O4F.js +0 -0
- package/dist/{server-ER36M7TR.js → server-JMXC2N3F.js} +40 -29
- package/dist/{server-77YS5NNN.js → server-QJHCJDA7.js} +6 -6
- package/dist/setup-wizard-S55ICNHH.js +0 -0
- package/dist/store-MWNHVGJT.js +0 -0
- package/dist/{task-orchestrator-56PQ7LGV.js → task-orchestrator-DJN36HP5.js} +6 -6
- package/dist/{usage-3YATXRFZ.js → usage-HXJVDETY.js} +3 -3
- package/dist/vector-store-BBDXB5IQ.js +0 -0
- package/dist/wasm/web-tree-sitter.wasm +0 -0
- package/dist/web/client/actions.js +104 -104
- package/dist/web/client/actions.js.br +0 -0
- package/dist/web/client/actions.js.gz +0 -0
- package/dist/web/client/api.js.gz +0 -0
- package/dist/web/client/app.js.gz +0 -0
- package/dist/web/client/dom.js.gz +0 -0
- package/dist/web/client/icon.svg +22 -22
- package/dist/web/client/icon.svg.br +0 -0
- package/dist/web/client/icon.svg.gz +0 -0
- package/dist/web/client/index.html +388 -388
- package/dist/web/client/index.html.br +0 -0
- package/dist/web/client/index.html.gz +0 -0
- package/dist/web/client/manifest.json +15 -15
- package/dist/web/client/sidebar-tabs.js.gz +0 -0
- package/dist/web/client/state.js.gz +0 -0
- package/dist/web/client/style.css +991 -991
- package/dist/web/client/style.css.br +0 -0
- package/dist/web/client/style.css.gz +0 -0
- package/dist/web/client/sw.js +85 -85
- package/dist/web/client/sw.js.br +0 -0
- package/dist/web/client/sw.js.gz +0 -0
- package/dist/web/client/templates.js.gz +0 -0
- package/dist/web/client/util.js.gz +0 -0
- package/dist/web/client/vendor/daisyui-full.min.css.gz +0 -0
- package/dist/web/client/vendor/github-dark.min.css.gz +0 -0
- package/dist/web/client/vendor/github.min.css.gz +0 -0
- package/dist/web/client/vendor/highlight.min.js.gz +0 -0
- package/dist/web/client/vendor/marked.min.js.gz +0 -0
- package/dist/web/client/vendor/tailwind.js.gz +0 -0
- package/package.json +178 -178
package/dist/electron-server.js
CHANGED
|
@@ -40,14 +40,14 @@ import {
|
|
|
40
40
|
touchMemoryReferences,
|
|
41
41
|
updateMemoryApproval,
|
|
42
42
|
updateMemoryEntry
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-4NH4Q7QK.js";
|
|
44
44
|
import {
|
|
45
45
|
redactJson,
|
|
46
46
|
scanString
|
|
47
47
|
} from "./chunk-FSC6KEWU.js";
|
|
48
48
|
import {
|
|
49
49
|
runTestsTool
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-ATD2Y3PB.js";
|
|
51
51
|
import {
|
|
52
52
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
53
53
|
APP_NAME,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
SUBAGENT_MAX_ROUNDS_LIMIT,
|
|
81
81
|
VERSION,
|
|
82
82
|
buildUserIdentityPrompt
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-UNL7NR55.js";
|
|
84
84
|
import {
|
|
85
85
|
hasSemanticIndex,
|
|
86
86
|
semanticSearch
|
|
@@ -99,7 +99,7 @@ import express from "express";
|
|
|
99
99
|
import { createServer } from "http";
|
|
100
100
|
import { WebSocketServer } from "ws";
|
|
101
101
|
import { join as join26, dirname as dirname10, resolve as resolve11, relative as relative6, sep as sep5, extname as extname3, resolve as resolvePath } from "path";
|
|
102
|
-
import { existsSync as existsSync31, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as
|
|
102
|
+
import { existsSync as existsSync31, readFileSync as readFileSync25, readdirSync as readdirSync15, statSync as statSync15, realpathSync as realpathSync3, createReadStream } from "fs";
|
|
103
103
|
import { networkInterfaces } from "os";
|
|
104
104
|
|
|
105
105
|
// src/config/config-manager.ts
|
|
@@ -817,6 +817,9 @@ var PRICING_TABLE = {
|
|
|
817
817
|
"glm-4.6": { input: 0.6, output: 2.2 },
|
|
818
818
|
"glm-4.6v": { input: 0.6, output: 2.2 },
|
|
819
819
|
"glm-5": { input: 0.85, output: 2.85 },
|
|
820
|
+
// GLM-5.3(2026-08-14 发布)官方公告口径「与 GLM-5.2 同价」,直连 API $1.40 / $4.40。
|
|
821
|
+
// 注意它**始终思考**,思考 token 按输出价计费 —— 实际成本高度取决于 reasoning_effort。
|
|
822
|
+
"glm-5.3": { input: 1.4, output: 4.4 },
|
|
820
823
|
// GLM-5.2(2026-06)官方直连 API 定价 $1.40 / $4.40。
|
|
821
824
|
"glm-5.2": { input: 1.4, output: 4.4 },
|
|
822
825
|
// GLM-5V-Turbo(2026-04 视觉编程旗舰)官方直连 API 定价 $1.20 / $4.00。
|
|
@@ -2407,12 +2410,12 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
2407
2410
|
const claimed = extractClaimedFilePaths(content);
|
|
2408
2411
|
if (claimed.length === 0) return [];
|
|
2409
2412
|
const normalize = (p) => p.replace(/\\/g, "/").toLowerCase().replace(/^\.\//, "");
|
|
2410
|
-
const
|
|
2413
|
+
const basename9 = (p) => {
|
|
2411
2414
|
const parts = normalize(p).split("/");
|
|
2412
2415
|
return parts[parts.length - 1] ?? "";
|
|
2413
2416
|
};
|
|
2414
2417
|
const written = extractWrittenFilePaths(extraMessages).map(normalize);
|
|
2415
|
-
const writtenBases = new Set(written.map(
|
|
2418
|
+
const writtenBases = new Set(written.map(basename9));
|
|
2416
2419
|
const writtenFull = new Set(written);
|
|
2417
2420
|
const bashText = extractBashCommands(extraMessages).map((c) => c.replace(/\\/g, "/").toLowerCase()).join("\n");
|
|
2418
2421
|
return claimed.filter((raw) => {
|
|
@@ -2421,8 +2424,8 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
2421
2424
|
for (const w of writtenFull) {
|
|
2422
2425
|
if (w.endsWith("/" + norm2) || norm2.endsWith("/" + w)) return false;
|
|
2423
2426
|
}
|
|
2424
|
-
if (writtenBases.has(
|
|
2425
|
-
const base =
|
|
2427
|
+
if (writtenBases.has(basename9(norm2))) return false;
|
|
2428
|
+
const base = basename9(norm2);
|
|
2426
2429
|
if (base && bashText.includes(base)) return false;
|
|
2427
2430
|
return true;
|
|
2428
2431
|
});
|
|
@@ -2578,6 +2581,11 @@ var META_NARRATION_HEURISTICS = [
|
|
|
2578
2581
|
/(?:需要你|请你|麻烦你|还要你|你看)\s*(?:确认|决定|选择|帮忙|看[一看下]|过目)/u,
|
|
2579
2582
|
/(?:总结|概括|归纳|整理)[一下]?(?:核心|主要|关键)?(?:思路|要点|内容|设计)/u,
|
|
2580
2583
|
/(?:随时|有问题|有需要|需要调整|需要修改|需要补充)\s*(?:联系|找我|告诉|沟通|调整|修改|补充|说)/u,
|
|
2584
|
+
// 「已(全部)生成并保存到 `path`」——对**文件**的汇报,不是文件的正文。
|
|
2585
|
+
// v0.4.274 实战:deferred 赛道的最终回复是一段「4 份教案已全部生成并保存到
|
|
2586
|
+
// `./精简版/` 目录下」的汇报表格,旧启发式只命中 1 条不足阈值,于是它被当文档
|
|
2587
|
+
// 正文落盘、覆盖掉模型刚用 write_file 写好的教案。仍受 2 hits 阈值与标题逃逸约束。
|
|
2588
|
+
/(?:已|均已|都已)[^\n]{0,10}(?:生成|写入|保存|创建)[^\n]{0,6}(?:到|至|于)\s*[`'"]/u,
|
|
2581
2589
|
/^(?:.{0,40})(?:好的[,,,!\s]|嗯[,,,!\s]|收到[了]?[,,,!\s]|了解[了]?[,,,!\s]|明白[了]?[,,,!\s])/mu,
|
|
2582
2590
|
/(?:我来|让我|容我)\s*(?:整理|梳理|归纳|想想|看看|重新|检查|核实)/u,
|
|
2583
2591
|
// 过渡语(需要 2+ hits):"以下是:" / "如下:" 作为独立行。文档中可作小节标题,
|
|
@@ -2723,7 +2731,8 @@ function buildDeferredSaveInstruction(saveToFile) {
|
|
|
2723
2731
|
return `[save_last_response \u65E0\u6CD5\u81EA\u52A8\u751F\u6210\u6587\u6863]
|
|
2724
2732
|
content-only \u6D41\u4EA7\u51FA\u7684\u662F\u5DE5\u5177\u8C03\u7528\u6807\u8BB0 / \u5185\u5FC3\u72EC\u767D\u800C\u975E\u6587\u6863\u6B63\u6587\uFF0C${saveToFile} \u672A\u4FDD\u5B58\u3002
|
|
2725
2733
|
|
|
2726
|
-
\u4E0D\u8981\u518D\u8C03\u7528 save_last_response\u3002\u8BF7\u76F4\u63A5\u7528**\u666E\u901A\u6587\u672C\u56DE\u590D**\u628A\u5B8C\u6574\u6587\u6863\u5199\u51FA\u6765\uFF1A\u7EAF markdown\uFF0C\u7B2C\u4E00\u4E2A\u5B57\u7B26\u5C31\u662F\u9876\u7EA7\u6807\u9898\uFF08\u5982 "# \u5BA1\u8BA1\u62A5\u544A"\uFF09\uFF0C\u4E0D\u8981\u4EFB\u4F55\u5DE5\u5177\u8C03\u7528\u3001\u4E0D\u8981\u524D\u8A00\u94FA\u57AB\u3002\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u628A\u4F60\u8FD9\u6761\u56DE\u590D\u4FDD\u5B58\u5230 ${saveToFile}\u3002
|
|
2734
|
+
\u4E0D\u8981\u518D\u8C03\u7528 save_last_response\u3002\u8BF7\u76F4\u63A5\u7528**\u666E\u901A\u6587\u672C\u56DE\u590D**\u628A\u5B8C\u6574\u6587\u6863\u5199\u51FA\u6765\uFF1A\u7EAF markdown\uFF0C\u7B2C\u4E00\u4E2A\u5B57\u7B26\u5C31\u662F\u9876\u7EA7\u6807\u9898\uFF08\u5982 "# \u5BA1\u8BA1\u62A5\u544A"\uFF09\uFF0C\u4E0D\u8981\u4EFB\u4F55\u5DE5\u5177\u8C03\u7528\u3001\u4E0D\u8981\u524D\u8A00\u94FA\u57AB\u3002\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u628A\u4F60\u8FD9\u6761\u56DE\u590D\u4FDD\u5B58\u5230 ${saveToFile}\u3002
|
|
2735
|
+
\u82E5\u4F60\u6539\u7528 write_file \u7B49\u5DE5\u5177\u76F4\u63A5\u628A\u6587\u4EF6\u5199\u5B8C\uFF08\u591A\u6587\u4EF6\u4EFB\u52A1\u4E0B\u66F4\u5408\u9002\uFF09\uFF0C\u4E5F\u53EF\u4EE5\u2014\u2014\u7CFB\u7EDF\u68C0\u6D4B\u5230 ${saveToFile} \u5DF2\u7531\u5DE5\u5177\u5199\u51FA\u65F6\uFF0C\u4E0D\u4F1A\u518D\u7528\u4F60\u7684\u56DE\u590D\u8986\u76D6\u5B83\u3002`;
|
|
2727
2736
|
}
|
|
2728
2737
|
function teeStreamErrorSummary(saveToFile, errMsg) {
|
|
2729
2738
|
return `[save_last_response failed] streaming was interrupted: ${errMsg}. ${saveToFile} (partial) was deleted. Retry \u2014 and consider producing a more compact output (split very large reports across multiple save_last_response calls if the previous attempt timed out).`;
|
|
@@ -3914,25 +3923,6 @@ var DeepSeekProvider = class extends OpenAICompatibleProvider {
|
|
|
3914
3923
|
}
|
|
3915
3924
|
};
|
|
3916
3925
|
|
|
3917
|
-
// src/providers/static-config.ts
|
|
3918
|
-
function createStaticProviderClass(config) {
|
|
3919
|
-
return class extends OpenAICompatibleProvider {
|
|
3920
|
-
defaultBaseUrl = config.baseUrl;
|
|
3921
|
-
defaultTimeout = config.defaultTimeout ?? 12e4;
|
|
3922
|
-
enableStreamingToolCalls = config.enableStreamingToolCalls ?? true;
|
|
3923
|
-
reliableContentOnlyTee = config.reliableContentOnlyTee ?? true;
|
|
3924
|
-
info = {
|
|
3925
|
-
id: config.id,
|
|
3926
|
-
displayName: config.displayName,
|
|
3927
|
-
defaultModel: config.defaultModel,
|
|
3928
|
-
apiKeyEnvVar: config.apiKeyEnvVar,
|
|
3929
|
-
requiresApiKey: config.requiresApiKey ?? true,
|
|
3930
|
-
baseUrl: config.baseUrl,
|
|
3931
|
-
models: config.models
|
|
3932
|
-
};
|
|
3933
|
-
};
|
|
3934
|
-
}
|
|
3935
|
-
|
|
3936
3926
|
// src/providers/zhipu.ts
|
|
3937
3927
|
var ZHIPU_CONFIG = {
|
|
3938
3928
|
id: "zhipu",
|
|
@@ -3942,6 +3932,7 @@ var ZHIPU_CONFIG = {
|
|
|
3942
3932
|
baseUrl: "https://open.bigmodel.cn/api/paas/v4",
|
|
3943
3933
|
defaultTimeout: 3e5,
|
|
3944
3934
|
models: [
|
|
3935
|
+
{ id: "glm-5.3", displayName: "GLM-5.3 (2026-08 Flagship, 1M, Coding/Security, \u59CB\u7EC8\u601D\u8003)", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
|
|
3945
3936
|
{ id: "glm-5.2", displayName: "GLM-5.2 (2026-06 Flagship, 1M, Coding)", contextWindow: 1048576, supportsStreaming: true, supportsThinking: true },
|
|
3946
3937
|
{ id: "glm-5v-turbo", displayName: "GLM-5V-Turbo (Multimodal Vision + Coding)", contextWindow: 202752, supportsStreaming: true },
|
|
3947
3938
|
{ id: "glm-5.1", displayName: "GLM-5.1 (2026 Flagship, 200K, Agent+Code)", contextWindow: 204800, supportsStreaming: true, supportsThinking: true },
|
|
@@ -3951,7 +3942,39 @@ var ZHIPU_CONFIG = {
|
|
|
3951
3942
|
{ id: "glm-4.6", displayName: "GLM-4.6 (200K, \u4E2D\u6587\u5199\u4F5C\u63A8\u8350)", contextWindow: 204800, supportsStreaming: true }
|
|
3952
3943
|
]
|
|
3953
3944
|
};
|
|
3954
|
-
var
|
|
3945
|
+
var REASONING_EFFORT_MODELS = /^glm-5/i;
|
|
3946
|
+
var ZhipuProvider = class extends OpenAICompatibleProvider {
|
|
3947
|
+
defaultBaseUrl = ZHIPU_CONFIG.baseUrl;
|
|
3948
|
+
/** GLM-5 系列深度思考生成很长,沿用 300s 超时。 */
|
|
3949
|
+
defaultTimeout = ZHIPU_CONFIG.defaultTimeout ?? 12e4;
|
|
3950
|
+
info = {
|
|
3951
|
+
id: ZHIPU_CONFIG.id,
|
|
3952
|
+
displayName: ZHIPU_CONFIG.displayName,
|
|
3953
|
+
defaultModel: ZHIPU_CONFIG.defaultModel,
|
|
3954
|
+
apiKeyEnvVar: ZHIPU_CONFIG.apiKeyEnvVar,
|
|
3955
|
+
requiresApiKey: true,
|
|
3956
|
+
baseUrl: ZHIPU_CONFIG.baseUrl,
|
|
3957
|
+
models: ZHIPU_CONFIG.models
|
|
3958
|
+
};
|
|
3959
|
+
/**
|
|
3960
|
+
* GLM-5 系列透传 `reasoning_effort`。
|
|
3961
|
+
*
|
|
3962
|
+
* 刻意**不**与 `request.thinking` 绑定:GLM-5.3 无论发不发 thinking 字段都会思考,
|
|
3963
|
+
* 档位是这个模型上唯一能压成本的旋钮(思考 token 按输出价 $4.40/MTok 计费),
|
|
3964
|
+
* 若跟着 `thinking` 走,用户 `/think off` 反而会落回服务端默认的 max —— 最贵的一档。
|
|
3965
|
+
*/
|
|
3966
|
+
buildChatRequestParams(request) {
|
|
3967
|
+
const params = super.buildChatRequestParams(request);
|
|
3968
|
+
if (request.thinkingEffort && REASONING_EFFORT_MODELS.test(request.model)) {
|
|
3969
|
+
params["reasoning_effort"] = request.thinkingEffort;
|
|
3970
|
+
}
|
|
3971
|
+
return params;
|
|
3972
|
+
}
|
|
3973
|
+
/** GLM-5 系列支持 low/high/max 三档(官方文档 + 2026-08-20 实测)。 */
|
|
3974
|
+
get supportsReasoningEffort() {
|
|
3975
|
+
return true;
|
|
3976
|
+
}
|
|
3977
|
+
};
|
|
3955
3978
|
|
|
3956
3979
|
// src/providers/kimi.ts
|
|
3957
3980
|
var KIMI_XML_REMINDER = `
|
|
@@ -4130,6 +4153,25 @@ var KimiProvider = class _KimiProvider extends OpenAICompatibleProvider {
|
|
|
4130
4153
|
}
|
|
4131
4154
|
};
|
|
4132
4155
|
|
|
4156
|
+
// src/providers/static-config.ts
|
|
4157
|
+
function createStaticProviderClass(config) {
|
|
4158
|
+
return class extends OpenAICompatibleProvider {
|
|
4159
|
+
defaultBaseUrl = config.baseUrl;
|
|
4160
|
+
defaultTimeout = config.defaultTimeout ?? 12e4;
|
|
4161
|
+
enableStreamingToolCalls = config.enableStreamingToolCalls ?? true;
|
|
4162
|
+
reliableContentOnlyTee = config.reliableContentOnlyTee ?? true;
|
|
4163
|
+
info = {
|
|
4164
|
+
id: config.id,
|
|
4165
|
+
displayName: config.displayName,
|
|
4166
|
+
defaultModel: config.defaultModel,
|
|
4167
|
+
apiKeyEnvVar: config.apiKeyEnvVar,
|
|
4168
|
+
requiresApiKey: config.requiresApiKey ?? true,
|
|
4169
|
+
baseUrl: config.baseUrl,
|
|
4170
|
+
models: config.models
|
|
4171
|
+
};
|
|
4172
|
+
};
|
|
4173
|
+
}
|
|
4174
|
+
|
|
4133
4175
|
// src/providers/minimax.ts
|
|
4134
4176
|
var MINIMAX_CONFIG = {
|
|
4135
4177
|
id: "minimax",
|
|
@@ -14453,12 +14495,70 @@ function loadContextFiles(options) {
|
|
|
14453
14495
|
};
|
|
14454
14496
|
}
|
|
14455
14497
|
|
|
14498
|
+
// src/tools/deferred-save.ts
|
|
14499
|
+
import { statSync as statSync10 } from "fs";
|
|
14500
|
+
import { basename as basename8 } from "path";
|
|
14501
|
+
function snapshotFile(path3) {
|
|
14502
|
+
try {
|
|
14503
|
+
const st = statSync10(path3);
|
|
14504
|
+
return { exists: true, size: st.size, mtimeMs: st.mtimeMs };
|
|
14505
|
+
} catch {
|
|
14506
|
+
return { exists: false, size: 0, mtimeMs: 0 };
|
|
14507
|
+
}
|
|
14508
|
+
}
|
|
14509
|
+
function armDeferredSave(path3) {
|
|
14510
|
+
return { path: path3, armedSnapshot: snapshotFile(path3) };
|
|
14511
|
+
}
|
|
14512
|
+
function snapshotChanged(a, b) {
|
|
14513
|
+
return a.exists !== b.exists || a.size !== b.size || a.mtimeMs !== b.mtimeMs;
|
|
14514
|
+
}
|
|
14515
|
+
var SAVE_CLAIM_PATTERNS = [
|
|
14516
|
+
/(?:已|均已|都已)[^\n]{0,12}(?:保存|写入|生成|创建|落盘)/u,
|
|
14517
|
+
/(?:保存|写入|生成|创建)(?:到|至|于)\s*[`'"]/u,
|
|
14518
|
+
/\b(?:saved|written|created|generated)\s+(?:to|at|as|into)\b/i
|
|
14519
|
+
];
|
|
14520
|
+
function narratesSavedTarget(content, path3) {
|
|
14521
|
+
const base = basename8(path3);
|
|
14522
|
+
if (!base || !content.includes(base)) return null;
|
|
14523
|
+
for (const re of SAVE_CLAIM_PATTERNS) {
|
|
14524
|
+
if (re.test(content)) return re.source;
|
|
14525
|
+
}
|
|
14526
|
+
return null;
|
|
14527
|
+
}
|
|
14528
|
+
function decideDeferredSave(params) {
|
|
14529
|
+
const { content, path: path3, armedSnapshot, currentSnapshot } = params;
|
|
14530
|
+
const body = stripOuterCodeFence(content);
|
|
14531
|
+
if (snapshotChanged(armedSnapshot, currentSnapshot)) {
|
|
14532
|
+
return {
|
|
14533
|
+
kind: "skip",
|
|
14534
|
+
reason: "target-already-written",
|
|
14535
|
+
message: `\u21AA \u8DF3\u8FC7 deferred \u843D\u76D8\uFF1A${path3} \u5DF2\u5728\u672C\u8F6E\u88AB\u5DE5\u5177\u5199\u5165\uFF08${currentSnapshot.size} bytes\uFF09\uFF0C\u4E0D\u7528\u6700\u7EC8\u56DE\u590D\u8986\u76D6\u5B83\u3002`
|
|
14536
|
+
};
|
|
14537
|
+
}
|
|
14538
|
+
const narrated = narratesSavedTarget(body, path3);
|
|
14539
|
+
if (narrated) {
|
|
14540
|
+
return {
|
|
14541
|
+
kind: "skip",
|
|
14542
|
+
reason: "narrates-target",
|
|
14543
|
+
message: `\u21AA \u8DF3\u8FC7 deferred \u843D\u76D8\uFF1A\u6700\u7EC8\u56DE\u590D\u662F\u5173\u4E8E ${basename8(path3)} \u7684\u6C47\u62A5\u800C\u975E\u6587\u6863\u6B63\u6587\uFF08matched: ${narrated}\uFF09\u3002`
|
|
14544
|
+
};
|
|
14545
|
+
}
|
|
14546
|
+
if (!isCleanDocumentBody(body)) {
|
|
14547
|
+
return {
|
|
14548
|
+
kind: "skip",
|
|
14549
|
+
reason: "not-document-body",
|
|
14550
|
+
message: `\u21AA \u8DF3\u8FC7 deferred \u843D\u76D8\uFF1A\u6700\u7EC8\u56DE\u590D\u4E0D\u50CF\u53EF\u76F4\u63A5\u843D\u76D8\u7684\u6587\u6863\u6B63\u6587\uFF08${path3} \u672A\u6539\u52A8\uFF09\u3002`
|
|
14551
|
+
};
|
|
14552
|
+
}
|
|
14553
|
+
return { kind: "save", body };
|
|
14554
|
+
}
|
|
14555
|
+
|
|
14456
14556
|
// src/web/session-handler.ts
|
|
14457
14557
|
import { mkdirSync as mkdirSync14, createWriteStream as createWriteStream2 } from "fs";
|
|
14458
14558
|
import { dirname as dirname9 } from "path";
|
|
14459
14559
|
|
|
14460
14560
|
// src/repl/commands/project-init.ts
|
|
14461
|
-
import { existsSync as existsSync26, readFileSync as readFileSync21, readdirSync as readdirSync11, statSync as
|
|
14561
|
+
import { existsSync as existsSync26, readFileSync as readFileSync21, readdirSync as readdirSync11, statSync as statSync11 } from "fs";
|
|
14462
14562
|
import { join as join20 } from "path";
|
|
14463
14563
|
var SCAN_SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
14464
14564
|
"node_modules",
|
|
@@ -14503,11 +14603,11 @@ function scanDirTree(dir, maxDepth = 2, maxEntries = 80) {
|
|
|
14503
14603
|
const sorted = filtered.sort((a, b) => {
|
|
14504
14604
|
let aIsDir = false, bIsDir = false;
|
|
14505
14605
|
try {
|
|
14506
|
-
aIsDir =
|
|
14606
|
+
aIsDir = statSync11(join20(d, a)).isDirectory();
|
|
14507
14607
|
} catch {
|
|
14508
14608
|
}
|
|
14509
14609
|
try {
|
|
14510
|
-
bIsDir =
|
|
14610
|
+
bIsDir = statSync11(join20(d, b)).isDirectory();
|
|
14511
14611
|
} catch {
|
|
14512
14612
|
}
|
|
14513
14613
|
if (aIsDir !== bIsDir) return aIsDir ? -1 : 1;
|
|
@@ -14520,7 +14620,7 @@ function scanDirTree(dir, maxDepth = 2, maxEntries = 80) {
|
|
|
14520
14620
|
const connector = isLast ? "+-- " : "|-- ";
|
|
14521
14621
|
let isDir;
|
|
14522
14622
|
try {
|
|
14523
|
-
isDir =
|
|
14623
|
+
isDir = statSync11(fullPath).isDirectory();
|
|
14524
14624
|
} catch {
|
|
14525
14625
|
continue;
|
|
14526
14626
|
}
|
|
@@ -15549,7 +15649,7 @@ function costSourceNote(source) {
|
|
|
15549
15649
|
}
|
|
15550
15650
|
|
|
15551
15651
|
// src/web/commands/_shared.ts
|
|
15552
|
-
import { existsSync as existsSync29, readFileSync as readFileSync23, writeFileSync as writeFileSync3, mkdirSync as mkdirSync13, readdirSync as readdirSync13, statSync as
|
|
15652
|
+
import { existsSync as existsSync29, readFileSync as readFileSync23, writeFileSync as writeFileSync3, mkdirSync as mkdirSync13, readdirSync as readdirSync13, statSync as statSync14, createWriteStream } from "fs";
|
|
15553
15653
|
import { join as join24, resolve as resolve9, dirname as dirname8 } from "path";
|
|
15554
15654
|
|
|
15555
15655
|
// src/cli/review-prompts.ts
|
|
@@ -15622,7 +15722,7 @@ function readGitDiff(options = {}) {
|
|
|
15622
15722
|
}
|
|
15623
15723
|
|
|
15624
15724
|
// src/diagnostics/doctor-report.ts
|
|
15625
|
-
import { existsSync as existsSync28, statSync as
|
|
15725
|
+
import { existsSync as existsSync28, statSync as statSync13 } from "fs";
|
|
15626
15726
|
import { join as join23 } from "path";
|
|
15627
15727
|
import { arch as arch2, platform as platform7, release as release2 } from "os";
|
|
15628
15728
|
|
|
@@ -15632,7 +15732,7 @@ import {
|
|
|
15632
15732
|
mkdirSync as mkdirSync12,
|
|
15633
15733
|
readdirSync as readdirSync12,
|
|
15634
15734
|
readFileSync as readFileSync22,
|
|
15635
|
-
statSync as
|
|
15735
|
+
statSync as statSync12,
|
|
15636
15736
|
unlinkSync as unlinkSync6,
|
|
15637
15737
|
writeFileSync as writeFileSync2
|
|
15638
15738
|
} from "fs";
|
|
@@ -15661,7 +15761,7 @@ function listRecentCrashes(limit = 10, configDir) {
|
|
|
15661
15761
|
if (!name.startsWith(CRASH_LOG_PREFIX) || !name.endsWith(".log")) continue;
|
|
15662
15762
|
const full = join22(dir, name);
|
|
15663
15763
|
try {
|
|
15664
|
-
const st =
|
|
15764
|
+
const st = statSync12(full);
|
|
15665
15765
|
const head = readFileSync22(full, "utf-8").split("\n").slice(0, 20);
|
|
15666
15766
|
const tsLine = head.find((l) => l.startsWith("timestamp:"));
|
|
15667
15767
|
const kindLine = head.find((l) => l.startsWith("kind:"));
|
|
@@ -15702,7 +15802,7 @@ function getConfigDirUsage(configDir) {
|
|
|
15702
15802
|
}
|
|
15703
15803
|
function dirSize(path3) {
|
|
15704
15804
|
try {
|
|
15705
|
-
const st =
|
|
15805
|
+
const st = statSync12(path3);
|
|
15706
15806
|
if (st.isFile()) return st.size;
|
|
15707
15807
|
if (!st.isDirectory()) return 0;
|
|
15708
15808
|
let sum = 0;
|
|
@@ -15721,7 +15821,7 @@ function checkFile(label, path3) {
|
|
|
15721
15821
|
let sizeBytes = null;
|
|
15722
15822
|
if (exists) {
|
|
15723
15823
|
try {
|
|
15724
|
-
sizeBytes =
|
|
15824
|
+
sizeBytes = statSync13(path3).size;
|
|
15725
15825
|
} catch {
|
|
15726
15826
|
}
|
|
15727
15827
|
}
|
|
@@ -16043,7 +16143,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
16043
16143
|
Cost: ${formatCost(cost)}` : "";
|
|
16044
16144
|
let memoryLine = "";
|
|
16045
16145
|
try {
|
|
16046
|
-
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-
|
|
16146
|
+
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-CI544RLT.js");
|
|
16047
16147
|
const pending = countPendingMemories2(ctx.config.getConfigDir());
|
|
16048
16148
|
if (pending > 0) memoryLine = `
|
|
16049
16149
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -16856,7 +16956,7 @@ async function handleTest(args, ctx) {
|
|
|
16856
16956
|
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
16857
16957
|
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
16858
16958
|
}
|
|
16859
|
-
const runTests = ctx.runTests ?? (await import("./run-tests-
|
|
16959
|
+
const runTests = ctx.runTests ?? (await import("./run-tests-72VNZXNT.js")).executeTests;
|
|
16860
16960
|
const report = await runTests(testArgs);
|
|
16861
16961
|
ctx.send({ type: "info", message: report });
|
|
16862
16962
|
} catch (err) {
|
|
@@ -17192,7 +17292,7 @@ async function handleMemory(args, ctx) {
|
|
|
17192
17292
|
ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
|
|
17193
17293
|
} else if (sub === "export") {
|
|
17194
17294
|
if (args[1] === "md") {
|
|
17195
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
17295
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-CI544RLT.js");
|
|
17196
17296
|
ctx.send({
|
|
17197
17297
|
type: "export_data",
|
|
17198
17298
|
format: "md",
|
|
@@ -17235,7 +17335,7 @@ Use /add-dir remove to clear.` : "No directories added.\nUsage: /add-dir <path>
|
|
|
17235
17335
|
ctx.send({ type: "error", message: `Directory not found: ${dirPath}` });
|
|
17236
17336
|
return;
|
|
17237
17337
|
}
|
|
17238
|
-
if (!
|
|
17338
|
+
if (!statSync14(dirPath).isDirectory()) {
|
|
17239
17339
|
ctx.send({ type: "error", message: `Not a directory: ${dirPath}` });
|
|
17240
17340
|
return;
|
|
17241
17341
|
}
|
|
@@ -18570,16 +18670,26 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
|
|
|
18570
18670
|
},
|
|
18571
18671
|
onFinalContent: (content, { reasoningContent }) => {
|
|
18572
18672
|
this.send({ type: "response_done", content, usage });
|
|
18573
|
-
if (pendingTeeSave
|
|
18574
|
-
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
|
|
18578
|
-
|
|
18579
|
-
|
|
18580
|
-
|
|
18581
|
-
|
|
18582
|
-
|
|
18673
|
+
if (pendingTeeSave) {
|
|
18674
|
+
const target = pendingTeeSave.path;
|
|
18675
|
+
const decision = decideDeferredSave({
|
|
18676
|
+
content,
|
|
18677
|
+
path: target,
|
|
18678
|
+
armedSnapshot: pendingTeeSave.armedSnapshot,
|
|
18679
|
+
currentSnapshot: snapshotFile(target)
|
|
18680
|
+
});
|
|
18681
|
+
if (decision.kind === "save") {
|
|
18682
|
+
try {
|
|
18683
|
+
mkdirSync14(dirname9(target), { recursive: true });
|
|
18684
|
+
atomicWriteFileSync(target, decision.body);
|
|
18685
|
+
undoStack.push(target, `save_last_response (deferred): ${target}`);
|
|
18686
|
+
const lines = decision.body.split("\n").length;
|
|
18687
|
+
this.send({ type: "info", message: `\u2705 Saved (from reply): ${target} (${lines} lines, ${decision.body.length} chars)` });
|
|
18688
|
+
} catch (saveErr) {
|
|
18689
|
+
this.send({ type: "info", message: `\u2717 Could not save to ${target}: ${saveErr.message ?? saveErr}` });
|
|
18690
|
+
}
|
|
18691
|
+
} else {
|
|
18692
|
+
this.send({ type: "info", message: decision.message });
|
|
18583
18693
|
}
|
|
18584
18694
|
pendingTeeSave = null;
|
|
18585
18695
|
}
|
|
@@ -18640,7 +18750,7 @@ ${summaryContent}`,
|
|
|
18640
18750
|
// 与 REPL 不同:Web 端 tee 成功后继续 agentic 循环(返回 'continue'),
|
|
18641
18751
|
// 让模型基于工具结果给出最终文本。
|
|
18642
18752
|
runSaveLastResponseTee: async ({ toolCalls, call, saveToFile, extraMessages, reasoningContent }) => {
|
|
18643
|
-
if (pendingTeeSave === saveToFile) {
|
|
18753
|
+
if (pendingTeeSave?.path === saveToFile) {
|
|
18644
18754
|
const results = toolCalls.map((tc) => ({
|
|
18645
18755
|
callId: tc.id,
|
|
18646
18756
|
content: tc.id === call.id ? buildDeferredSaveInstruction(saveToFile) : "[skipped: write the document as plain text, not via tools]",
|
|
@@ -18651,7 +18761,7 @@ ${summaryContent}`,
|
|
|
18651
18761
|
}
|
|
18652
18762
|
const freshPrior = freshPriorContent(lastAssistantText(apiMessages), lastAssistantAtTurnStart);
|
|
18653
18763
|
if (provider.supportsContentOnlyTee === false && !freshPrior) {
|
|
18654
|
-
pendingTeeSave = saveToFile;
|
|
18764
|
+
pendingTeeSave = armDeferredSave(saveToFile);
|
|
18655
18765
|
this.send({ type: "info", message: `\u21AA \u8DF3\u8FC7 tee\uFF08${this.currentProvider} \u4E0D\u64C5\u957F content-only \u751F\u6210\uFF09\uFF0C\u6539\u7528\u666E\u901A\u6587\u672C\u5199\u62A5\u544A\uFF0C\u5C06\u81EA\u52A8\u4FDD\u5B58\u5230 ${saveToFile}` });
|
|
18656
18766
|
const results = toolCalls.map((tc) => ({
|
|
18657
18767
|
callId: tc.id,
|
|
@@ -18674,7 +18784,7 @@ ${summaryContent}`,
|
|
|
18674
18784
|
usage,
|
|
18675
18785
|
freshPrior
|
|
18676
18786
|
);
|
|
18677
|
-
if (teeResult.deferred) pendingTeeSave = saveToFile;
|
|
18787
|
+
if (teeResult.deferred) pendingTeeSave = armDeferredSave(saveToFile);
|
|
18678
18788
|
const teeToolResults = toolCalls.map((tc) => {
|
|
18679
18789
|
if (tc.id === call.id) {
|
|
18680
18790
|
return {
|
|
@@ -20062,7 +20172,7 @@ async function startWebServer(options = {}) {
|
|
|
20062
20172
|
return;
|
|
20063
20173
|
}
|
|
20064
20174
|
try {
|
|
20065
|
-
const stat =
|
|
20175
|
+
const stat = statSync15(fullPath);
|
|
20066
20176
|
if (stat.size > 512 * 1024) {
|
|
20067
20177
|
res.json({ error: `File too large (${(stat.size / 1024).toFixed(0)} KB, max 512 KB)` });
|
|
20068
20178
|
return;
|
|
File without changes
|
|
File without changes
|
|
@@ -158,7 +158,7 @@ ${content}`);
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
161
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
161
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-DJN36HP5.js");
|
|
162
162
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
163
163
|
let interrupted = false;
|
|
164
164
|
const onSigint = () => {
|
|
File without changes
|