jinzd-ai-cli 0.4.266 → 0.4.268

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 (33) hide show
  1. package/dist/{batch-FQU6HK3Z.js → batch-2N2YMRX2.js} +2 -2
  2. package/dist/{chunk-QW76RX6G.js → chunk-2FQGMR34.js} +1 -1
  3. package/dist/{chunk-Y2X24VYB.js → chunk-74BK22BM.js} +4 -4
  4. package/dist/{chunk-TJNBSR3I.js → chunk-7US7K3CD.js} +1 -1
  5. package/dist/{chunk-FA3HGXXM.js → chunk-EPVJS4F6.js} +3 -1
  6. package/dist/{chunk-V4D7YD24.js → chunk-R7GERZDA.js} +145 -4
  7. package/dist/{chunk-GWOZET2E.js → chunk-RRQZRSXW.js} +1 -1
  8. package/dist/{chunk-LGJ7EX2F.js → chunk-UT2WAJJG.js} +1 -1
  9. package/dist/{chunk-CEJUB4YV.js → chunk-VGVKJTHF.js} +1 -1
  10. package/dist/{chunk-UCHND2K6.js → chunk-VNCBY4KY.js} +193 -2
  11. package/dist/{chunk-3O4VLKD4.js → chunk-WNG3YVZX.js} +1 -1
  12. package/dist/{chunk-N2E6GFLZ.js → chunk-WWLXW4SY.js} +1 -1
  13. package/dist/{chunk-LHY7ST6X.js → chunk-XDITAGE5.js} +1 -1
  14. package/dist/{chunk-FIDEG2PG.js → chunk-YLSM7RF6.js} +3 -3
  15. package/dist/{chunk-XEVURCAM.js → chunk-Z7CZ72RP.js} +3 -3
  16. package/dist/{ci-GZH3QMME.js → ci-3RWVJSZ3.js} +4 -4
  17. package/dist/{ci-format-VKP2MGYJ.js → ci-format-M6HVCXCG.js} +2 -2
  18. package/dist/{constants-ICAF6I3J.js → constants-G6VN7SJL.js} +1 -1
  19. package/dist/{doctor-cli-CO6BJWRW.js → doctor-cli-Y3SVVJBO.js} +4 -4
  20. package/dist/electron-server.js +915 -410
  21. package/dist/{hub-4APIRQ73.js → hub-5T5HKOAR.js} +1 -1
  22. package/dist/index.js +87 -134
  23. package/dist/{persistent-memory-YD3SHSUH.js → persistent-memory-XVSSR277.js} +2 -2
  24. package/dist/{persistent-memory-YPO25MOP.js → persistent-memory-YBWIZWQP.js} +2 -2
  25. package/dist/{pr-CDOPCAPK.js → pr-NF5IWLH3.js} +4 -4
  26. package/dist/{run-tests-QNNP2HCD.js → run-tests-33X3D7PV.js} +2 -2
  27. package/dist/{run-tests-4XRHKHN5.js → run-tests-Y44SCLIO.js} +2 -2
  28. package/dist/{server-B4A7LHZ5.js → server-3LERX42X.js} +5 -5
  29. package/dist/{server-53GM3CRH.js → server-NJ3ZNPQW.js} +114 -38
  30. package/dist/{task-orchestrator-WNV6PT6Z.js → task-orchestrator-JN2WFZSF.js} +5 -5
  31. package/dist/{usage-E3FEYSBU.js → usage-IFTNXTWC.js} +4 -6
  32. package/package.json +1 -1
  33. package/dist/chunk-YRD6M5XI.js +0 -149
@@ -13,23 +13,30 @@ import {
13
13
  TOKEN_EXPIRY_MS
14
14
  } from "./chunk-RYQBBEMM.js";
