jinzd-ai-cli 0.4.276 → 0.4.278
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/dist/{batch-F7SKIBI3.js → batch-7Y4NAA6N.js} +2 -2
- package/dist/{chunk-VF7DMSKF.js → chunk-2BYQP6JX.js} +1 -1
- package/dist/{chunk-GLSR2NR3.js → chunk-4DEMGCK4.js} +4 -3
- package/dist/{chunk-MXPUOF5K.js → chunk-4Z6GAYB5.js} +4 -4
- package/dist/{chunk-NXAHXWPF.js → chunk-H7QC5VMQ.js} +1 -1
- package/dist/{chunk-MCKUGWOY.js → chunk-JJCNNQTU.js} +183 -3
- package/dist/{chunk-AOISQVXS.js → chunk-L3CPM472.js} +1 -1
- package/dist/{chunk-ATD2Y3PB.js → chunk-LOXEYWC3.js} +1 -1
- package/dist/{chunk-WYDP2WEQ.js → chunk-LTZFUYBT.js} +4 -4
- package/dist/{chunk-4NH4Q7QK.js → chunk-LXXQTWT2.js} +1 -1
- package/dist/{chunk-QCG6UU2S.js → chunk-PPIISCFN.js} +4 -3
- package/dist/{chunk-KWSGSSWN.js → chunk-RFSKPCYC.js} +1 -1
- package/dist/{chunk-OMBKLWLJ.js → chunk-SB4XONS4.js} +1 -1
- package/dist/{chunk-UNL7NR55.js → chunk-SJCOE4C7.js} +1 -1
- package/dist/{chunk-4KTK2OYU.js → chunk-UGY5SVNX.js} +46 -20
- package/dist/{chunk-NXNXWM6H.js → chunk-WOXIKQRI.js} +16 -7
- package/dist/{chunk-FLDYAXJR.js → chunk-X3722RFA.js} +1 -1
- package/dist/{ci-VURFRMWQ.js → ci-WDF2CYR4.js} +5 -5
- package/dist/{ci-format-AFJJIURF.js → ci-format-7B5VAZGA.js} +2 -2
- package/dist/{constants-WO7ERENL.js → constants-DC3TNLTL.js} +1 -1
- package/dist/{doctor-cli-BGGILTHE.js → doctor-cli-CDDG5XOY.js} +5 -5
- package/dist/electron-server.js +378 -78
- package/dist/{hub-Z73RLNJI.js → hub-TO7ODOIA.js} +1 -1
- package/dist/index.js +175 -188
- package/dist/{indexer-M2LJGTY2.js → indexer-RBEKMFT4.js} +1 -1
- package/dist/{indexer-VZETNE4H.js → indexer-TNDWGFRI.js} +1 -1
- package/dist/{persistent-memory-5QMARQJF.js → persistent-memory-BU63CSGK.js} +2 -2
- package/dist/{persistent-memory-CI544RLT.js → persistent-memory-JCENBMCJ.js} +2 -2
- package/dist/{pr-24REDMGV.js → pr-GVSZYX6I.js} +5 -5
- package/dist/{run-tests-72VNZXNT.js → run-tests-2Q5MJHXB.js} +2 -2
- package/dist/{run-tests-JJ3KOY5E.js → run-tests-R4IQS6IF.js} +2 -2
- package/dist/{server-JMXC2N3F.js → server-KAURBKFI.js} +167 -62
- package/dist/{server-QJHCJDA7.js → server-WXLE53HG.js} +6 -6
- package/dist/{task-orchestrator-DJN36HP5.js → task-orchestrator-RJ6FXYY5.js} +8 -8
- package/dist/{usage-HXJVDETY.js → usage-V3R7DA7M.js} +2 -2
- package/dist/web/client/app.js +4 -1
- package/dist/web/client/app.js.br +0 -0
- package/dist/web/client/app.js.gz +0 -0
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2BYQP6JX.js";
|
|
5
5
|
import "./chunk-TU3L3PW7.js";
|
|
6
6
|
import {
|
|
7
7
|
atomicWriteFileSync
|
|
8
8
|
} from "./chunk-IW3Q7AE5.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-X3722RFA.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/batch.ts
|
|
12
12
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -20,8 +20,9 @@ import { Parser, Language } from "web-tree-sitter";
|
|
|
20
20
|
import { createRequire } from "module";
|
|
21
21
|
import path from "path";
|
|
22
22
|
import fs from "fs";
|
|
23
|
+
var packagedProcess = process;
|
|
23
24
|
var entryCandidates = [
|
|
24
|
-
|
|
25
|
+
packagedProcess.pkg?.entrypoint,
|
|
25
26
|
process.argv[1],
|
|
26
27
|
process.execPath
|
|
27
28
|
].filter((p) => !!p);
|
|
@@ -48,12 +49,12 @@ function resolveWasmPath(filename) {
|
|
|
48
49
|
candidates.push(path.join(dir, "..", "wasm", filename));
|
|
49
50
|
candidates.push(path.join(dir, "..", "dist", "wasm", filename));
|
|
50
51
|
}
|
|
51
|
-
if (
|
|
52
|
+
if (packagedProcess.pkg) {
|
|
52
53
|
candidates.push(path.join(path.dirname(process.execPath), "dist", "wasm", filename));
|
|
53
54
|
candidates.push(path.join("/snapshot", "ai-cli", "dist", "wasm", filename));
|
|
54
55
|
candidates.push(path.join("/snapshot", "jinzd-ai-cli", "dist", "wasm", filename));
|
|
55
56
|
}
|
|
56
|
-
const resourcesPath =
|
|
57
|
+
const resourcesPath = packagedProcess.resourcesPath;
|
|
57
58
|
if (resourcesPath) {
|
|
58
59
|
candidates.push(path.join(resourcesPath, "app.asar.unpacked", "dist", "wasm", filename));
|
|
59
60
|
candidates.push(path.join(resourcesPath, "app", "dist", "wasm", filename));
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
evaluateCiGate,
|
|
4
4
|
normalizeCiThresholds
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-H7QC5VMQ.js";
|
|
6
6
|
import {
|
|
7
7
|
buildReviewPrompt,
|
|
8
8
|
buildSecurityReviewPrompt,
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
} from "./chunk-6YZEZFX5.js";
|
|
14
14
|
import {
|
|
15
15
|
ProviderRegistry
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UGY5SVNX.js";
|
|
17
17
|
import {
|
|
18
18
|
ConfigManager
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-2BYQP6JX.js";
|
|
20
20
|
import {
|
|
21
21
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-X3722RFA.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/ci.ts
|
|
25
25
|
import { execFileSync } from "child_process";
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
estimateTokens,
|
|
7
7
|
truncateForPersist
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WOXIKQRI.js";
|
|
9
9
|
import {
|
|
10
10
|
isMemoryExpired,
|
|
11
11
|
isMemoryStale
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RFSKPCYC.js";
|
|
13
13
|
import {
|
|
14
14
|
isCleanDocumentBody,
|
|
15
15
|
stripOuterCodeFence
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
MCP_PROTOCOL_VERSION,
|
|
28
28
|
MCP_TOOL_PREFIX,
|
|
29
29
|
VERSION
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-X3722RFA.js";
|
|
31
31
|
|
|
32
32
|
// src/mcp/client.ts
|
|
33
33
|
import { spawn } from "child_process";
|
|
@@ -1382,6 +1382,178 @@ function applyThinkCommand(sub, state) {
|
|
|
1382
1382
|
return stay(`Unknown /think option "${sub}" \u2014 expected on | off | low | high | max | status`);
|
|
1383
1383
|
}
|
|
1384
1384
|
|
|
1385
|
+
// src/core/provider-command.ts
|
|
1386
|
+
function preservedSuffix(messageCount) {
|
|
1387
|
+
return messageCount > 0 ? ` (conversation preserved: ${messageCount} messages)` : "";
|
|
1388
|
+
}
|
|
1389
|
+
function resolveProviderSwitch(input) {
|
|
1390
|
+
const id = input.targetId;
|
|
1391
|
+
if (!input.configured) {
|
|
1392
|
+
return {
|
|
1393
|
+
status: "not-configured",
|
|
1394
|
+
message: `Provider '${id}' is not configured. Run: aicli config`
|
|
1395
|
+
};
|
|
1396
|
+
}
|
|
1397
|
+
if (input.availableModels.length === 0) {
|
|
1398
|
+
return {
|
|
1399
|
+
status: "no-models",
|
|
1400
|
+
message: `Provider '${id}' has no available models. ` + (id === "ollama" ? "Make sure Ollama is running (`ollama serve`) and has models (`ollama pull <model>`)." : "Check provider configuration.")
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
if (id === input.currentProvider) {
|
|
1404
|
+
return { status: "unchanged", message: `Already using provider: ${id}` };
|
|
1405
|
+
}
|
|
1406
|
+
const model = input.configuredDefaultModel || input.providerDefaultModel;
|
|
1407
|
+
return {
|
|
1408
|
+
status: "switched",
|
|
1409
|
+
providerId: id,
|
|
1410
|
+
model,
|
|
1411
|
+
message: `Switched to provider: ${id} (${model})` + preservedSuffix(input.messageCount)
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
function parseModelCommand(args, currentProvider) {
|
|
1415
|
+
const raw = args[0];
|
|
1416
|
+
if (!raw) return { kind: "select" };
|
|
1417
|
+
const sub = raw.toLowerCase();
|
|
1418
|
+
if (sub === "refresh") return { kind: "refresh", providerId: args[1] ?? currentProvider };
|
|
1419
|
+
if (sub === "cache") {
|
|
1420
|
+
if ((args[1] ?? "").toLowerCase() === "clear") return { kind: "cache-clear", providerId: args[2] };
|
|
1421
|
+
return { kind: "cache-show" };
|
|
1422
|
+
}
|
|
1423
|
+
return { kind: "set", modelId: raw };
|
|
1424
|
+
}
|
|
1425
|
+
function resolveModelSwitch(input) {
|
|
1426
|
+
if (input.targetModel === input.currentModel) {
|
|
1427
|
+
return { status: "unchanged", message: `Already using model: ${input.targetModel}` };
|
|
1428
|
+
}
|
|
1429
|
+
const known = input.knownModels.includes(input.targetModel);
|
|
1430
|
+
return {
|
|
1431
|
+
status: "switched",
|
|
1432
|
+
model: input.targetModel,
|
|
1433
|
+
message: `Switched to model: ${input.targetModel}` + preservedSuffix(input.messageCount),
|
|
1434
|
+
warning: known ? void 0 : `'${input.targetModel}' is not in the known model list for ${input.provider}. If the provider rejects it, check the spelling or run /model refresh ${input.provider}.`
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
var PLAN_MODE_TOOL_HINT = [
|
|
1438
|
+
"read_file \xB7 list_dir \xB7 grep_files \xB7 glob_files",
|
|
1439
|
+
"web_fetch \xB7 google_search \xB7 ask_user \xB7 write_todos"
|
|
1440
|
+
];
|
|
1441
|
+
function applyPlanCommand(sub, active) {
|
|
1442
|
+
const key = (sub ?? "enter").toLowerCase() === "toggle" ? active ? "exit" : "enter" : (sub ?? "enter").toLowerCase();
|
|
1443
|
+
if (key === "enter") {
|
|
1444
|
+
if (active) {
|
|
1445
|
+
return {
|
|
1446
|
+
planMode: true,
|
|
1447
|
+
changed: false,
|
|
1448
|
+
status: "already-active",
|
|
1449
|
+
summary: "Already in Plan Mode. Use /plan execute to start executing, or /plan exit to leave.",
|
|
1450
|
+
details: []
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
return {
|
|
1454
|
+
planMode: true,
|
|
1455
|
+
changed: true,
|
|
1456
|
+
status: "entered",
|
|
1457
|
+
summary: "\u{1F4CB} Plan Mode activated",
|
|
1458
|
+
details: [
|
|
1459
|
+
"AI can now ONLY use read-only tools:",
|
|
1460
|
+
...PLAN_MODE_TOOL_HINT,
|
|
1461
|
+
"Describe your task and the AI will analyze the codebase and create a detailed implementation plan.",
|
|
1462
|
+
"When ready: /plan execute | To cancel: /plan exit"
|
|
1463
|
+
]
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
if (key === "execute") {
|
|
1467
|
+
if (!active) {
|
|
1468
|
+
return { planMode: false, changed: false, status: "not-active", summary: "Not in Plan Mode. Enter first with /plan", details: [] };
|
|
1469
|
+
}
|
|
1470
|
+
return {
|
|
1471
|
+
planMode: false,
|
|
1472
|
+
changed: true,
|
|
1473
|
+
status: "executing",
|
|
1474
|
+
summary: "Plan Mode ended \u2014 switching to execute mode. AI now has full tool access.",
|
|
1475
|
+
details: []
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
if (key === "exit" || key === "cancel") {
|
|
1479
|
+
if (!active) {
|
|
1480
|
+
return { planMode: false, changed: false, status: "not-active", summary: "Not in Plan Mode.", details: [] };
|
|
1481
|
+
}
|
|
1482
|
+
return { planMode: false, changed: true, status: "cancelled", summary: "Plan Mode cancelled. Returning to normal mode.", details: [] };
|
|
1483
|
+
}
|
|
1484
|
+
if (key === "status" || key === "show") {
|
|
1485
|
+
return {
|
|
1486
|
+
planMode: active,
|
|
1487
|
+
changed: false,
|
|
1488
|
+
status: "status",
|
|
1489
|
+
summary: `Plan Mode: ${active ? "ACTIVE \u{1F4CB}" : "inactive"}`,
|
|
1490
|
+
details: active ? ["Tools restricted to read-only set.", "Use /plan execute to start executing, or /plan exit to cancel."] : []
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
return {
|
|
1494
|
+
planMode: active,
|
|
1495
|
+
changed: false,
|
|
1496
|
+
status: "unknown",
|
|
1497
|
+
summary: `Unknown /plan option "${sub}" \u2014 expected execute | exit | status`,
|
|
1498
|
+
details: []
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
function parseRouteCommand(args) {
|
|
1502
|
+
const sub = (args[0] ?? "show").toLowerCase();
|
|
1503
|
+
if (sub === "on" || sub === "enable") return { kind: "enable" };
|
|
1504
|
+
if (sub === "off" || sub === "disable") return { kind: "disable" };
|
|
1505
|
+
if (sub === "test") {
|
|
1506
|
+
const message = args.slice(1).join(" ").trim();
|
|
1507
|
+
return message ? { kind: "test", message } : { kind: "usage", message: "Usage: /route test <message>" };
|
|
1508
|
+
}
|
|
1509
|
+
if (sub === "show" || sub === "status") return { kind: "show" };
|
|
1510
|
+
return { kind: "unknown", message: `Unknown subcommand: ${sub}. Usage: /route [on|off|show|test <message>]` };
|
|
1511
|
+
}
|
|
1512
|
+
function routingEmptyRulesNote(routing) {
|
|
1513
|
+
if (routing && routing.rules.length > 0) return null;
|
|
1514
|
+
return 'No rules configured yet. Add rules under `routing.rules` in ~/.aicli/config.json.\nExample: { match: { tag: "fast" }, model: "claude-haiku-4-5" }';
|
|
1515
|
+
}
|
|
1516
|
+
function describeRoutingRule(rule, index) {
|
|
1517
|
+
const parts = [];
|
|
1518
|
+
if (rule.match.tag) parts.push(`tag=#${rule.match.tag}`);
|
|
1519
|
+
if (rule.match.contains && rule.match.contains.length > 0) {
|
|
1520
|
+
const shown = rule.match.contains.slice(0, 3).join(", ");
|
|
1521
|
+
parts.push(`contains=[${shown}${rule.match.contains.length > 3 ? ", \u2026" : ""}]`);
|
|
1522
|
+
}
|
|
1523
|
+
if (typeof rule.match.maxLength === "number") parts.push(`maxLen=${rule.match.maxLength}`);
|
|
1524
|
+
if (typeof rule.match.minLength === "number") parts.push(`minLen=${rule.match.minLength}`);
|
|
1525
|
+
const empty = parts.length === 0;
|
|
1526
|
+
return {
|
|
1527
|
+
index,
|
|
1528
|
+
name: rule.name,
|
|
1529
|
+
condition: empty ? "(empty \u2014 never matches)" : parts.join(" & "),
|
|
1530
|
+
model: rule.model,
|
|
1531
|
+
empty
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
function describeRouting(input) {
|
|
1535
|
+
const rules = input.routing?.rules ?? [];
|
|
1536
|
+
return {
|
|
1537
|
+
enabled: input.routing?.enabled === true,
|
|
1538
|
+
provider: input.provider,
|
|
1539
|
+
currentModel: input.currentModel,
|
|
1540
|
+
fallback: input.routing?.fallback,
|
|
1541
|
+
rules: rules.map((r, i) => describeRoutingRule(r, i)),
|
|
1542
|
+
noRulesNote: rules.length === 0 ? "(no rules configured \u2014 edit ~/.aicli/config.json `routing.rules`)" : null,
|
|
1543
|
+
hint: "Commands: /route on | off | test <msg> | show"
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
function routeDecisionRows(message, currentModel, decision) {
|
|
1547
|
+
const rows = [
|
|
1548
|
+
{ label: "Input", value: message },
|
|
1549
|
+
{ label: "Current", value: currentModel },
|
|
1550
|
+
{ label: "Decision", value: `${decision.model} ${decision.overridden ? "\u2192 ROUTED" : "(unchanged)"}` },
|
|
1551
|
+
{ label: "Reason", value: decision.reason }
|
|
1552
|
+
];
|
|
1553
|
+
if (typeof decision.ruleIdx === "number") rows.push({ label: "Rule", value: `#${decision.ruleIdx}` });
|
|
1554
|
+
return rows;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1385
1557
|
// src/core/profile-command.ts
|
|
1386
1558
|
var PROFILE_FIELDS = ["name", "nickname", "role", "bio", "interests", "locale", "extra"];
|
|
1387
1559
|
function stripSurroundingQuotes(value) {
|
|
@@ -1543,6 +1715,14 @@ function costSourceNote(source) {
|
|
|
1543
1715
|
|
|
1544
1716
|
export {
|
|
1545
1717
|
applyThinkCommand,
|
|
1718
|
+
resolveProviderSwitch,
|
|
1719
|
+
parseModelCommand,
|
|
1720
|
+
resolveModelSwitch,
|
|
1721
|
+
applyPlanCommand,
|
|
1722
|
+
parseRouteCommand,
|
|
1723
|
+
routingEmptyRulesNote,
|
|
1724
|
+
describeRouting,
|
|
1725
|
+
routeDecisionRows,
|
|
1546
1726
|
applyProfileCommand,
|
|
1547
1727
|
readGitDiff,
|
|
1548
1728
|
scanDirTree,
|
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
listHooks,
|
|
9
9
|
listInstalledPlugins,
|
|
10
10
|
resetStats
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-L3CPM472.js";
|
|
12
12
|
import {
|
|
13
13
|
ProviderRegistry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-UGY5SVNX.js";
|
|
15
15
|
import {
|
|
16
16
|
ConfigManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-2BYQP6JX.js";
|
|
18
18
|
import {
|
|
19
19
|
getGitRoot
|
|
20
20
|
} from "./chunk-HOSJZMQS.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
MCP_PROJECT_CONFIG_NAME,
|
|
27
27
|
MEMORY_FILE_NAME,
|
|
28
28
|
VERSION
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-X3722RFA.js";
|
|
30
30
|
|
|
31
31
|
// src/diagnostics/doctor-report.ts
|
|
32
32
|
import { existsSync as existsSync3, statSync as statSync2 } from "fs";
|
|
@@ -19,8 +19,9 @@ import { Parser, Language } from "web-tree-sitter";
|
|
|
19
19
|
import { createRequire } from "module";
|
|
20
20
|
import path from "path";
|
|
21
21
|
import fs from "fs";
|
|
22
|
+
var packagedProcess = process;
|
|
22
23
|
var entryCandidates = [
|
|
23
|
-
|
|
24
|
+
packagedProcess.pkg?.entrypoint,
|
|
24
25
|
process.argv[1],
|
|
25
26
|
process.execPath
|
|
26
27
|
].filter((p) => !!p);
|
|
@@ -47,12 +48,12 @@ function resolveWasmPath(filename) {
|
|
|
47
48
|
candidates.push(path.join(dir, "..", "wasm", filename));
|
|
48
49
|
candidates.push(path.join(dir, "..", "dist", "wasm", filename));
|
|
49
50
|
}
|
|
50
|
-
if (
|
|
51
|
+
if (packagedProcess.pkg) {
|
|
51
52
|
candidates.push(path.join(path.dirname(process.execPath), "dist", "wasm", filename));
|
|
52
53
|
candidates.push(path.join("/snapshot", "ai-cli", "dist", "wasm", filename));
|
|
53
54
|
candidates.push(path.join("/snapshot", "jinzd-ai-cli", "dist", "wasm", filename));
|
|
54
55
|
}
|
|
55
|
-
const resourcesPath =
|
|
56
|
+
const resourcesPath = packagedProcess.resourcesPath;
|
|
56
57
|
if (resourcesPath) {
|
|
57
58
|
candidates.push(path.join(resourcesPath, "app.asar.unpacked", "dist", "wasm", filename));
|
|
58
59
|
candidates.push(path.join(resourcesPath, "app", "dist", "wasm", filename));
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
MEMORY_FILE_NAME,
|
|
14
14
|
MEMORY_MAX_CHARS,
|
|
15
15
|
MEMORY_STORE_FILE_NAME
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-X3722RFA.js";
|
|
17
17
|
|
|
18
18
|
// src/memory/persistent-memory.ts
|
|
19
19
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
|
|
@@ -31,7 +31,8 @@ var BaseProvider = class {
|
|
|
31
31
|
return this.reliableContentOnlyTee;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* 该 provider 是否支持 `reasoning_effort` 档位(low/high/max
|
|
34
|
+
* 该 provider 是否支持 `reasoning_effort` 档位(low/high/max)。目前是 DeepSeek V4
|
|
35
|
+
* 与智谱 GLM-5 系列(v0.4.276 接入 GLM-5.3 时补上——它关不掉思考,档位是唯一的成本闸门)。
|
|
35
36
|
*
|
|
36
37
|
* 2026-08-14 审计 P2-03:提示符标签此前无条件渲染成 `[THINK:high]`,于是 Claude
|
|
37
38
|
* (用 thinkingBudget 计 token 预算)和 GLM(根本没有 effort 概念)也显示一个
|
|
@@ -947,6 +948,18 @@ Node.js does not automatically use system proxies. Try one of the following:
|
|
|
947
948
|
|
|
948
949
|
// src/providers/openai-compatible.ts
|
|
949
950
|
import OpenAI from "openai";
|
|
951
|
+
|
|
952
|
+
// src/providers/openai-extensions.ts
|
|
953
|
+
function toSdkParams(params) {
|
|
954
|
+
return params;
|
|
955
|
+
}
|
|
956
|
+
function readReasoningContent(message) {
|
|
957
|
+
if (!message || typeof message !== "object") return void 0;
|
|
958
|
+
const value = message.reasoning_content;
|
|
959
|
+
return typeof value === "string" ? value : void 0;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// src/providers/openai-compatible.ts
|
|
950
963
|
function toUsage(u) {
|
|
951
964
|
if (!u) return void 0;
|
|
952
965
|
const cached = u.prompt_tokens_details?.cached_tokens ?? 0;
|
|
@@ -1064,7 +1077,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1064
1077
|
continue;
|
|
1065
1078
|
}
|
|
1066
1079
|
if (m.role === "assistant" && m.toolCalls && m.toolCalls.length > 0) {
|
|
1067
|
-
|
|
1080
|
+
msgs.push({
|
|
1068
1081
|
role: "assistant",
|
|
1069
1082
|
content: typeof m.content === "string" && m.content ? m.content : null,
|
|
1070
1083
|
tool_calls: m.toolCalls.map((tc) => ({
|
|
@@ -1073,15 +1086,22 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1073
1086
|
function: { name: tc.name, arguments: JSON.stringify(tc.arguments) }
|
|
1074
1087
|
})),
|
|
1075
1088
|
reasoning_content: m.reasoningContent ?? ""
|
|
1076
|
-
};
|
|
1077
|
-
msgs.push(assistantMsg);
|
|
1089
|
+
});
|
|
1078
1090
|
continue;
|
|
1079
1091
|
}
|
|
1080
|
-
const base = { role: m.role, content: m.content };
|
|
1081
1092
|
if (m.role === "assistant") {
|
|
1082
|
-
|
|
1093
|
+
msgs.push({
|
|
1094
|
+
role: "assistant",
|
|
1095
|
+
content: typeof m.content === "string" ? m.content : "",
|
|
1096
|
+
reasoning_content: m.reasoningContent ?? ""
|
|
1097
|
+
});
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
1100
|
+
if (m.role === "system") {
|
|
1101
|
+
msgs.push({ role: "system", content: typeof m.content === "string" ? m.content : "" });
|
|
1102
|
+
continue;
|
|
1083
1103
|
}
|
|
1084
|
-
msgs.push(
|
|
1104
|
+
msgs.push({ role: "user", content: m.content });
|
|
1085
1105
|
}
|
|
1086
1106
|
const systemContent = [request.systemPrompt, request.systemPromptVolatile].filter(Boolean).join("\n\n---\n\n");
|
|
1087
1107
|
if (systemContent) {
|
|
@@ -1110,12 +1130,13 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1110
1130
|
*/
|
|
1111
1131
|
async chat(request) {
|
|
1112
1132
|
try {
|
|
1113
|
-
const
|
|
1133
|
+
const params = {
|
|
1114
1134
|
model: request.model,
|
|
1115
1135
|
messages: this.buildMessages(request),
|
|
1116
1136
|
...this.buildChatRequestParams(request),
|
|
1117
1137
|
stream: false
|
|
1118
|
-
}
|
|
1138
|
+
};
|
|
1139
|
+
const response = await this.client.chat.completions.create(toSdkParams(params), {
|
|
1119
1140
|
timeout: request.timeout ?? this.defaultTimeout,
|
|
1120
1141
|
signal: request.signal
|
|
1121
1142
|
});
|
|
@@ -1123,7 +1144,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1123
1144
|
if (!firstChoice) {
|
|
1124
1145
|
return { content: "", model: response.model, usage: void 0 };
|
|
1125
1146
|
}
|
|
1126
|
-
const reasoningContent = firstChoice.message
|
|
1147
|
+
const reasoningContent = readReasoningContent(firstChoice.message);
|
|
1127
1148
|
return {
|
|
1128
1149
|
content: firstChoice.message.content ?? "",
|
|
1129
1150
|
model: response.model,
|
|
@@ -1136,14 +1157,15 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1136
1157
|
}
|
|
1137
1158
|
async *chatStream(request) {
|
|
1138
1159
|
try {
|
|
1139
|
-
const
|
|
1160
|
+
const params = {
|
|
1140
1161
|
model: request.model,
|
|
1141
1162
|
messages: this.buildMessages(request),
|
|
1142
1163
|
...this.buildChatRequestParams(request),
|
|
1143
1164
|
stream: true,
|
|
1144
1165
|
// 请求末尾 usage chunk,供 token 统计使用
|
|
1145
1166
|
stream_options: { include_usage: true }
|
|
1146
|
-
}
|
|
1167
|
+
};
|
|
1168
|
+
const stream = await this.client.chat.completions.create(toSdkParams(params), {
|
|
1147
1169
|
timeout: request.timeout ?? this.defaultTimeout,
|
|
1148
1170
|
signal: request.signal
|
|
1149
1171
|
});
|
|
@@ -1213,14 +1235,15 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1213
1235
|
const baseMessages = this.buildMessages(request);
|
|
1214
1236
|
const extraMessages = request._extraMessages ?? [];
|
|
1215
1237
|
const allMessages = [...baseMessages, ...extraMessages];
|
|
1216
|
-
const
|
|
1238
|
+
const params = {
|
|
1217
1239
|
model: request.model,
|
|
1218
1240
|
messages: allMessages,
|
|
1219
1241
|
tools: openaiTools,
|
|
1220
1242
|
tool_choice: "auto",
|
|
1221
1243
|
...this.buildChatRequestParams(request),
|
|
1222
1244
|
stream: false
|
|
1223
|
-
}
|
|
1245
|
+
};
|
|
1246
|
+
const response = await this.client.chat.completions.create(toSdkParams(params), {
|
|
1224
1247
|
timeout: request.timeout ?? this.defaultTimeout,
|
|
1225
1248
|
// 非流式路径同样必须收 signal,否则 Ctrl+C 期间整个请求不可中断(见 chat() 上方注释)
|
|
1226
1249
|
signal: request.signal
|
|
@@ -1233,7 +1256,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1233
1256
|
const finishReason = firstChoice.finish_reason;
|
|
1234
1257
|
const usage = toUsage(response.usage);
|
|
1235
1258
|
const hasToolCalls = !!(message.tool_calls && message.tool_calls.length > 0);
|
|
1236
|
-
const reasoningContent = message
|
|
1259
|
+
const reasoningContent = readReasoningContent(message);
|
|
1237
1260
|
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
1238
1261
|
const toolCalls = message.tool_calls.map((tc) => {
|
|
1239
1262
|
const parsed = parseToolCallArguments(
|
|
@@ -1312,7 +1335,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1312
1335
|
const extraMessages = request._extraMessages ?? [];
|
|
1313
1336
|
const allMessages = [...baseMessages, ...extraMessages];
|
|
1314
1337
|
try {
|
|
1315
|
-
const
|
|
1338
|
+
const params = {
|
|
1316
1339
|
model: request.model,
|
|
1317
1340
|
messages: allMessages,
|
|
1318
1341
|
tools: openaiTools,
|
|
@@ -1320,7 +1343,8 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1320
1343
|
...this.buildChatRequestParams(request),
|
|
1321
1344
|
stream: true,
|
|
1322
1345
|
stream_options: { include_usage: true }
|
|
1323
|
-
}
|
|
1346
|
+
};
|
|
1347
|
+
const stream = await this.client.chat.completions.create(toSdkParams(params), {
|
|
1324
1348
|
timeout: request.timeout ?? this.defaultTimeout,
|
|
1325
1349
|
signal: request.signal
|
|
1326
1350
|
});
|
|
@@ -1438,9 +1462,11 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1438
1462
|
name: tc.name,
|
|
1439
1463
|
arguments: JSON.stringify(tc.arguments)
|
|
1440
1464
|
}
|
|
1441
|
-
}))
|
|
1465
|
+
})),
|
|
1466
|
+
// DeepSeek V4 thinking 模式严格校验:assistant 消息必须包含 reasoning_content
|
|
1467
|
+
// 字段(即使为空字符串也必须存在,否则 API 返回 400)
|
|
1468
|
+
reasoning_content: reasoningContent ?? ""
|
|
1442
1469
|
};
|
|
1443
|
-
assistantMsg.reasoning_content = reasoningContent ?? "";
|
|
1444
1470
|
const resultMsgs = results.map((r) => ({
|
|
1445
1471
|
role: "tool",
|
|
1446
1472
|
tool_call_id: r.callId,
|
|
@@ -1653,7 +1679,7 @@ var ZhipuProvider = class extends OpenAICompatibleProvider {
|
|
|
1653
1679
|
buildChatRequestParams(request) {
|
|
1654
1680
|
const params = super.buildChatRequestParams(request);
|
|
1655
1681
|
if (request.thinkingEffort && REASONING_EFFORT_MODELS.test(request.model)) {
|
|
1656
|
-
params
|
|
1682
|
+
params.reasoning_effort = request.thinkingEffort;
|
|
1657
1683
|
}
|
|
1658
1684
|
return params;
|
|
1659
1685
|
}
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
searchPersistentMemories,
|
|
12
12
|
touchMemoryReferences,
|
|
13
13
|
updateMemoryEntry
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RFSKPCYC.js";
|
|
15
15
|
import {
|
|
16
16
|
indexProject
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4DEMGCK4.js";
|
|
18
18
|
import {
|
|
19
19
|
hasSemanticIndex,
|
|
20
20
|
semanticSearch
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
runHook,
|
|
31
31
|
runLifecycleHooks,
|
|
32
32
|
runTool
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-L3CPM472.js";
|
|
34
34
|
import {
|
|
35
35
|
buildTruncatedArgumentsError,
|
|
36
36
|
getDangerLevel,
|
|
@@ -50,14 +50,14 @@ import {
|
|
|
50
50
|
} from "./chunk-4BKXL7SM.js";
|
|
51
51
|
import {
|
|
52
52
|
runTestsTool
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-SB4XONS4.js";
|
|
54
54
|
import {
|
|
55
55
|
CONFIG_DIR_NAME,
|
|
56
56
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
57
57
|
SUBAGENT_ALLOWED_TOOLS,
|
|
58
58
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
59
59
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-X3722RFA.js";
|
|
61
61
|
|
|
62
62
|
// src/tools/shell-pool.ts
|
|
63
63
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -339,6 +339,13 @@ function cleanupAllSessions() {
|
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
// src/core/tool-capable-provider.ts
|
|
343
|
+
function isToolCapableProvider(provider) {
|
|
344
|
+
if (!provider) return false;
|
|
345
|
+
const candidate = provider;
|
|
346
|
+
return typeof candidate.chatWithTools === "function" && typeof candidate.buildToolResultMessages === "function";
|
|
347
|
+
}
|
|
348
|
+
|
|
342
349
|
// src/tools/builtin/bash.ts
|
|
343
350
|
import { spawn as spawn3 } from "child_process";
|
|
344
351
|
import { existsSync as existsSync2, readdirSync, statSync } from "fs";
|
|
@@ -2945,7 +2952,7 @@ Do NOT split a long document into many write_file(append=true) calls. That patte
|
|
|
2945
2952
|
const mode = appendMode ? "appended" : "written";
|
|
2946
2953
|
void (async () => {
|
|
2947
2954
|
try {
|
|
2948
|
-
const { updateFile } = await import("./indexer-
|
|
2955
|
+
const { updateFile } = await import("./indexer-TNDWGFRI.js");
|
|
2949
2956
|
await updateFile(process.cwd(), filePath);
|
|
2950
2957
|
} catch {
|
|
2951
2958
|
}
|
|
@@ -5576,7 +5583,8 @@ async function runSubAgent(task, maxRounds, agentIndex, ctx, agent) {
|
|
|
5576
5583
|
if (!ctx.provider) {
|
|
5577
5584
|
throw new ToolError("spawn_agent", "provider not initialized (context not injected)");
|
|
5578
5585
|
}
|
|
5579
|
-
const
|
|
5586
|
+
const configured = agent.provider && ctx.providers?.has(agent.provider) ? ctx.providers.get(agent.provider) : void 0;
|
|
5587
|
+
const providerFromConfig = isToolCapableProvider(configured) ? configured : void 0;
|
|
5580
5588
|
const provider = providerFromConfig ?? ctx.provider;
|
|
5581
5589
|
const model = agent.model ?? (providerFromConfig?.info?.defaultModel ?? ctx.model);
|
|
5582
5590
|
const run = startAgentRun({
|
|
@@ -6995,6 +7003,7 @@ export {
|
|
|
6995
7003
|
cleanupRejectedTeeFile,
|
|
6996
7004
|
askUserContext,
|
|
6997
7005
|
googleSearchContext,
|
|
7006
|
+
isToolCapableProvider,
|
|
6998
7007
|
listAgentConfigs,
|
|
6999
7008
|
resolveAgentConfig,
|
|
7000
7009
|
listAgentRuns,
|