jinzd-ai-cli 0.4.320 → 0.4.322
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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{batch-LRYDPB6F.js → batch-IMC6Q63Y.js} +2 -2
- package/dist/{chunk-NOAWUEJJ.js → chunk-3TWEKDHH.js} +1 -1
- package/dist/{chunk-TKBWA3XJ.js → chunk-FHBV5EUM.js} +4 -4
- package/dist/{chunk-WY4IWCQ5.js → chunk-G46THFJN.js} +1 -1
- package/dist/{chunk-4S2XD3M2.js → chunk-HVVDGSUN.js} +4 -4
- package/dist/{chunk-46OEMKQX.js → chunk-NFPJ6KUU.js} +8 -4
- package/dist/{chunk-WW2LFOWE.js → chunk-NX72SBGU.js} +1 -1
- package/dist/{chunk-DB4HVUPI.js → chunk-OR46O57D.js} +1 -1
- package/dist/{chunk-5VZHSSLW.js → chunk-RO67VWKW.js} +1 -1
- package/dist/{chunk-N6YFBRQV.js → chunk-RSWCASRV.js} +1 -1
- package/dist/{chunk-QB3MECZJ.js → chunk-SYK2TDKV.js} +24 -17
- package/dist/{chunk-P4FJBD2H.js → chunk-W7D4M4KV.js} +1 -1
- package/dist/{chunk-SKQUWDRM.js → chunk-X5ZC4TI4.js} +1 -1
- package/dist/{chunk-YAMPLTYO.js → chunk-XVB4RARX.js} +74 -1
- package/dist/{chunk-46M65JDN.js → chunk-ZSR2UIRD.js} +56 -19
- package/dist/{chunk-J7IPNING.js → chunk-ZUONW7FS.js} +1 -1
- package/dist/{ci-7TSOMDHV.js → ci-74EPK5JN.js} +5 -5
- package/dist/{ci-format-6A2RFYZS.js → ci-format-QADWGCX7.js} +2 -2
- package/dist/{constants-EHYM2NS5.js → constants-P5JJ6FO4.js} +1 -1
- package/dist/{constants-P33UDQVS.js → constants-SSVJCBAT.js} +1 -1
- package/dist/{doctor-cli-2B72UMZO.js → doctor-cli-KJT5HMQB.js} +5 -5
- package/dist/electron-server.js +170 -49
- package/dist/{hub-JACLTKYY.js → hub-5CPMJQVG.js} +1 -1
- package/dist/index.js +29 -20
- package/dist/{persistent-memory-5ICLP275.js → persistent-memory-BOUJARIV.js} +2 -2
- package/dist/{persistent-memory-ZIM6ICIR.js → persistent-memory-H5MUAC4X.js} +2 -2
- package/dist/{pr-UBGLNROK.js → pr-BU2FN7CO.js} +5 -5
- package/dist/{run-tests-HCID73KE.js → run-tests-6JKF6JJZ.js} +2 -2
- package/dist/{run-tests-SYJG4S3N.js → run-tests-WJJW77HK.js} +2 -2
- package/dist/{server-BVTFIPB2.js → server-GFL7MYAP.js} +5 -5
- package/dist/{server-3UEEPEUD.js → server-XGY6OUUT.js} +15 -15
- package/dist/{task-orchestrator-6NRCGF5V.js → task-orchestrator-EETPUWBK.js} +5 -5
- package/dist/{usage-6V64TTRE.js → usage-BVHFDNRW.js} +3 -3
- package/package.json +3 -2
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
formatDoctorReport,
|
|
4
4
|
runDoctorCli
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-HVVDGSUN.js";
|
|
6
|
+
import "./chunk-RO67VWKW.js";
|
|
7
7
|
import "./chunk-RS7SKYTS.js";
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-XVB4RARX.js";
|
|
9
|
+
import "./chunk-OR46O57D.js";
|
|
10
10
|
import "./chunk-E2W2MI6H.js";
|
|
11
11
|
import "./chunk-TU3L3PW7.js";
|
|
12
12
|
import "./chunk-HOSJZMQS.js";
|
|
13
13
|
import "./chunk-BMLQPSHP.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-ZUONW7FS.js";
|
|
15
15
|
export {
|
|
16
16
|
formatDoctorReport,
|
|
17
17
|
runDoctorCli
|
package/dist/electron-server.js
CHANGED
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
touchMemoryReferences,
|
|
56
56
|
updateMemoryApproval,
|
|
57
57
|
updateMemoryEntry
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-NX72SBGU.js";
|
|
59
59
|
import {
|
|
60
60
|
DEFAULT_PATTERNS,
|
|
61
61
|
redactJson,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
recoverGbkMojibake,
|
|
82
82
|
runTestsTool,
|
|
83
83
|
shellInvocation
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-RSWCASRV.js";
|
|
85
85
|
import {
|
|
86
86
|
getCurrentSessionKey,
|
|
87
87
|
getExecutionConfigDir,
|
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
SUBAGENT_MAX_ROUNDS_LIMIT,
|
|
124
124
|
VERSION,
|
|
125
125
|
buildUserIdentityPrompt
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-X5ZC4TI4.js";
|
|
127
127
|
|
|
128
128
|
// src/web/access.ts
|
|
129
129
|
import { randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -205,7 +205,7 @@ function imageValidationError(images) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
// src/web/server.ts
|
|
208
|
-
import { join as join25, dirname as
|
|
208
|
+
import { join as join25, dirname as dirname12, resolve as resolve12, relative as relative6, sep as sep5, extname as extname3, resolve as resolvePath } from "path";
|
|
209
209
|
import { existsSync as existsSync31, readFileSync as readFileSync22, readdirSync as readdirSync15, statSync as statSync16, realpathSync as realpathSync3, createReadStream } from "fs";
|
|
210
210
|
import { networkInterfaces as networkInterfaces2 } from "os";
|
|
211
211
|
|
|
@@ -981,17 +981,21 @@ var PRICING_TABLE = {
|
|
|
981
981
|
"glm-4.6": { input: 0.6, output: 2.2 },
|
|
982
982
|
"glm-4.6v": { input: 0.6, output: 2.2 },
|
|
983
983
|
"glm-5": { input: 0.85, output: 2.85 },
|
|
984
|
-
// GLM-5.3
|
|
984
|
+
// GLM-5.3:官方定价页(open.bigmodel.cn/pricing,2026-10-08 浏览器读取)——输入 8 元、
|
|
985
|
+
// 输出 28 元、缓存命中 2 元(每百万 token),按 ¥6.9/$1 换算。此前记的 $1.40/$4.40 是
|
|
986
|
+
// Z.ai 国际站的美元价,而本 provider 打的是国内站、按人民币计费,高报约 20%;更大的
|
|
987
|
+
// 偏差在**缓存**:没有 cacheRead 时缓存命中按输入全价算,2026-10-07 审计会话 1474 万
|
|
988
|
+
// 缓存 token 被记成 $21.34,按官方缓存价约 $4.90(2026-10-07 审计 X-03)。
|
|
985
989
|
// 注意它**始终思考**,思考 token 按输出价计费 —— 实际成本高度取决于 reasoning_effort。
|
|
986
|
-
"glm-5.3": { input:
|
|
990
|
+
"glm-5.3": { input: 8 / CNY_PER_USD, output: 28 / CNY_PER_USD, cacheRead: 2 / CNY_PER_USD },
|
|
987
991
|
// GLM-5.3-Flash:官方定价页(open.bigmodel.cn/pricing)一手数字——输入 0.8 元、
|
|
988
992
|
// 输出 2.8 元、缓存命中 0.23 元(每百万 token),按记账汇率 ¥6.9/$1 换算。
|
|
989
993
|
// **刻意记恢复价而非当前的 5 折限时价**(0.4/1.4/0.115 元):官方只说「限时两周」、
|
|
990
994
|
// 没公布截止日期,静态表表达不了这个时间维度;高估比低估安全——预算告警早触发
|
|
991
995
|
// 好过晚触发。折扣期内 `/cost` 会比实际偏高约一倍,这是刻意的取舍。
|
|
992
996
|
"glm-5.3-flash": { input: 0.116, output: 0.406, cacheRead: 0.033 },
|
|
993
|
-
// GLM-5.2
|
|
994
|
-
"glm-5.2": { input:
|
|
997
|
+
// GLM-5.2:与 GLM-5.3 同价(同一定价页:8 / 28 / 缓存命中 2 元),口径修正同上。
|
|
998
|
+
"glm-5.2": { input: 8 / CNY_PER_USD, output: 28 / CNY_PER_USD, cacheRead: 2 / CNY_PER_USD },
|
|
995
999
|
// GLM-5V-Turbo(2026-04 视觉编程旗舰)官方直连 API 定价 $1.20 / $4.00。
|
|
996
1000
|
"glm-5v-turbo": { input: 1.2, output: 4 },
|
|
997
1001
|
"glm-5.1": { input: 0.95, output: 3.15 },
|
|
@@ -2710,12 +2714,12 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
2710
2714
|
const claimed = extractClaimedFilePaths(content);
|
|
2711
2715
|
if (claimed.length === 0) return [];
|
|
2712
2716
|
const normalize = (p) => p.replace(/\\/g, "/").toLowerCase().replace(/^\.\//, "");
|
|
2713
|
-
const
|
|
2717
|
+
const basename11 = (p) => {
|
|
2714
2718
|
const parts = normalize(p).split("/");
|
|
2715
2719
|
return parts[parts.length - 1] ?? "";
|
|
2716
2720
|
};
|
|
2717
2721
|
const written = extractWrittenFilePaths(extraMessages).map(normalize);
|
|
2718
|
-
const writtenBases = new Set(written.map(
|
|
2722
|
+
const writtenBases = new Set(written.map(basename11));
|
|
2719
2723
|
const writtenFull = new Set(written);
|
|
2720
2724
|
const bashText = extractBashCommands(extraMessages).map((c) => c.replace(/\\/g, "/").toLowerCase()).join("\n");
|
|
2721
2725
|
return claimed.filter((raw) => {
|
|
@@ -2724,8 +2728,8 @@ function findPhantomClaims(content, extraMessages) {
|
|
|
2724
2728
|
for (const w of writtenFull) {
|
|
2725
2729
|
if (w.endsWith("/" + norm2) || norm2.endsWith("/" + w)) return false;
|
|
2726
2730
|
}
|
|
2727
|
-
if (writtenBases.has(
|
|
2728
|
-
const base =
|
|
2731
|
+
if (writtenBases.has(basename11(norm2))) return false;
|
|
2732
|
+
const base = basename11(norm2);
|
|
2729
2733
|
if (base && bashText.includes(base)) return false;
|
|
2730
2734
|
return true;
|
|
2731
2735
|
});
|
|
@@ -4773,6 +4777,7 @@ function ollamaNativeBaseUrl(openAiBaseUrl) {
|
|
|
4773
4777
|
return openAiBaseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
4774
4778
|
}
|
|
4775
4779
|
var NATIVE_API_TIMEOUT_MS = 3e3;
|
|
4780
|
+
var SMALL_CONTEXT_WARN = 16384;
|
|
4776
4781
|
var OllamaProvider = class extends OpenAICompatibleProvider {
|
|
4777
4782
|
// 用 127.0.0.1 而非 localhost:Node.js 18+ 在 Windows 上优先解析 localhost 为 IPv6 (::1),
|
|
4778
4783
|
// 但 Ollama 默认只监听 IPv4,导致连接失败。
|
|
@@ -4851,12 +4856,13 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
|
|
|
4851
4856
|
if (show?.capabilities?.includes("thinking")) thinkingModels.add(id);
|
|
4852
4857
|
if (running.size === 0 && !show) return;
|
|
4853
4858
|
const digest = digests.get(id);
|
|
4854
|
-
const { contextWindow } = resolveOllamaContextWindow({
|
|
4859
|
+
const { contextWindow, source: source2 } = resolveOllamaContextWindow({
|
|
4855
4860
|
runningContext: digest && running.get(digest) || running.get(id),
|
|
4856
4861
|
show,
|
|
4857
4862
|
fallback: this.estimateContextWindow(id)
|
|
4858
4863
|
});
|
|
4859
4864
|
result.set(id, contextWindow);
|
|
4865
|
+
this.contextSources.set(id, source2);
|
|
4860
4866
|
}));
|
|
4861
4867
|
return { contextWindows: result, thinkingModels };
|
|
4862
4868
|
}
|
|
@@ -4952,6 +4958,77 @@ var OllamaProvider = class extends OpenAICompatibleProvider {
|
|
|
4952
4958
|
const target = norm2(model);
|
|
4953
4959
|
return this.dynamicModels.some((m) => m.supportsThinking === true && norm2(m.id) === target);
|
|
4954
4960
|
}
|
|
4961
|
+
// ── 加载后补读真实窗口(2026-10-07 审计 C-01)────────────────────────────
|
|
4962
|
+
//
|
|
4963
|
+
// 上下文窗口只在启动时读一次。模型当时若还没加载,`/api/ps` 里没有它,只能取训练上限
|
|
4964
|
+
// (Qwen3.8 是 262K);而服务端实际开的窗口可能只有它的几十分之一。第一次请求把模型
|
|
4965
|
+
// 加载进来之后若不再读,上下文压力监控、自动压缩与工具预算就整场按那个大数在算——
|
|
4966
|
+
// aicli 以为还有余量,Ollama 早已在悄悄截掉最早的消息(v0.4.311 那次说的正是这个后果)。
|
|
4967
|
+
// 所以每个模型在首次请求之后补读一次 `/api/ps`;读到的窗口若小得连工具定义都放不下,
|
|
4968
|
+
// 提示一次怎么调大。都是后台做,不拖慢这次请求。
|
|
4969
|
+
/** 每个模型的窗口是从哪一级读到的(只有 'running' 是服务端实际值) */
|
|
4970
|
+
contextSources = /* @__PURE__ */ new Map();
|
|
4971
|
+
refreshedAfterLoad = /* @__PURE__ */ new Set();
|
|
4972
|
+
warnedSmallContext = /* @__PURE__ */ new Set();
|
|
4973
|
+
async chat(request) {
|
|
4974
|
+
try {
|
|
4975
|
+
return await super.chat(request);
|
|
4976
|
+
} finally {
|
|
4977
|
+
this.scheduleContextRefresh(request.model);
|
|
4978
|
+
}
|
|
4979
|
+
}
|
|
4980
|
+
async *chatStream(request) {
|
|
4981
|
+
try {
|
|
4982
|
+
yield* super.chatStream(request);
|
|
4983
|
+
} finally {
|
|
4984
|
+
this.scheduleContextRefresh(request.model);
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
async chatWithTools(request, tools) {
|
|
4988
|
+
try {
|
|
4989
|
+
return await super.chatWithTools(request, tools);
|
|
4990
|
+
} finally {
|
|
4991
|
+
this.scheduleContextRefresh(request.model);
|
|
4992
|
+
}
|
|
4993
|
+
}
|
|
4994
|
+
async *chatWithToolsStream(request, tools) {
|
|
4995
|
+
try {
|
|
4996
|
+
yield* super.chatWithToolsStream(request, tools);
|
|
4997
|
+
} finally {
|
|
4998
|
+
this.scheduleContextRefresh(request.model);
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
scheduleContextRefresh(model) {
|
|
5002
|
+
const key = model.replace(/:latest$/, "");
|
|
5003
|
+
if (this.refreshedAfterLoad.has(key)) return;
|
|
5004
|
+
this.refreshedAfterLoad.add(key);
|
|
5005
|
+
void this.refreshLoadedContext(model).catch(() => {
|
|
5006
|
+
});
|
|
5007
|
+
}
|
|
5008
|
+
/** 补读已加载模型的实际窗口,更新同一份权重(digest 相同)的所有别名。测试可直接 await。 */
|
|
5009
|
+
async refreshLoadedContext(model) {
|
|
5010
|
+
const norm2 = (id2) => id2.replace(/:latest$/, "");
|
|
5011
|
+
const [running, digests] = await Promise.all([this.fetchRunningContexts(), this.fetchDigests()]);
|
|
5012
|
+
const self = this.dynamicModels.find((m) => norm2(m.id) === norm2(model));
|
|
5013
|
+
const id = self?.id ?? model;
|
|
5014
|
+
const digest = digests.get(id);
|
|
5015
|
+
const actual = digest && running.get(digest) || running.get(id);
|
|
5016
|
+
if (!actual) return;
|
|
5017
|
+
for (const m of this.dynamicModels) {
|
|
5018
|
+
if (m.id === id || digest && digests.get(m.id) === digest) {
|
|
5019
|
+
m.contextWindow = actual;
|
|
5020
|
+
this.contextSources.set(m.id, "running");
|
|
5021
|
+
}
|
|
5022
|
+
}
|
|
5023
|
+
if (actual < SMALL_CONTEXT_WARN && !this.warnedSmallContext.has(norm2(id))) {
|
|
5024
|
+
this.warnedSmallContext.add(norm2(id));
|
|
5025
|
+
process.stderr.write(
|
|
5026
|
+
`
|
|
5027
|
+
[ollama] ${id} is loaded with a ${actual.toLocaleString()}-token context window. aicli's tool definitions alone take about 8K tokens, so earlier messages will be silently cut off. Raise it: set OLLAMA_CONTEXT_LENGTH=32768 (or more) for the Ollama server, or add "PARAMETER num_ctx 32768" to the model's Modelfile.
|
|
5028
|
+
`
|
|
5029
|
+
);
|
|
5030
|
+
}
|
|
5031
|
+
}
|
|
4955
5032
|
/** 实时刷新模型列表 */
|
|
4956
5033
|
async listModels() {
|
|
4957
5034
|
await this.tryConnect();
|
|
@@ -13487,21 +13564,37 @@ function estimateTokens(text) {
|
|
|
13487
13564
|
return Math.ceil(tokens) + 4;
|
|
13488
13565
|
}
|
|
13489
13566
|
function estimateToolDefinitionTokens(def) {
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
if (param.enum) {
|
|
13494
|
-
charCount += param.enum.join(" ").length;
|
|
13495
|
-
}
|
|
13496
|
-
}
|
|
13497
|
-
const structuralOverhead = 40 + Object.keys(def.parameters).length * 30;
|
|
13498
|
-
return Math.ceil((charCount + structuralOverhead) * 0.25) + 10;
|
|
13567
|
+
const json = JSON.stringify({ name: def.name, description: def.description, parameters: def.parameters });
|
|
13568
|
+
const cjk = json.match(CJK_REGEX)?.length ?? 0;
|
|
13569
|
+
return Math.ceil((json.length - cjk + 40) / 3.7 + cjk * 1.5);
|
|
13499
13570
|
}
|
|
13500
13571
|
|
|
13501
13572
|
// src/tools/registry.ts
|
|
13502
13573
|
import { pathToFileURL } from "url";
|
|
13503
13574
|
import { existsSync as existsSync19, mkdirSync as mkdirSync9, readdirSync as readdirSync9 } from "fs";
|
|
13504
13575
|
import { join as join13 } from "path";
|
|
13576
|
+
var TRIMMABLE_BUILTIN_ORDER = [
|
|
13577
|
+
"google_search",
|
|
13578
|
+
"recall_memory",
|
|
13579
|
+
"search_code",
|
|
13580
|
+
"notebook_edit",
|
|
13581
|
+
"spawn_agent",
|
|
13582
|
+
"run_interactive",
|
|
13583
|
+
"save_memory",
|
|
13584
|
+
"find_references",
|
|
13585
|
+
"get_outline",
|
|
13586
|
+
"find_symbol",
|
|
13587
|
+
"task_stop",
|
|
13588
|
+
"task_list",
|
|
13589
|
+
"task_create",
|
|
13590
|
+
"git_log",
|
|
13591
|
+
"git_diff",
|
|
13592
|
+
"git_commit",
|
|
13593
|
+
"git_status",
|
|
13594
|
+
"web_fetch",
|
|
13595
|
+
"web_search",
|
|
13596
|
+
"run_tests"
|
|
13597
|
+
];
|
|
13505
13598
|
var ToolRegistry = class {
|
|
13506
13599
|
tools = /* @__PURE__ */ new Map();
|
|
13507
13600
|
pluginToolNames = /* @__PURE__ */ new Set();
|
|
@@ -13569,7 +13662,7 @@ var ToolRegistry = class {
|
|
|
13569
13662
|
totalTokens += estimateToolDefinitionTokens(def);
|
|
13570
13663
|
}
|
|
13571
13664
|
if (totalTokens <= tokenBudget) {
|
|
13572
|
-
return { definitions: allDefs, trimmedCount: 0, systemNote: null };
|
|
13665
|
+
return { definitions: allDefs, trimmedCount: 0, trimmedBuiltins: [], systemNote: null };
|
|
13573
13666
|
}
|
|
13574
13667
|
const builtinDefs = [];
|
|
13575
13668
|
const mcpDefs = [];
|
|
@@ -13581,10 +13674,19 @@ var ToolRegistry = class {
|
|
|
13581
13674
|
}
|
|
13582
13675
|
}
|
|
13583
13676
|
let budget = tokenBudget;
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
const
|
|
13677
|
+
const trimmedBuiltins = [];
|
|
13678
|
+
let builtinCost = builtinDefs.reduce((n, d) => n + estimateToolDefinitionTokens(d), 0);
|
|
13679
|
+
const keptBuiltins = new Set(builtinDefs.map((d) => d.name));
|
|
13680
|
+
for (const name of TRIMMABLE_BUILTIN_ORDER) {
|
|
13681
|
+
if (builtinCost <= budget) break;
|
|
13682
|
+
const def = builtinDefs.find((d) => d.name === name);
|
|
13683
|
+
if (!def || this.pluginToolNames.has(name)) continue;
|
|
13684
|
+
keptBuiltins.delete(name);
|
|
13685
|
+
trimmedBuiltins.push(name);
|
|
13686
|
+
builtinCost -= estimateToolDefinitionTokens(def);
|
|
13687
|
+
}
|
|
13688
|
+
budget -= builtinCost;
|
|
13689
|
+
const kept = builtinDefs.filter((d) => keptBuiltins.has(d.name));
|
|
13588
13690
|
const used = usedToolNames ?? /* @__PURE__ */ new Set();
|
|
13589
13691
|
const remaining = [];
|
|
13590
13692
|
for (const def of mcpDefs) {
|
|
@@ -13606,6 +13708,12 @@ var ToolRegistry = class {
|
|
|
13606
13708
|
trimmed++;
|
|
13607
13709
|
}
|
|
13608
13710
|
}
|
|
13711
|
+
const notes = [];
|
|
13712
|
+
if (trimmedBuiltins.length > 0) {
|
|
13713
|
+
notes.push(
|
|
13714
|
+
`[Tool Budget] To fit this model's context window, these tools are not available in this session: ${trimmedBuiltins.join(", ")}. Use bash for the equivalent (git commands, grep for symbols, curl for web pages) instead of calling them.`
|
|
13715
|
+
);
|
|
13716
|
+
}
|
|
13609
13717
|
let systemNote = null;
|
|
13610
13718
|
if (trimmed > 0) {
|
|
13611
13719
|
const trimmedServers = /* @__PURE__ */ new Set();
|
|
@@ -13618,7 +13726,13 @@ var ToolRegistry = class {
|
|
|
13618
13726
|
}
|
|
13619
13727
|
systemNote = `[MCP Tool Budget] ${trimmed} MCP tool(s) from server(s) [${[...trimmedServers].join(", ")}] were excluded to fit the context window. If you need a specific MCP tool that isn't listed, tell the user to ask for it explicitly.`;
|
|
13620
13728
|
}
|
|
13621
|
-
|
|
13729
|
+
if (systemNote) notes.push(systemNote);
|
|
13730
|
+
return {
|
|
13731
|
+
definitions: kept,
|
|
13732
|
+
trimmedCount: trimmed,
|
|
13733
|
+
trimmedBuiltins,
|
|
13734
|
+
systemNote: notes.length > 0 ? notes.join("\n\n") : null
|
|
13735
|
+
};
|
|
13622
13736
|
}
|
|
13623
13737
|
listAll() {
|
|
13624
13738
|
return [...this.tools.values()];
|
|
@@ -14239,7 +14353,7 @@ var McpManager = class {
|
|
|
14239
14353
|
|
|
14240
14354
|
// src/skills/manager.ts
|
|
14241
14355
|
import { existsSync as existsSync20, readdirSync as readdirSync10, mkdirSync as mkdirSync10, statSync as statSync9 } from "fs";
|
|
14242
|
-
import { join as join14 } from "path";
|
|
14356
|
+
import { basename as basename8, dirname as dirname8, join as join14 } from "path";
|
|
14243
14357
|
|
|
14244
14358
|
// src/skills/types.ts
|
|
14245
14359
|
import { readFileSync as readFileSync13 } from "fs";
|
|
@@ -14379,7 +14493,14 @@ var SkillManager = class {
|
|
|
14379
14493
|
}
|
|
14380
14494
|
/** 获取激活技能的 prompt 内容(null 表示无激活技能) */
|
|
14381
14495
|
getActivePromptContent() {
|
|
14382
|
-
|
|
14496
|
+
const skill = this.activeSkill;
|
|
14497
|
+
if (!skill) return null;
|
|
14498
|
+
if (basename8(skill.filePath) === "SKILL.md") {
|
|
14499
|
+
return `Skill directory (SKILL_DIR, \u6280\u80FD\u76EE\u5F55): ${dirname8(skill.filePath)}
|
|
14500
|
+
|
|
14501
|
+
${skill.content}`;
|
|
14502
|
+
}
|
|
14503
|
+
return skill.content;
|
|
14383
14504
|
}
|
|
14384
14505
|
/** 获取激活技能的工具白名单 Set(null 表示无限制) */
|
|
14385
14506
|
getActiveToolFilter() {
|
|
@@ -15371,7 +15492,7 @@ function loadContextFiles(options) {
|
|
|
15371
15492
|
|
|
15372
15493
|
// src/tools/deferred-save.ts
|
|
15373
15494
|
import { statSync as statSync10 } from "fs";
|
|
15374
|
-
import { basename as
|
|
15495
|
+
import { basename as basename9 } from "path";
|
|
15375
15496
|
function snapshotFile(path3) {
|
|
15376
15497
|
try {
|
|
15377
15498
|
const st = statSync10(path3);
|
|
@@ -15392,7 +15513,7 @@ var SAVE_CLAIM_PATTERNS = [
|
|
|
15392
15513
|
/\b(?:saved|written|created|generated)\s+(?:to|at|as|into)\b/i
|
|
15393
15514
|
];
|
|
15394
15515
|
function narratesSavedTarget(content, path3) {
|
|
15395
|
-
const base =
|
|
15516
|
+
const base = basename9(path3);
|
|
15396
15517
|
if (!base || !content.includes(base)) return null;
|
|
15397
15518
|
for (const re of SAVE_CLAIM_PATTERNS) {
|
|
15398
15519
|
if (re.test(content)) return re.source;
|
|
@@ -15414,7 +15535,7 @@ function decideDeferredSave(params) {
|
|
|
15414
15535
|
return {
|
|
15415
15536
|
kind: "skip",
|
|
15416
15537
|
reason: "narrates-target",
|
|
15417
|
-
message: `\u21AA \u8DF3\u8FC7 deferred \u843D\u76D8\uFF1A\u6700\u7EC8\u56DE\u590D\u662F\u5173\u4E8E ${
|
|
15538
|
+
message: `\u21AA \u8DF3\u8FC7 deferred \u843D\u76D8\uFF1A\u6700\u7EC8\u56DE\u590D\u662F\u5173\u4E8E ${basename9(path3)} \u7684\u6C47\u62A5\u800C\u975E\u6587\u6863\u6B63\u6587\uFF08matched: ${narrated}\uFF09\u3002`
|
|
15418
15539
|
};
|
|
15419
15540
|
}
|
|
15420
15541
|
if (!isCleanDocumentBody(body)) {
|
|
@@ -15429,7 +15550,7 @@ function decideDeferredSave(params) {
|
|
|
15429
15550
|
|
|
15430
15551
|
// src/web/session-handler.ts
|
|
15431
15552
|
import { mkdirSync as mkdirSync15, createWriteStream as createWriteStream2 } from "fs";
|
|
15432
|
-
import { dirname as
|
|
15553
|
+
import { dirname as dirname11 } from "path";
|
|
15433
15554
|
|
|
15434
15555
|
// src/repl/commands/project-init.ts
|
|
15435
15556
|
import { existsSync as existsSync24, readFileSync as readFileSync17, readdirSync as readdirSync11, statSync as statSync11 } from "fs";
|
|
@@ -16808,7 +16929,7 @@ function costSourceNote(source2) {
|
|
|
16808
16929
|
|
|
16809
16930
|
// src/web/commands/_shared.ts
|
|
16810
16931
|
import { existsSync as existsSync27, readFileSync as readFileSync19, writeFileSync as writeFileSync3, mkdirSync as mkdirSync13, readdirSync as readdirSync13, statSync as statSync14, createWriteStream } from "fs";
|
|
16811
|
-
import { join as join21, resolve as resolve9, dirname as
|
|
16932
|
+
import { join as join21, resolve as resolve9, dirname as dirname9 } from "path";
|
|
16812
16933
|
|
|
16813
16934
|
// src/cli/review-prompts.ts
|
|
16814
16935
|
function buildReviewPrompt(diff, gitContextStr, detailed) {
|
|
@@ -17595,7 +17716,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
|
|
|
17595
17716
|
Cost: ${formatCost(cost)}` : "";
|
|
17596
17717
|
let memoryLine = "";
|
|
17597
17718
|
try {
|
|
17598
|
-
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-
|
|
17719
|
+
const { countPendingMemories: countPendingMemories2 } = await import("./persistent-memory-H5MUAC4X.js");
|
|
17599
17720
|
const pending = countPendingMemories2(ctx.config.getConfigDir());
|
|
17600
17721
|
if (pending > 0) memoryLine = `
|
|
17601
17722
|
Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
|
|
@@ -18583,7 +18704,7 @@ async function handleTest(args, ctx) {
|
|
|
18583
18704
|
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
18584
18705
|
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
18585
18706
|
}
|
|
18586
|
-
const runTests = ctx.runTests ?? (await import("./run-tests-
|
|
18707
|
+
const runTests = ctx.runTests ?? (await import("./run-tests-6JKF6JJZ.js")).executeTests;
|
|
18587
18708
|
const report = await runTests(testArgs);
|
|
18588
18709
|
ctx.send({ type: "info", message: report });
|
|
18589
18710
|
} catch (err) {
|
|
@@ -18974,7 +19095,7 @@ async function handleMemory(args, ctx) {
|
|
|
18974
19095
|
}
|
|
18975
19096
|
if (intent.kind === "status") {
|
|
18976
19097
|
const { getChatIndexStatus: getChatIndexStatus2 } = await import("./chat-index-RLVLQRRC.js");
|
|
18977
|
-
const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-
|
|
19098
|
+
const { listMemoryEntries: listMemoryEntries2, isMemoryExpired: isMemoryExpired2, formatMemoryForPrompt: formatMemoryForPrompt2 } = await import("./persistent-memory-H5MUAC4X.js");
|
|
18978
19099
|
const memories = listMemoryEntries2(configDir, { includeExpired: true, includeRejected: true });
|
|
18979
19100
|
const injected = formatMemoryForPrompt2(configDir, process.cwd(), ctx.config.get("memory")?.maxChars);
|
|
18980
19101
|
const view = buildMemoryStatusView({
|
|
@@ -18997,7 +19118,7 @@ async function handleMemory(args, ctx) {
|
|
|
18997
19118
|
return;
|
|
18998
19119
|
}
|
|
18999
19120
|
if (intent.kind === "recall") {
|
|
19000
|
-
const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-
|
|
19121
|
+
const { searchPersistentMemories: searchPersistentMemories2, touchMemoryReferences: touchMemoryReferences2 } = await import("./persistent-memory-H5MUAC4X.js");
|
|
19001
19122
|
const { searchChatMemory: searchChatMemory2 } = await import("./chat-index-RLVLQRRC.js");
|
|
19002
19123
|
const persistentHits = searchPersistentMemories2(configDir, intent.query, process.cwd(), 3);
|
|
19003
19124
|
if (persistentHits.length > 0) {
|
|
@@ -19118,7 +19239,7 @@ async function handleMemory(args, ctx) {
|
|
|
19118
19239
|
ctx.handleMemoryManage(intent.action, args[1], intent.action === "expire" ? args[2] : void 0);
|
|
19119
19240
|
} else if (intent.kind === "export") {
|
|
19120
19241
|
if (args[1] === "md") {
|
|
19121
|
-
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-
|
|
19242
|
+
const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-H5MUAC4X.js");
|
|
19122
19243
|
ctx.send({
|
|
19123
19244
|
type: "export_data",
|
|
19124
19245
|
format: "md",
|
|
@@ -20123,7 +20244,7 @@ No tools match "${filter}".
|
|
|
20123
20244
|
const { join: join26 } = await import("path");
|
|
20124
20245
|
const { existsSync: existsSync32 } = await import("fs");
|
|
20125
20246
|
const { getGitRoot: getGitRoot2 } = await import("./git-context-VNCA2GU7.js");
|
|
20126
|
-
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-
|
|
20247
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-P5JJ6FO4.js");
|
|
20127
20248
|
const { approveProject, hashMcpFile } = await import("./project-trust-6CJB5ZMX.js");
|
|
20128
20249
|
const cwd = process.cwd();
|
|
20129
20250
|
const projectRoot = getGitRoot2(cwd) ?? cwd;
|
|
@@ -21042,7 +21163,7 @@ function createReviewCommands() {
|
|
|
21042
21163
|
usage: "/test [command|filter]",
|
|
21043
21164
|
async execute(args, ctx) {
|
|
21044
21165
|
try {
|
|
21045
|
-
const { executeTests } = await import("./run-tests-
|
|
21166
|
+
const { executeTests } = await import("./run-tests-6JKF6JJZ.js");
|
|
21046
21167
|
const argStr = args.join(" ").trim();
|
|
21047
21168
|
let testArgs = {};
|
|
21048
21169
|
if (argStr) {
|
|
@@ -21784,7 +21905,7 @@ ${view.chatHeading}
|
|
|
21784
21905
|
|
|
21785
21906
|
// src/repl/commands/session-commands.ts
|
|
21786
21907
|
import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync14 } from "fs";
|
|
21787
|
-
import { resolve as resolve11, dirname as
|
|
21908
|
+
import { resolve as resolve11, dirname as dirname10 } from "path";
|
|
21788
21909
|
import chalk7 from "chalk";
|
|
21789
21910
|
function createSessionCommands() {
|
|
21790
21911
|
return [
|
|
@@ -22074,7 +22195,7 @@ function createSessionCommands() {
|
|
|
22074
22195
|
const exported = buildSessionExport(session, format, outFile);
|
|
22075
22196
|
const absPath = resolve11(process.cwd(), exported.filename);
|
|
22076
22197
|
try {
|
|
22077
|
-
mkdirSync14(
|
|
22198
|
+
mkdirSync14(dirname10(absPath), { recursive: true });
|
|
22078
22199
|
writeFileSync5(absPath, exported.content, "utf-8");
|
|
22079
22200
|
ctx.renderer.printSuccess(`Exported ${exported.messageCount} messages \u2192 ${absPath}`);
|
|
22080
22201
|
} catch (err) {
|
|
@@ -22241,7 +22362,7 @@ function createSessionCommands() {
|
|
|
22241
22362
|
}
|
|
22242
22363
|
|
|
22243
22364
|
// src/repl/commands/misc-commands.ts
|
|
22244
|
-
import { basename as
|
|
22365
|
+
import { basename as basename10 } from "path";
|
|
22245
22366
|
import { platform as platform8 } from "os";
|
|
22246
22367
|
|
|
22247
22368
|
// src/repl/clipboard.ts
|
|
@@ -22587,7 +22708,7 @@ ${hint}` : "")
|
|
|
22587
22708
|
return;
|
|
22588
22709
|
}
|
|
22589
22710
|
const description = args.join(" ").trim() || "Please describe this image";
|
|
22590
|
-
ctx.renderer.printSuccess(`\u{1F4CB} Image loaded: ${
|
|
22711
|
+
ctx.renderer.printSuccess(`\u{1F4CB} Image loaded: ${basename10(imgPath)}`);
|
|
22591
22712
|
await ctx.sendAsChat(`@${imgPath} ${description}`);
|
|
22592
22713
|
}
|
|
22593
22714
|
},
|
|
@@ -23794,7 +23915,7 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
|
|
|
23794
23915
|
});
|
|
23795
23916
|
if (decision.kind === "save") {
|
|
23796
23917
|
try {
|
|
23797
|
-
mkdirSync15(
|
|
23918
|
+
mkdirSync15(dirname11(target), { recursive: true });
|
|
23798
23919
|
atomicWriteFileSync(target, decision.body);
|
|
23799
23920
|
undoStack.push(target, `save_last_response (deferred): ${target}`);
|
|
23800
23921
|
const lines = decision.body.split("\n").length;
|
|
@@ -23972,7 +24093,7 @@ ${summaryContent}`,
|
|
|
23972
24093
|
let isError = false;
|
|
23973
24094
|
let summary;
|
|
23974
24095
|
try {
|
|
23975
|
-
mkdirSync15(
|
|
24096
|
+
mkdirSync15(dirname11(saveToFile), { recursive: true });
|
|
23976
24097
|
fileStream = createWriteStream2(saveToFile);
|
|
23977
24098
|
const teeSystemPrompt = stripToolCallReminder(systemPrompt ?? "") + CONTENT_ONLY_STREAM_REMINDER;
|
|
23978
24099
|
const teeExtraMessages = extraMessages.length > 0 ? [...extraMessages, { role: "user", content: TEE_FINAL_USER_NUDGE }] : [{ role: "user", content: TEE_FINAL_USER_NUDGE }];
|
|
@@ -25007,7 +25128,7 @@ function getModuleDir() {
|
|
|
25007
25128
|
if (typeof import.meta?.url === "string") {
|
|
25008
25129
|
const url = new URL(import.meta.url);
|
|
25009
25130
|
const filePath = url.pathname.replace(/^\/([A-Z]:)/i, "$1");
|
|
25010
|
-
return
|
|
25131
|
+
return dirname12(filePath);
|
|
25011
25132
|
}
|
|
25012
25133
|
} catch {
|
|
25013
25134
|
}
|
|
@@ -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-EETPUWBK.js");
|
|
162
162
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
163
163
|
let interrupted = false;
|
|
164
164
|
const onSigint = () => {
|