15
15
  import {
16
+ AUTO_COMPACT_INSTRUCTION,
16
17
  McpManager,
17
18
  SkillManager,
19
+ applyProfileCommand,
18
20
  applyThinkCommand,
19
21
  autoTrimSessionIfNeeded,
20
22
  buildInitPrompt,
23
+ buildSessionCostReport,
24
+ costSourceNote,
25
+ estimateConversationTokens,
26
+ evaluateContextPressure,
21
27
  loadDevState,
22
28
  persistToolRound,
23
29
  readGitDiff,
24
30
  scanDirTree,
25
31
  scanProject,
26
32
  setupProxy
27
- } from "./chunk-UCHND2K6.js";
33
+ } from "./chunk-VNCBY4KY.js";
28
34
  import {
35
+ CostTracker,
29
36
  computeCost,
30
37
  formatCost,
31
38
  getPricing
32
- } from "./chunk-YRD6M5XI.js";
39
+ } from "./chunk-R7GERZDA.js";
33
40
  import {
34
41
  buildReviewPrompt,
35
42
  buildSecurityReviewPrompt
@@ -68,7 +75,7 @@ import {
68
75
  spawnAgentContext,
69
76
  truncateOutput,
70
77
  undoStack
71
- } from "./chunk-Y2X24VYB.js";
78
+ } from "./chunk-74BK22BM.js";
72
79
  import {
73
80
  addMemoryEntry,
74
81
  clearMemoryEntries,
@@ -82,7 +89,7 @@ import {
82
89
  parseWritableScope,
83
90
  updateMemoryApproval,
84
91
  updateMemoryEntry
85
- } from "./chunk-3O4VLKD4.js";
92
+ } from "./chunk-WNG3YVZX.js";
86
93
  import "./chunk-GLSR2NR3.js";
87
94
  import "./chunk-UUSRWSSX.js";
88
95
  import "./chunk-CKH4KQ4E.js";
@@ -96,13 +103,13 @@ import {
96
103
  buildDoctorReport,
97
104
  formatDoctorReport,
98
105
  loadContextFiles
99
- } from "./chunk-FIDEG2PG.js";
106
+ } from "./chunk-YLSM7RF6.js";
100
107
  import {
101
108
  ProviderRegistry
102
109
  } from "./chunk-AUEX6RNY.js";
103
110
  import {
104
111
  ConfigManager
105
- } from "./chunk-CEJUB4YV.js";
112
+ } from "./chunk-VGVKJTHF.js";
106
113
  import {
107
114
  describePlugin,
108
115
  getActivePluginAssets,
@@ -117,7 +124,7 @@ import {
117
124
  runTool,
118
125
  setPluginEnabled,
119
126
  trustPlugin
120
- } from "./chunk-QW76RX6G.js";
127
+ } from "./chunk-2FQGMR34.js";
121
128
  import {
122
129
  CONTENT_ONLY_STREAM_REMINDER,
123
130
  TEE_FINAL_USER_NUDGE,
@@ -142,7 +149,7 @@ import {
142
149
  getGitRoot
143
150
  } from "./chunk-HOSJZMQS.js";
144
151
  import "./chunk-4BKXL7SM.js";
145
- import "./chunk-N2E6GFLZ.js";
152
+ import "./chunk-WWLXW4SY.js";
146
153
  import {
147
154
  AGENTIC_BEHAVIOR_GUIDELINE,
148
155
  AUTHOR,
@@ -158,7 +165,7 @@ import {
158
165
  SKILLS_DIR_NAME,
159
166
  VERSION,
160
167
  buildUserIdentityPrompt
161
- } from "./chunk-LGJ7EX2F.js";
168
+ } from "./chunk-UT2WAJJG.js";
162
169
  import "./chunk-6RPGQ5CG.js";
163
170
  import "./chunk-KHYD3WXE.js";
164
171
  import "./chunk-NYNSYLFY.js";
@@ -784,6 +791,12 @@ async function handlePlan(args, ctx) {
784
791
  } else if (sub === "execute") {
785
792
  ctx.planMode = false;
786
793
  ctx.send({ type: "info", message: "Plan mode OFF. Executing with all tools enabled." });
794
+ } else if (sub === "status" || sub === "show") {
795
+ ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
796
+ return;
797
+ } else if (sub !== void 0) {
798
+ ctx.send({ type: "error", message: `Unknown /plan option "${sub}" \u2014 expected execute | exit | status` });
799
+ return;
787
800
  } else {
788
801
  ctx.planMode = !ctx.planMode;
789
802
  ctx.send({ type: "info", message: `Plan mode: ${ctx.planMode ? "ON (read-only tools only)" : "OFF"}` });
@@ -832,7 +845,7 @@ Cache: write=${cacheCreate} read=${cacheRead}` : "";
832
845
  Cost: ${formatCost(cost)}` : "";
833
846
  let memoryLine = "";
834
847
  try {
835
- const { countPendingMemories } = await import("./persistent-memory-YD3SHSUH.js");
848
+ const { countPendingMemories } = await import("./persistent-memory-XVSSR277.js");
836
849
  const pending = countPendingMemories(ctx.config.getConfigDir());
837
850
  if (pending > 0) memoryLine = `
838
851
  Memory: \u26A0 ${pending} pending approval \u2014 see the Memory panel or /memory`;
@@ -1040,18 +1053,16 @@ async function handleExport(args, ctx) {
1040
1053
  }
1041
1054
  async function handleCost(_args, ctx) {
1042
1055
  const u = ctx.sessionTokenUsage;
1043
- const total = u.inputTokens + u.outputTokens + u.cacheCreationTokens + u.cacheReadTokens;
1044
- const cost = computeCost(ctx.currentProvider, ctx.currentModel, u);
1045
- let savings = null;
1046
- if (cost != null && u.cacheReadTokens > 0) {
1047
- const withoutCache = computeCost(ctx.currentProvider, ctx.currentModel, {
1048
- inputTokens: u.inputTokens + u.cacheReadTokens,
1049
- outputTokens: u.outputTokens,
1050
- cacheCreationTokens: u.cacheCreationTokens,
1051
- cacheReadTokens: 0
1052
- });
1053
- if (withoutCache != null) savings = withoutCache - cost;
1054
- }
1056
+ const report = buildSessionCostReport({
1057
+ provider: ctx.currentProvider,
1058
+ model: ctx.currentModel,
1059
+ usage: u,
1060
+ accruedUsd: ctx.sessionAccruedCostUsd,
1061
+ accrualIncomplete: ctx.sessionCostIncomplete
1062
+ });
1063
+ const total = report.totalTokens;
1064
+ const cost = report.cost;
1065
+ const savings = report.savings;
1055
1066
  const lines = [
1056
1067
  "\u{1F4B0} Session Cost & Token Usage",
1057
1068
  ` Provider : ${ctx.currentProvider}`,
@@ -1060,13 +1071,13 @@ async function handleCost(_args, ctx) {
1060
1071
  ` Output : ${u.outputTokens.toLocaleString()}`
1061
1072
  ];
1062
1073
  if (u.cacheCreationTokens > 0) lines.push(` Cache write : ${u.cacheCreationTokens.toLocaleString()}`);
1063
- if (u.cacheReadTokens > 0) {
1064
- const pct = Math.round(u.cacheReadTokens / (u.cacheReadTokens + u.inputTokens) * 100);
1065
- lines.push(` Cache read : ${u.cacheReadTokens.toLocaleString()} (${pct}% hit rate)`);
1074
+ if (report.cacheHitPct != null) {
1075
+ lines.push(` Cache read : ${u.cacheReadTokens.toLocaleString()} (${report.cacheHitPct}% hit rate)`);
1066
1076
  }
1067
1077
  lines.push(` Total tokens : ${total.toLocaleString()}`);
1068
1078
  if (cost != null) {
1069
- lines.push(` Cost : ${formatCost(cost)}`);
1079
+ const note = costSourceNote(report.costSource);
1080
+ lines.push(` Cost : ${formatCost(cost)}${note ? ` ${note}` : ""}`);
1070
1081
  if (savings != null && savings > 0) {
1071
1082
  lines.push(` Cache savings : -${formatCost(savings)} (vs no cache)`);
1072
1083
  }
@@ -1647,7 +1658,7 @@ async function handleTest(args, ctx) {
1647
1658
  const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
1648
1659
  testArgs = isCommand ? { command: argStr } : { filter: argStr };
1649
1660
  }
1650
- const runTests = ctx.runTests ?? (await import("./run-tests-QNNP2HCD.js")).executeTests;
1661
+ const runTests = ctx.runTests ?? (await import("./run-tests-33X3D7PV.js")).executeTests;
1651
1662
  const report = await runTests(testArgs);
1652
1663
  ctx.send({ type: "info", message: report });
1653
1664
  } catch (err) {
@@ -1905,7 +1916,7 @@ async function handleMemory(args, ctx) {
1905
1916
  ctx.handleMemoryManage(sub, args[1], sub === "expire" ? args[2] : void 0);
1906
1917
  } else if (sub === "export") {
1907
1918
  if (args[1] === "md") {
1908
- const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-YD3SHSUH.js");
1919
+ const { exportMemoryEntries: exportMemoryEntries2 } = await import("./persistent-memory-XVSSR277.js");
1909
1920
  ctx.send({
1910
1921
  type: "export_data",
1911
1922
  format: "md",
@@ -2017,6 +2028,18 @@ async function handleBug(_args, ctx) {
2017
2028
  ];
2018
2029
  ctx.send({ type: "info", message: lines.join("\n") });
2019
2030
  }
2031
+ async function handleProfile(args, ctx) {
2032
+ const outcome = applyProfileCommand(args, ctx.config.get("userProfile") ?? {});
2033
+ if (outcome.profile) {
2034
+ ctx.config.set("userProfile", outcome.profile);
2035
+ ctx.config.save();
2036
+ }
2037
+ const lines = [outcome.summary];
2038
+ for (const [label, value] of outcome.rows) lines.push(` ${label}: ${value}`);
2039
+ for (const line of outcome.details) lines.push(line);
2040
+ ctx.send({ type: outcome.isError ? "error" : "info", message: lines.join("\n") });
2041
+ if (outcome.changed) ctx.sendStatus();
2042
+ }
2020
2043
 
2021
2044
  // src/web/commands/agent-commands.ts
2022
2045
  async function handleAuto(args, ctx) {
@@ -2060,6 +2083,17 @@ async function handlePermissions(args, ctx) {
2060
2083
  }
2061
2084
  async function handleYolo(args, ctx) {
2062
2085
  const sub = args[0]?.toLowerCase();
2086
+ if (sub === "status") {
2087
+ ctx.send({
2088
+ type: "info",
2089
+ message: `YOLO mode: ${ctx.toolExecutor.sessionAutoApprove ? "ON (write tools auto-approved)" : "OFF"}`
2090
+ });
2091
+ return;
2092
+ }
2093
+ if (sub !== void 0 && sub !== "on" && sub !== "off") {
2094
+ ctx.send({ type: "error", message: `Unknown /yolo option "${sub}" \u2014 expected on | off | status` });
2095
+ return;
2096
+ }
2063
2097
  if (sub === "off") {
2064
2098
  ctx.toolExecutor.sessionAutoApprove = false;
2065
2099
  ctx.send({ type: "info", message: "\u{1F512} Auto-approve disabled \u2014 confirmations restored for this session." });
@@ -2271,14 +2305,17 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2271
2305
  }
2272
2306
 
2273
2307
  // src/web/session-handler.ts
2274
- var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Set([
2275
- "copy",
2276
- "paste",
2277
- "exit",
2278
- "quit",
2279
- "snapshot",
2280
- "hooks",
2281
- "hook"
2308
+ var CLI_ONLY_WEB_COMMANDS = /* @__PURE__ */ new Map([
2309
+ ["copy", "It copies to the terminal clipboard; use your browser/OS copy instead."],
2310
+ ["paste", "It reads the terminal clipboard; paste directly into the composer instead."],
2311
+ ["exit", "Close the browser tab to end this Web session."],
2312
+ ["quit", "Close the browser tab to end this Web session."],
2313
+ ["snapshot", "Dev-state snapshots are written when the terminal REPL exits."],
2314
+ ["hooks", "Hook trust is granted per machine from the terminal."],
2315
+ ["hook", "Hook trust is granted per machine from the terminal."],
2316
+ // 以下两条并非「终端才有意义」,而是 Web 侧尚未实现——如实说明,别假装是设计。
2317
+ ["route", "Smart model routing is not applied to Web sessions yet (config.routing is REPL-only)."],
2318
+ ["security", "Redaction status and toggles are terminal-only for now; /status shows the current profile."]
2282
2319
  ]);
2283
2320
  var webCommandHandlers = {
2284
2321
  provider: handleProvider,
@@ -2314,6 +2351,7 @@ var webCommandHandlers = {
2314
2351
  config: handleConfig,
2315
2352
  doctor: handleDoctor,
2316
2353
  bug: handleBug,
2354
+ profile: handleProfile,
2317
2355
  auto: handleAuto,
2318
2356
  permissions: handlePermissions,
2319
2357
  yolo: handleYolo,
@@ -2326,6 +2364,7 @@ var webCommandHandlers = {
2326
2364
  var SessionHandler = class {
2327
2365
  ws;
2328
2366
  config;
2367
+ costTracker;
2329
2368
  providers;
2330
2369
  sessions;
2331
2370
  toolRegistry;
@@ -2339,12 +2378,22 @@ var SessionHandler = class {
2339
2378
  runtimeThinkingEffort = null;
2340
2379
  sessionTokenUsage = { inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
2341
2380
  unknownPricingWarnings = /* @__PURE__ */ new Set();
2381
+ /**
2382
+ * 本会话按**调用时刻**费率累计的花费(美元)。
2383
+ * 审计 P2-02 第二批:Web 端此前根本不给 CostTracker 记账,aicli usage 与
2384
+ * monthlyBudget 完全看不到 Web UI 的开销;顺带补上 P3-01 的记账口径。
2385
+ */
2386
+ sessionAccruedCostUsd = 0;
2387
+ sessionCostIncomplete = false;
2342
2388
  /** Accumulate a TokenUsage (with optional cache fields) into sessionTokenUsage. */
2343
2389
  addWebSessionUsage(u) {
2344
2390
  this.sessionTokenUsage.inputTokens += u.inputTokens;
2345
2391
  this.sessionTokenUsage.outputTokens += u.outputTokens;
2346
2392
  this.sessionTokenUsage.cacheCreationTokens += u.cacheCreationTokens ?? 0;
2347
2393
  this.sessionTokenUsage.cacheReadTokens += u.cacheReadTokens ?? 0;
2394
+ const priced = this.costTracker.addCost(this.currentProvider, this.currentModel, u);
2395
+ if (priced === null) this.sessionCostIncomplete = true;
2396
+ else this.sessionAccruedCostUsd += priced;
2348
2397
  const totalTokens = u.inputTokens + u.outputTokens + (u.cacheCreationTokens ?? 0) + (u.cacheReadTokens ?? 0);
2349
2398
  if (totalTokens > 0 && !getPricing(this.currentProvider, this.currentModel)) {
2350
2399
  const key = `${this.currentProvider}/${this.currentModel}`;
@@ -2356,6 +2405,8 @@ var SessionHandler = class {
2356
2405
  }
2357
2406
  resetWebSessionUsage() {
2358
2407
  this.sessionTokenUsage = { inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
2408
+ this.sessionAccruedCostUsd = 0;
2409
+ this.sessionCostIncomplete = false;
2359
2410
  }
2360
2411
  abortController = null;
2361
2412
  userInterjection = null;
@@ -2389,6 +2440,7 @@ var SessionHandler = class {
2389
2440
  constructor(ws, shared) {
2390
2441
  this.ws = ws;
2391
2442
  this.config = shared.config;
2443
+ this.costTracker = shared.costTracker;
2392
2444
  this.providers = shared.providers;
2393
2445
  this.sessions = shared.sessions;
2394
2446
  this.toolRegistry = shared.toolRegistry;
@@ -2807,6 +2859,7 @@ var SessionHandler = class {
2807
2859
  } else {
2808
2860
  await this.handleChatSimple(provider, session.messages);
2809
2861
  }
2862
+ await this.checkContextPressure();
2810
2863
  } catch (err) {
2811
2864
  const parts = [];
2812
2865
  let current = err;
@@ -3325,10 +3378,11 @@ ${summaryContent}`,
3325
3378
  }
3326
3379
  // ── Commands ─────────────────────────────────────────────────────
3327
3380
  async handleCommand(name, args) {
3328
- if (CLI_ONLY_WEB_COMMANDS.has(name)) {
3381
+ const cliOnlyReason = CLI_ONLY_WEB_COMMANDS.get(name);
3382
+ if (cliOnlyReason) {
3329
3383
  this.send({
3330
3384
  type: "error",
3331
- message: `/${name} is only available in the terminal REPL. Run \`aicli\` in a terminal and use /${name} there.`
3385
+ message: `/${name} is not available in the Web UI. ${cliOnlyReason}`
3332
3386
  });
3333
3387
  return;
3334
3388
  }
@@ -3339,6 +3393,25 @@ ${summaryContent}`,
3339
3393
  this.send({ type: "error", message: `Unknown command: /${name}. Type /help for available commands.` });
3340
3394
  }
3341
3395
  }
3396
+ /**
3397
+ * 到达上下文压力阈值时自动压缩(与 REPL 同一判据,见 core/context-pressure.ts)。
3398
+ * 上下文窗口未知时不动——不基于猜测改用户的对话历史。
3399
+ */
3400
+ async checkContextPressure() {
3401
+ const contextWindow = this.getContextWindowSize();
3402
+ const session = this.sessions.current;
3403
+ const pressure = evaluateContextPressure({
3404
+ autoCompactEnabled: this.config.get("autoCompact") === true,
3405
+ estimatedTokens: contextWindow > 0 && session ? estimateConversationTokens({ systemPrompt: this.activeSystemPrompt, messages: session.messages }) : 0,
3406
+ contextWindow
3407
+ });
3408
+ if (!pressure.shouldCompact) return;
3409
+ this.send({
3410
+ type: "info",
3411
+ message: `\u26A0 Context pressure: ~${pressure.percent}% of the ${contextWindow.toLocaleString()}-token window used. Auto-compacting\u2026`
3412
+ });
3413
+ await this.compactSession(AUTO_COMPACT_INSTRUCTION);
3414
+ }
3342
3415
  async compactSession(instruction) {
3343
3416
  const session = this.sessions.current;
3344
3417
  if (!session || session.messages.length < 6) {
@@ -3902,6 +3975,7 @@ async function startWebServer(options = {}) {
3902
3975
  }
3903
3976
  const shared = {
3904
3977
  config,
3978
+ costTracker: new CostTracker(config.getConfigDir()),
3905
3979
  providers,
3906
3980
  sessions,
3907
3981
  toolRegistry,
@@ -4168,6 +4242,8 @@ async function startWebServer(options = {}) {
4168
4242
  const userSessions = new SessionManager(userConfig);
4169
4243
  const userShared = {
4170
4244
  config: userConfig,
4245
+ // 每用户各自的 config 目录 → 各自的 cost-history.json
4246
+ costTracker: new CostTracker(userConfig.getConfigDir()),
4171
4247
  providers,
4172
4248
  // Shared — providers re-read API keys per call
4173
4249
  sessions: userSessions,
@@ -3,8 +3,8 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-Y2X24VYB.js";
7
- import "./chunk-3O4VLKD4.js";
6
+ } from "./chunk-74BK22BM.js";
7
+ import "./chunk-WNG3YVZX.js";
8
8
  import "./chunk-GLSR2NR3.js";
9
9
  import "./chunk-UUSRWSSX.js";
10
10
  import "./chunk-CKH4KQ4E.js";
@@ -12,7 +12,7 @@ import "./chunk-BXP6YZ2P.js";
12
12
  import "./chunk-5C76XDDF.js";
13
13
  import {
14
14
  runTool
15
- } from "./chunk-QW76RX6G.js";
15
+ } from "./chunk-2FQGMR34.js";
16
16
  import {
17
17
  getDangerLevel,
18
18
  runLeanAgentLoop
@@ -20,10 +20,10 @@ import {
20
20
  import "./chunk-TU3L3PW7.js";
21
21
  import "./chunk-HOSJZMQS.js";
22
22
  import "./chunk-4BKXL7SM.js";
23
- import "./chunk-N2E6GFLZ.js";
23
+ import "./chunk-WWLXW4SY.js";
24
24
  import {
25
25
  SUBAGENT_ALLOWED_TOOLS
26
- } from "./chunk-LGJ7EX2F.js";
26
+ } from "./chunk-UT2WAJJG.js";
27
27
  import "./chunk-6RPGQ5CG.js";
28
28
  import "./chunk-KHYD3WXE.js";
29
29
  import "./chunk-NYNSYLFY.js";
@@ -1,16 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- CostTracker
4
- } from "./chunk-V4D7YD24.js";
5
- import {
3
+ CostTracker,
6
4
  formatCost,
7
5
  getPricing
8
- } from "./chunk-YRD6M5XI.js";
6
+ } from "./chunk-R7GERZDA.js";
9
7
  import {
10
8
  ConfigManager
11
- } from "./chunk-CEJUB4YV.js";
9
+ } from "./chunk-VGVKJTHF.js";
12
10
  import "./chunk-TU3L3PW7.js";
13
- import "./chunk-LGJ7EX2F.js";
11
+ import "./chunk-UT2WAJJG.js";
14
12
  import "./chunk-IW3Q7AE5.js";
15
13
 
16
14
  // src/cli/usage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.266",
3
+ "version": "0.4.268",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,149 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/core/pricing.ts
4
- var DEEPSEEK_CNY_PER_USD = 6.9;
5
- var DEEPSEEK_TIME_PRICING_EFFECTIVE_AT = /* @__PURE__ */ new Date("2026-08-16T16:00:00.000Z");
6
- function deepSeekCnyPricing(cacheRead, input, output) {
7
- return {
8
- cacheRead: cacheRead / DEEPSEEK_CNY_PER_USD,
9
- input: input / DEEPSEEK_CNY_PER_USD,
10
- output: output / DEEPSEEK_CNY_PER_USD
11
- };
12
- }
13
- function getDeepSeekV4Pricing(model, at) {
14
- const isPro = model.startsWith("deepseek-v4-pro");
15
- const isFlash = model.startsWith("deepseek-v4-flash");
16
- if (!isPro && !isFlash) return null;
17
- if (at < DEEPSEEK_TIME_PRICING_EFFECTIVE_AT) {
18
- return isPro ? deepSeekCnyPricing(0.025, 3, 6) : deepSeekCnyPricing(0.02, 1, 2);
19
- }
20
- const beijingHour = (at.getUTCHours() + 8) % 24;
21
- const isPeak = beijingHour >= 9 && beijingHour < 12 || beijingHour >= 14 && beijingHour < 18;
22
- if (isPro) {
23
- return isPeak ? deepSeekCnyPricing(0.3, 9, 27) : deepSeekCnyPricing(0.15, 4.5, 13.5);
24
- }
25
- return isPeak ? deepSeekCnyPricing(0.1, 3, 9) : deepSeekCnyPricing(0.05, 1.5, 4.5);
26
- }
27
- var PRICING_TABLE = {
28
- // ── Anthropic Claude ──────────────────────────────────────────
29
- "claude-opus-4-8": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
30
- "claude-opus-4-7": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
31
- "claude-opus-4-6": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
32
- "claude-opus-4-5": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
33
- "claude-sonnet-4-6": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
34
- "claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
35
- "claude-haiku-4-5-20251001": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
36
- "claude-haiku-4-5": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
37
- // Legacy Claude 3.x families (prefix fallback handles minor date suffixes)
38
- "claude-3-5-sonnet": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
39
- "claude-3-5-haiku": { input: 0.8, output: 4, cacheWrite: 1, cacheRead: 0.08 },
40
- "claude-3-opus": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
41
- // ── OpenAI ────────────────────────────────────────────────────
42
- // GAP (v0.4.184): the GPT-5 family (gpt-5, gpt-5-mini/nano, gpt-5.4, gpt-5.4-pro)
43
- // and o4-mini are in the provider's model list but have NO verified pricing yet —
44
- // left unpriced on purpose so `aicli usage` shows "—" (unknown) rather than a
45
- // deceptive $0.00. Add real rates when confirmed from the official pricing page.
46
- "gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25 },
47
- "gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075 },
48
- "gpt-4-turbo": { input: 10, output: 30 },
49
- "gpt-4": { input: 30, output: 60 },
50
- "gpt-4.1": { input: 2, output: 8, cacheRead: 0.5 },
51
- "gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1 },
52
- "gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025 },
53
- "o1": { input: 15, output: 60, cacheRead: 7.5 },
54
- "o1-mini": { input: 3, output: 12, cacheRead: 1.5 },
55
- "o3": { input: 10, output: 40, cacheRead: 2.5 },
56
- "o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55 },
57
- // ── Google Gemini ─────────────────────────────────────────────
58
- "gemini-2.5-pro": { input: 1.25, output: 10 },
59
- "gemini-2.5-flash": { input: 0.3, output: 2.5 },
60
- "gemini-2.0-flash": { input: 0.1, output: 0.4 },
61
- "gemini-1.5-pro": { input: 1.25, output: 5 },
62
- "gemini-1.5-flash": { input: 0.075, output: 0.3 },
63
- // ── DeepSeek ──────────────────────────────────────────────────
64
- // V4 family (2026-04-23+):1M context, Thinking / Non-Thinking dual-mode, 384K max output
65
- // 费率 2026-08-01 对 api-docs.deepseek.com/quick_start/pricing 官方 USD 表逐项核对。
66
- // 修正前 pro 三项整齐高 4×(官方降过价未跟)、flash cacheRead 高 10×(像是按 input 的
67
- // 20% 拍脑袋而非抄文档)——`aicli usage` 因此系统性高报 DeepSeek 成本。
68
- // 待办:官方已公告峰谷定价(北京时间 9-12 点、14-18 点为平时 2 倍),本表仍是单一费率,
69
- // 届时高峰时段会低报;等该策略实际生效后再决定是否引入时段维度。
70
- // Legacy aliases:retires 2026-07-24 UTC 15:59,官方 route 到 V4 Flash。
71
- // 这几条只服务历史 session 的成本回算,保留当时的费率口径,不随现价改动。
72
- "deepseek-chat": { input: 0.14, output: 0.28, cacheRead: 0.028 },
73
- "deepseek-reasoner": { input: 0.14, output: 0.28, cacheRead: 0.028 },
74
- "deepseek-v3": { input: 0.27, output: 1.1, cacheRead: 0.07 },
75
- // ── Moonshot Kimi ─────────────────────────────────────────────
76
- "moonshot-v1-8k": { input: 0.17, output: 0.17 },
77
- "moonshot-v1-32k": { input: 0.33, output: 0.33 },
78
- "moonshot-v1-128k": { input: 0.83, output: 0.83 },
79
- "kimi-k2": { input: 0.6, output: 2.5 },
80
- "kimi-latest": { input: 0.6, output: 2.5 },
81
- // Kimi K3(2026-07 旗舰,1M 上下文)官方定价 platform.kimi.ai/pricing/chat-k3:
82
- // 输入 cache-miss $3.00 / cache-hit $0.30,输出 $15.00(/MTok)。
83
- "kimi-k3": { input: 3, output: 15, cacheRead: 0.3 },
84
- // ── Zhipu GLM ─────────────────────────────────────────────────
85
- "glm-4-plus": { input: 0.7, output: 0.7 },
86
- "glm-4": { input: 0.14, output: 0.14 },
87
- "glm-4-flash": { input: 0, output: 0 },
88
- "glm-4.5": { input: 0.29, output: 1.14 },
89
- "glm-4.6": { input: 0.6, output: 2.2 },
90
- "glm-4.6v": { input: 0.6, output: 2.2 },
91
- "glm-5": { input: 0.85, output: 2.85 },
92
- // GLM-5.2(2026-06)官方直连 API 定价 $1.40 / $4.40。
93
- "glm-5.2": { input: 1.4, output: 4.4 },
94
- // GLM-5V-Turbo(2026-04 视觉编程旗舰)官方直连 API 定价 $1.20 / $4.00。
95
- "glm-5v-turbo": { input: 1.2, output: 4 },
96
- "glm-5.1": { input: 0.95, output: 3.15 },
97
- "glm-5.1-reasoning": { input: 1.4, output: 4.4 },
98
- "glm-5.1-air": { input: 0.4, output: 1.2 },
99
- "glm-z1": { input: 0.5, output: 1.5 },
100
- "glm-z1-air": { input: 0.2, output: 0.6 },
101
- "glm-z1-flash": { input: 0, output: 0 }
102
- // ── MiniMax (海螺) ────────────────────────────────────────────
103
- // GAP (v0.4.184): MiniMax-M3 / M2.x are unpriced — no verified rate anchor yet.
104
- // Unpriced → `aicli usage` shows "—" (unknown), not a false $0.00. Add when confirmed.
105
- // ── OpenRouter (pass-through — actual cost depends on underlying model) ──
106
- // Left empty by design: model IDs are "vendor/model" (e.g. anthropic/claude-sonnet-4)
107
- // and the real price is set by the underlying model + OpenRouter markup, not statically
108
- // resolvable here. Shows "—" (unknown) in `aicli usage`.
109
- // ── Ollama (local, zero cost) ─────────────────────────────────
110
- // Handled via provider check below (FREE_PROVIDERS → genuine $0.00, not "unknown").
111
- };
112
- var FREE_PROVIDERS = /* @__PURE__ */ new Set(["ollama"]);
113
- function getPricing(provider, model, at = /* @__PURE__ */ new Date()) {
114
- if (FREE_PROVIDERS.has(provider.toLowerCase())) {
115
- return { input: 0, output: 0 };
116
- }
117
- const key = model.toLowerCase();
118
- if (provider.toLowerCase() === "deepseek") {
119
- const dynamicPricing = getDeepSeekV4Pricing(key, at);
120
- if (dynamicPricing) return dynamicPricing;
121
- }
122
- if (PRICING_TABLE[key]) return PRICING_TABLE[key];
123
- const keys = Object.keys(PRICING_TABLE).sort((a, b) => b.length - a.length);
124
- for (const k of keys) {
125
- if (key.startsWith(k)) return PRICING_TABLE[k];
126
- }
127
- return null;
128
- }
129
- function computeCost(provider, model, usage, at = /* @__PURE__ */ new Date()) {
130
- const p = getPricing(provider, model, at);
131
- if (!p) return null;
132
- const input = usage.inputTokens * p.input;
133
- const output = usage.outputTokens * p.output;
134
- const cacheWrite = (usage.cacheCreationTokens ?? 0) * (p.cacheWrite ?? p.input);
135
- const cacheRead = (usage.cacheReadTokens ?? 0) * (p.cacheRead ?? p.input);
136
- return (input + output + cacheWrite + cacheRead) / 1e6;
137
- }
138
- function formatCost(amount) {
139
- if (amount === 0) return "$0.0000";
140
- if (amount < 0.01) return `$${amount.toFixed(4)}`;
141
- if (amount < 1) return `$${amount.toFixed(3)}`;
142
- return `$${amount.toFixed(2)}`;
143
- }
144
-
145
- export {
146
- getPricing,
147
- computeCost,
148
- formatCost
149
- };