jinzd-ai-cli 0.4.325 → 0.4.327

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 (37) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/{batch-BGKTM75D.js → batch-NBI46MI4.js} +6 -4
  4. package/dist/{chunk-PIX4ZPFB.js → chunk-AVVT7ZZT.js} +129 -72
  5. package/dist/{chunk-NFPJ6KUU.js → chunk-BRZZ3QAI.js} +23 -5
  6. package/dist/{chunk-TJFHBYQ3.js → chunk-C2625RDR.js} +1 -1
  7. package/dist/{chunk-N6QFHXSF.js → chunk-C3EFGIJY.js} +34 -2
  8. package/dist/{chunk-PXJ3XVR5.js → chunk-CLGEU35T.js} +1 -1
  9. package/dist/{chunk-NBNRQ44O.js → chunk-HN5A5ZXX.js} +1 -1
  10. package/dist/{chunk-GCYH5WOZ.js → chunk-I7J7E7OB.js} +1 -1
  11. package/dist/{chunk-3ALMUKHF.js → chunk-KIE2KL2R.js} +4 -4
  12. package/dist/{chunk-5BS2NVSB.js → chunk-L3KXGINR.js} +4 -4
  13. package/dist/{chunk-CVWR3VYH.js → chunk-NFA6OCYA.js} +1 -1
  14. package/dist/{chunk-KS6RNA4E.js → chunk-NW3X6KQR.js} +1 -1
  15. package/dist/{chunk-C52FQ3ZE.js → chunk-RE72FGOG.js} +14 -11
  16. package/dist/{chunk-NI7YIDLF.js → chunk-URTVV3CB.js} +1 -1
  17. package/dist/{chunk-GVVYQJYF.js → chunk-YHTEI5KL.js} +4 -4
  18. package/dist/{chunk-WDD76ALZ.js → chunk-ZAZUWQBG.js} +1 -1
  19. package/dist/{ci-OE7Q3UOI.js → ci-XDUIRFJL.js} +5 -5
  20. package/dist/{ci-format-OWSFR34D.js → ci-format-DRD4BRGP.js} +2 -2
  21. package/dist/{constants-74TAAY4L.js → constants-NZVTDFL4.js} +1 -1
  22. package/dist/{constants-W2CH36YR.js → constants-QFXJCLTM.js} +1 -1
  23. package/dist/{doctor-cli-6C3WJTL5.js → doctor-cli-Z2Y4MWLK.js} +5 -5
  24. package/dist/electron-server.js +200 -92
  25. package/dist/{hub-RHMDL74E.js → hub-OE7M7DRD.js} +1 -1
  26. package/dist/index.js +21 -20
  27. package/dist/{persistent-memory-S2QLVL43.js → persistent-memory-EWDVXYTZ.js} +2 -2
  28. package/dist/{persistent-memory-OAFPFGKB.js → persistent-memory-Q34UVU4P.js} +2 -2
  29. package/dist/{pr-5PMXXHH6.js → pr-XWYKWZ2C.js} +5 -5
  30. package/dist/{run-tests-7AOMBU2D.js → run-tests-6EB6ABYH.js} +2 -2
  31. package/dist/{run-tests-W773M3KK.js → run-tests-WUN5OEU5.js} +2 -2
  32. package/dist/{server-SK4JQWT5.js → server-KQBLT4EX.js} +17 -16
  33. package/dist/{server-O75UHHR7.js → server-N7GH5D3I.js} +5 -5
  34. package/dist/{task-orchestrator-7H7UYCU7.js → task-orchestrator-MWWHWMBT.js} +5 -5
  35. package/dist/{usage-F6BD7DHL.js → usage-VFQINJ7I.js} +3 -3
  36. package/dist/wasm/web-tree-sitter.wasm +0 -0
  37. package/package.json +15 -15
package/README.md CHANGED
@@ -129,7 +129,7 @@ aicli user delete x # Delete user
129
129
 
130
130
  | Provider | Models | Get API Key |
131
131
  |----------|--------|-------------|
132
- | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
132
+ | **Claude** | Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5 (+ legacy Opus 4.6, Haiku 4.5) | [console.anthropic.com](https://console.anthropic.com) |
133
133
  | **Gemini** | 2.5 Pro, 2.5 Flash | [aistudio.google.com](https://aistudio.google.com) |
134
134
  | **DeepSeek** | deepseek-flash (default, multimodal), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
135
135
  | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
package/README.zh-CN.md CHANGED
@@ -117,7 +117,7 @@ aicli user delete x # 删除用户
117
117
 
118
118
  | Provider | 模型 | 获取 API Key |
119
119
  |----------|------|-------------|
120
- | **Claude** | Opus 4, Sonnet 4, Haiku 4 | [console.anthropic.com](https://console.anthropic.com) |
120
+ | **Claude** | Fable 5.1、Opus 5.5、Sonnet 5.5、Haiku 5.5(另保留旧版 Opus 4.6、Haiku 4.5) | [console.anthropic.com](https://console.anthropic.com) |
121
121
  | **Gemini** | 2.5 Pro, 2.5 Flash | [aistudio.google.com](https://aistudio.google.com) |
122
122
  | **DeepSeek** | deepseek-flash(默认,多模态), deepseek-v4-pro | [platform.deepseek.com](https://platform.deepseek.com) |
123
123
  | **OpenAI** | GPT-5.4, GPT-5, GPT-4.1, o3, o4-mini | [platform.openai.com](https://platform.openai.com) |
@@ -4,12 +4,12 @@ import {
4
4
  } from "./chunk-RS7SKYTS.js";
5
5
  import {
6
6
  ConfigManager
7
- } from "./chunk-N6QFHXSF.js";
7
+ } from "./chunk-C3EFGIJY.js";
8
8
  import "./chunk-TU3L3PW7.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
11
  } from "./chunk-BMLQPSHP.js";
12
- import "./chunk-CVWR3VYH.js";
12
+ import "./chunk-NFA6OCYA.js";
13
13
 
14
14
  // src/cli/batch.ts
15
15
  import Anthropic from "@anthropic-ai/sdk";
@@ -90,7 +90,7 @@ function getClaudeClient(config) {
90
90
  }
91
91
  function getDefaultModel(config) {
92
92
  const models = config.get("defaultModels");
93
- return models?.claude ?? "claude-sonnet-4-5-20250929";
93
+ return models?.claude ?? "claude-sonnet-5-5";
94
94
  }
95
95
  async function cmdSubmit(inputFile, options = {}) {
96
96
  const config = new ConfigManager();
@@ -110,7 +110,9 @@ async function cmdSubmit(inputFile, options = {}) {
110
110
  custom_id: r.customId,
111
111
  params: {
112
112
  model: r.model ?? defaultModel,
113
- max_tokens: r.maxTokens ?? 4096,
113
+ // 默认模型 Sonnet 5.5 默认就在思考,思考计入 max_tokens;4096 容易被思考吃光、正文为空。
114
+ // 只按实际产出计费,上限放宽不增加成本(Batches 不受 SDK 非流式 21333 的客户端校验约束)
115
+ max_tokens: r.maxTokens ?? 16e3,
114
116
  messages: r.messages,
115
117
  ...r.system ? { system: r.system } : {}
116
118
  }
@@ -13,6 +13,9 @@ import {
13
13
  import {
14
14
  atomicWriteFileSync
15
15
  } from "./chunk-BMLQPSHP.js";
16
+ import {
17
+ DEFAULT_MAX_TOKENS
18
+ } from "./chunk-NFA6OCYA.js";
16
19
 
17
20
  // src/providers/claude.ts
18
21
  import Anthropic from "@anthropic-ai/sdk";
@@ -41,6 +44,10 @@ var BaseProvider = class {
41
44
  get supportsReasoningEffort() {
42
45
  return false;
43
46
  }
47
+ /** 该模型能否关掉思考。默认能;Claude Opus 5.5 / Fable 5.x 关不掉(见 claude-models.ts) */
48
+ canDisableThinking(_model) {
49
+ return true;
50
+ }
44
51
  /**
45
52
  * 将 Message[] 转换为 OpenAI API 格式的消息数组。
46
53
  * content 为 string 时直接传递;为 MessageContentPart[] 时保留数组格式(vision 请求)。
@@ -118,6 +125,75 @@ function describeNetworkFailure(err, ctx = {}) {
118
125
  return { code, address, transient, message: parts.join(" ") };
119
126
  }
120
127
 
128
+ // src/providers/claude-models.ts
129
+ var DISABLE_BY_MODEL = [
130
+ [/^claude-sonnet-5-5/, { type: "between_tools" }],
131
+ [/^claude-sonnet-5(?!-\d)/, { type: "disabled" }],
132
+ [/^claude-opus-5(?!-\d)/, { type: "disabled" }],
133
+ [/^claude-haiku-5-5/, { type: "disabled" }]
134
+ ];
135
+ function claudeThinkingStyle(model) {
136
+ if (/^claude-(?:opus|sonnet|haiku)-4-5|^claude-3/.test(model)) return "manual";
137
+ if (/^claude-(?:opus-4-[678]|sonnet-4-6)/.test(model)) return "adaptive-optin";
138
+ return "adaptive-default";
139
+ }
140
+ function claudeAcceptsTemperature(model) {
141
+ return /^claude-(?:opus|sonnet|haiku)-4-[56]|^claude-3/.test(model);
142
+ }
143
+ function claudeDisableThinking(model) {
144
+ if (claudeThinkingStyle(model) !== "adaptive-default") return null;
145
+ for (const [re, param] of DISABLE_BY_MODEL) if (re.test(model)) return param;
146
+ return null;
147
+ }
148
+ function claudeCanDisableThinking(model) {
149
+ return claudeThinkingStyle(model) !== "adaptive-default" || claudeDisableThinking(model) !== null;
150
+ }
151
+ var MANUAL_BUDGET = {
152
+ low: 4096,
153
+ high: 16e3,
154
+ max: 32e3
155
+ };
156
+ var THINKING_MAX_TOKENS_STREAM = 32e3;
157
+ var THINKING_MAX_TOKENS_NONSTREAM = 16e3;
158
+ var NONSTREAM_SDK_LIMIT = 21333;
159
+ function buildClaudeRequestParams(request, streaming) {
160
+ const model = request.model;
161
+ const style = claudeThinkingStyle(model);
162
+ const wantThinking = request.thinking === true;
163
+ let thinking;
164
+ let outputConfig;
165
+ let maxTokens = request.maxTokens ?? DEFAULT_MAX_TOKENS;
166
+ const thinkingActive = wantThinking || style === "adaptive-default" && claudeDisableThinking(model) === null;
167
+ if (thinkingActive && maxTokens === DEFAULT_MAX_TOKENS) {
168
+ maxTokens = streaming ? THINKING_MAX_TOKENS_STREAM : THINKING_MAX_TOKENS_NONSTREAM;
169
+ }
170
+ if (wantThinking) {
171
+ if (style === "manual") {
172
+ let budget = Math.max(
173
+ request.thinkingBudget ?? (request.thinkingEffort ? MANUAL_BUDGET[request.thinkingEffort] : 1e4),
174
+ 1024
175
+ );
176
+ if (budget >= maxTokens) maxTokens = budget + 4096;
177
+ if (!streaming && maxTokens > NONSTREAM_SDK_LIMIT) {
178
+ maxTokens = NONSTREAM_SDK_LIMIT;
179
+ budget = Math.max(1024, Math.min(budget, maxTokens - 4096));
180
+ }
181
+ thinking = { type: "enabled", budget_tokens: budget };
182
+ } else {
183
+ thinking = { type: "adaptive", display: "summarized" };
184
+ outputConfig = { effort: request.thinkingEffort ?? "high" };
185
+ }
186
+ } else if (style === "adaptive-default") {
187
+ thinking = claudeDisableThinking(model) ?? void 0;
188
+ }
189
+ const temperature = !wantThinking && claudeAcceptsTemperature(model) ? request.temperature : void 0;
190
+ const out = { max_tokens: maxTokens };
191
+ if (thinking) out.thinking = thinking;
192
+ if (outputConfig) out.output_config = outputConfig;
193
+ if (temperature !== void 0) out.temperature = temperature;
194
+ return out;
195
+ }
196
+
121
197
  // src/providers/claude.ts
122
198
  var CACHE_MIN_SYSTEM_CHARS = 2e3;
123
199
  var ClaudeProvider = class extends BaseProvider {
@@ -127,30 +203,28 @@ var ClaudeProvider = class extends BaseProvider {
127
203
  info = {
128
204
  id: "claude",
129
205
  displayName: "Claude (Anthropic)",
130
- defaultModel: "claude-sonnet-4-5-20250929",
206
+ // 2026-10-09 按官方 Models overview / Model deprecations 核实:当前一代 4 个,
207
+ // 上下文 1M、最大输出 128K;Sonnet 4.5 已弃用(2026-11-30 下线,官方推荐换 Sonnet 5.5),
208
+ // 从清单移除,旧 config 由 config-manager 自愈迁移。Opus 4.6 / Haiku 4.5 仍为 Active,留作旧版。
209
+ defaultModel: "claude-sonnet-5-5",
131
210
  apiKeyEnvVar: "AICLI_API_KEY_CLAUDE",
132
211
  requiresApiKey: true,
133
212
  models: [
134
- {
135
- id: "claude-opus-4-6",
136
- displayName: "Claude Opus 4.6",
137
- contextWindow: 2e5,
138
- supportsStreaming: true
139
- },
140
- {
141
- id: "claude-sonnet-4-5-20250929",
142
- displayName: "Claude Sonnet 4.5",
143
- contextWindow: 2e5,
144
- supportsStreaming: true
145
- },
146
- {
147
- id: "claude-haiku-4-5-20251001",
148
- displayName: "Claude Haiku 4.5",
149
- contextWindow: 2e5,
150
- supportsStreaming: true
151
- }
213
+ { id: "claude-fable-5-1", displayName: "Claude Fable 5.1", contextWindow: 1e6, supportsStreaming: true, supportsThinking: true },
214
+ { id: "claude-opus-5-5", displayName: "Claude Opus 5.5", contextWindow: 1e6, supportsStreaming: true, supportsThinking: true },
215
+ { id: "claude-sonnet-5-5", displayName: "Claude Sonnet 5.5", contextWindow: 1e6, supportsStreaming: true, supportsThinking: true },
216
+ { id: "claude-haiku-5-5", displayName: "Claude Haiku 5.5", contextWindow: 1e6, supportsStreaming: true, supportsThinking: true },
217
+ { id: "claude-opus-4-6", displayName: "Claude Opus 4.6 (legacy)", contextWindow: 1e6, supportsStreaming: true, supportsThinking: true },
218
+ { id: "claude-haiku-4-5-20251001", displayName: "Claude Haiku 4.5 (legacy)", contextWindow: 2e5, supportsStreaming: true, supportsThinking: true }
152
219
  ]
153
220
  };
221
+ /** 4.6 起用 `output_config.effort` 控制思考深浅;4.5 系列按档位换算成思考预算 */
222
+ get supportsReasoningEffort() {
223
+ return true;
224
+ }
225
+ canDisableThinking(model) {
226
+ return claudeCanDisableThinking(model);
227
+ }
154
228
  async initialize(apiKey, options) {
155
229
  const clientOptions = {
156
230
  apiKey,
@@ -258,24 +332,6 @@ var ClaudeProvider = class extends BaseProvider {
258
332
  }
259
333
  return usage;
260
334
  }
261
- /**
262
- * 构建 Extended Thinking 参数。
263
- * - thinking 启用时 temperature 必须为 1 或不设置(Anthropic API 要求)
264
- * - budget_tokens 最小 1024,默认 10000
265
- */
266
- buildThinkingParams(request) {
267
- if (!request.thinking) {
268
- return { temperature: request.temperature };
269
- }
270
- return {
271
- thinking: {
272
- type: "enabled",
273
- budget_tokens: Math.max(request.thinkingBudget ?? 1e4, 1024)
274
- },
275
- // thinking 启用时 temperature 必须不设置(API 强制 temperature=1)
276
- temperature: void 0
277
- };
278
- }
279
335
  /**
280
336
  * 从 response.content 中提取文本内容。
281
337
  * 当 thinking 启用时,将 ThinkingBlock 内容用 <think>...</think> 标签包裹,
@@ -286,7 +342,8 @@ var ClaudeProvider = class extends BaseProvider {
286
342
  const textParts = [];
287
343
  for (const block of blocks) {
288
344
  if (block.type === "thinking") {
289
- thinkingParts.push(block.thinking);
345
+ const text = block.thinking;
346
+ if (text) thinkingParts.push(text);
290
347
  } else if (block.type === "text") {
291
348
  textParts.push(block.text);
292
349
  }
@@ -301,14 +358,11 @@ var ClaudeProvider = class extends BaseProvider {
301
358
  async chat(request) {
302
359
  try {
303
360
  const messages = this.toClaudeMessagesWithToolHistory(request.messages);
304
- const { thinking, temperature } = this.buildThinkingParams(request);
305
361
  const response = await this.client.messages.create({
306
362
  model: request.model,
307
363
  messages,
308
364
  system: this.buildSystemParam(request.systemPrompt, request.systemPromptVolatile),
309
- max_tokens: request.maxTokens ?? 8192,
310
- temperature,
311
- thinking
365
+ ...buildClaudeRequestParams(request, false)
312
366
  // 非流式路径必须收 signal,否则 Ctrl+C 期间请求不可中断(同 openai-compatible 的同类遗漏)
313
367
  }, { signal: request.signal });
314
368
  const content = this.extractContent(response.content);
@@ -324,33 +378,31 @@ var ClaudeProvider = class extends BaseProvider {
324
378
  async *chatStream(request) {
325
379
  try {
326
380
  const messages = this.toClaudeMessagesWithToolHistory(request.messages);
327
- const { thinking, temperature } = this.buildThinkingParams(request);
328
381
  const stream = this.client.messages.stream({
329
382
  model: request.model,
330
383
  messages,
331
384
  system: this.buildSystemParam(request.systemPrompt, request.systemPromptVolatile),
332
- max_tokens: request.maxTokens ?? 8192,
333
- temperature,
334
- thinking
385
+ ...buildClaudeRequestParams(request, true)
335
386
  }, { signal: request.signal });
336
- let currentBlockType = null;
387
+ let thinkOpen = false;
337
388
  for await (const event of stream) {
338
- if (event.type === "content_block_start") {
339
- currentBlockType = event.content_block.type;
340
- if (currentBlockType === "thinking") {
341
- yield { delta: "<think>", done: false };
342
- }
343
- } else if (event.type === "content_block_delta") {
389
+ if (event.type === "content_block_delta") {
344
390
  if (event.delta.type === "text_delta") {
345
391
  yield { delta: event.delta.text, done: false };
346
392
  } else if (event.delta.type === "thinking_delta") {
347
- yield { delta: event.delta.thinking, done: false };
393
+ const text = event.delta.thinking;
394
+ if (!text) continue;
395
+ if (!thinkOpen) {
396
+ yield { delta: "<think>", done: false };
397
+ thinkOpen = true;
398
+ }
399
+ yield { delta: text, done: false };
348
400
  }
349
401
  } else if (event.type === "content_block_stop") {
350
- if (currentBlockType === "thinking") {
402
+ if (thinkOpen) {
351
403
  yield { delta: "</think>", done: false };
404
+ thinkOpen = false;
352
405
  }
353
- currentBlockType = null;
354
406
  } else if (event.type === "message_stop") {
355
407
  yield { delta: "", done: true };
356
408
  }
@@ -380,15 +432,12 @@ var ClaudeProvider = class extends BaseProvider {
380
432
  const baseMessages = this.toClaudeMessagesWithToolHistory(request.messages);
381
433
  const extraMessages = request._extraMessages ?? [];
382
434
  const allMessages = [...baseMessages, ...extraMessages];
383
- const { thinking, temperature } = this.buildThinkingParams(request);
384
435
  const response = await this.client.messages.create({
385
436
  model: request.model,
386
437
  messages: allMessages,
387
438
  tools: anthropicTools,
388
439
  system: this.buildSystemParam(request.systemPrompt, request.systemPromptVolatile),
389
- max_tokens: request.maxTokens ?? 8192,
390
- temperature,
391
- thinking
440
+ ...buildClaudeRequestParams(request, false)
392
441
  // 轮次耗尽的总结轮对所有 provider 都走这条非流式路径——漏 signal 则 Ctrl+C 无效
393
442
  }, { signal: request.signal });
394
443
  const usage = this.extractUsage(response.usage);
@@ -434,7 +483,6 @@ var ClaudeProvider = class extends BaseProvider {
434
483
  const baseMessages = this.toClaudeMessagesWithToolHistory(request.messages);
435
484
  const extraMessages = request._extraMessages ?? [];
436
485
  const allMessages = [...baseMessages, ...extraMessages];
437
- const { thinking, temperature } = this.buildThinkingParams(request);
438
486
  let doneEmitted = false;
439
487
  const rawContentBlocks = [];
440
488
  try {
@@ -443,12 +491,11 @@ var ClaudeProvider = class extends BaseProvider {
443
491
  messages: allMessages,
444
492
  tools: anthropicTools,
445
493
  system: this.buildSystemParam(request.systemPrompt, request.systemPromptVolatile),
446
- max_tokens: request.maxTokens ?? 8192,
447
- temperature,
448
- thinking
494
+ ...buildClaudeRequestParams(request, true)
449
495
  }, { signal: request.signal });
450
496
  let currentBlockType = null;
451
497
  let currentToolIndex = 0;
498
+ let thinkingShown = false;
452
499
  let currentBlockData = {};
453
500
  let startUsage = null;
454
501
  for await (const event of stream) {
@@ -462,7 +509,7 @@ var ClaudeProvider = class extends BaseProvider {
462
509
  currentBlockType = block.type;
463
510
  currentBlockData = { type: block.type };
464
511
  if (block.type === "thinking") {
465
- yield { type: "thinking_start" };
512
+ thinkingShown = false;
466
513
  currentBlockData = { type: "thinking", thinking: "", signature: "" };
467
514
  } else if (block.type === "text") {
468
515
  currentBlockData = { type: "text", text: "" };
@@ -484,7 +531,13 @@ var ClaudeProvider = class extends BaseProvider {
484
531
  currentBlockData.text += event.delta.text;
485
532
  } else if (event.delta.type === "thinking_delta") {
486
533
  const thinkingDelta = event.delta.thinking;
487
- yield { type: "thinking_delta", delta: thinkingDelta };
534
+ if (thinkingDelta) {
535
+ if (!thinkingShown) {
536
+ yield { type: "thinking_start" };
537
+ thinkingShown = true;
538
+ }
539
+ yield { type: "thinking_delta", delta: thinkingDelta };
540
+ }
488
541
  currentBlockData.thinking += thinkingDelta;
489
542
  } else if (event.delta.type === "input_json_delta") {
490
543
  const jsonDelta = event.delta.partial_json;
@@ -499,7 +552,7 @@ var ClaudeProvider = class extends BaseProvider {
499
552
  }
500
553
  } else if (event.type === "content_block_stop") {
501
554
  if (currentBlockType === "thinking") {
502
- yield { type: "thinking_end" };
555
+ if (thinkingShown) yield { type: "thinking_end" };
503
556
  } else if (currentBlockType === "tool_use") {
504
557
  yield { type: "tool_call_end", index: currentToolIndex };
505
558
  currentToolIndex++;
@@ -662,10 +715,12 @@ var ClaudeProvider = class extends BaseProvider {
662
715
  try {
663
716
  const response = await this.client.models.list();
664
717
  const data = response.data ?? [];
718
+ const known = new Map(this.info.models.map((m) => [m.id, m.contextWindow]));
665
719
  return data.map((model) => ({
666
720
  id: model.id,
667
721
  displayName: model.id,
668
- contextWindow: 2e5,
722
+ // Models API 返回 max_input_tokens;SDK 类型未必带,取不到时用清单值或保守的 200K
723
+ contextWindow: model.max_input_tokens ?? known.get(model.id) ?? 2e5,
669
724
  supportsStreaming: true,
670
725
  source: "live",
671
726
  available: true,
@@ -2052,13 +2107,15 @@ var OpenAIProvider = createStaticProviderClass(OPENAI_CONFIG);
2052
2107
  var OPENROUTER_CONFIG = {
2053
2108
  id: "openrouter",
2054
2109
  displayName: "OpenRouter",
2055
- defaultModel: "anthropic/claude-sonnet-4",
2110
+ defaultModel: "anthropic/claude-sonnet-5.5",
2056
2111
  apiKeyEnvVar: "AICLI_API_KEY_OPENROUTER",
2057
2112
  baseUrl: "https://openrouter.ai/api/v1",
2058
2113
  models: [
2059
- { id: "anthropic/claude-opus-4", displayName: "Claude Opus 4", contextWindow: 2e5, supportsStreaming: true },
2060
- { id: "anthropic/claude-sonnet-4", displayName: "Claude Sonnet 4", contextWindow: 2e5, supportsStreaming: true },
2061
- { id: "anthropic/claude-haiku-4", displayName: "Claude Haiku 4", contextWindow: 2e5, supportsStreaming: true },
2114
+ // 2026-10-09 对 /api/v1/models 实测:OpenRouter 的 Claude id 用点号(claude-sonnet-5.5),
2115
+ // 此前清单里的 `anthropic/claude-opus-4` / `anthropic/claude-haiku-4` 在列表里不存在
2116
+ { id: "anthropic/claude-opus-5.5", displayName: "Claude Opus 5.5", contextWindow: 1e6, supportsStreaming: true },
2117
+ { id: "anthropic/claude-sonnet-5.5", displayName: "Claude Sonnet 5.5", contextWindow: 1e6, supportsStreaming: true },
2118
+ { id: "anthropic/claude-haiku-5.5", displayName: "Claude Haiku 5.5", contextWindow: 1e6, supportsStreaming: true },
2062
2119
  { id: "openai/gpt-5.4", displayName: "GPT-5.4", contextWindow: 105e4, supportsStreaming: true },
2063
2120
  { id: "google/gemini-2.5-pro", displayName: "Gemini 2.5 Pro", contextWindow: 1048576, supportsStreaming: true },
2064
2121
  { id: "google/gemini-2.5-flash", displayName: "Gemini 2.5 Flash", contextWindow: 1048576, supportsStreaming: true },
@@ -45,12 +45,23 @@ function getDeepSeekV4Pricing(model, at) {
45
45
  }
46
46
  var PRICING_TABLE = {
47
47
  // ── Anthropic Claude ──────────────────────────────────────────
48
- "claude-opus-4-8": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
49
- "claude-opus-4-7": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
50
- "claude-opus-4-6": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
51
- "claude-opus-4-5": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
48
+ // 2026-10-09 按官方 Pricing 页核实(USD/MTok)。cacheWrite 取 5 分钟缓存写入价(aicli 只用
49
+ // ephemeral 默认 5m)。缓存读取倍率不统一:Fable 5.1 0.025x、Opus 5.5 / Sonnet 5.5 0.05x、其余 0.1x。
50
+ // 此前 Opus 4.5–4.8 记成 $15/$75(Opus 4.1 的价),费用显示高了 3 倍。
51
+ "claude-fable-5-1": { input: 10, output: 50, cacheWrite: 12.5, cacheRead: 0.25 },
52
+ "claude-fable-5": { input: 10, output: 50, cacheWrite: 12.5, cacheRead: 1 },
53
+ "claude-opus-5-5": { input: 4, output: 20, cacheWrite: 5, cacheRead: 0.2 },
54
+ "claude-opus-5": { input: 5, output: 25, cacheWrite: 6.25, cacheRead: 0.5 },
55
+ "claude-opus-4-8": { input: 5, output: 25, cacheWrite: 6.25, cacheRead: 0.5 },
56
+ "claude-opus-4-7": { input: 5, output: 25, cacheWrite: 6.25, cacheRead: 0.5 },
57
+ "claude-opus-4-6": { input: 5, output: 25, cacheWrite: 6.25, cacheRead: 0.5 },
58
+ "claude-opus-4-5": { input: 5, output: 25, cacheWrite: 6.25, cacheRead: 0.5 },
59
+ "claude-sonnet-5-5": { input: 2, output: 10, cacheWrite: 2.5, cacheRead: 0.1 },
60
+ "claude-sonnet-5": { input: 2, output: 10, cacheWrite: 2.5, cacheRead: 0.2 },
52
61
  "claude-sonnet-4-6": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
53
62
  "claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
63
+ // Haiku 5.5 按提示长度分档:此处为 ≤100K 档,超过的那档见 computeCost 的 CLAUDE_HAIKU_55_LONG
64
+ "claude-haiku-5-5": { input: 0.1, output: 0.5, cacheWrite: 0.125, cacheRead: 0.01 },
54
65
  "claude-haiku-4-5-20251001": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
55
66
  "claude-haiku-4-5": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
56
67
  // Legacy Claude 3.x families (prefix fallback handles minor date suffixes)
@@ -185,8 +196,15 @@ function getPricing(provider, model, at = /* @__PURE__ */ new Date()) {
185
196
  }
186
197
  return null;
187
198
  }
199
+ var CLAUDE_HAIKU_55_LONG = { input: 0.5, output: 2.5, cacheWrite: 0.625, cacheRead: 0.05 };
200
+ var CLAUDE_HAIKU_55_TIER_TOKENS = 1e5;
201
+ function longPromptTier(model, usage) {
202
+ if (!model.toLowerCase().startsWith("claude-haiku-5-5")) return null;
203
+ const prompt = usage.inputTokens + (usage.cacheCreationTokens ?? 0) + (usage.cacheReadTokens ?? 0);
204
+ return prompt > CLAUDE_HAIKU_55_TIER_TOKENS ? CLAUDE_HAIKU_55_LONG : null;
205
+ }
188
206
  function computeCost(provider, model, usage, at = /* @__PURE__ */ new Date()) {
189
- const p = getPricing(provider, model, at);
207
+ const p = longPromptTier(model, usage) ?? getPricing(provider, model, at);
190
208
  if (!p) return null;
191
209
  const input = usage.inputTokens * p.input;
192
210
  const output = usage.outputTokens * p.output;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QMFMST2T.js";
5
5
  import {
6
6
  TEST_TIMEOUT
7
- } from "./chunk-GCYH5WOZ.js";
7
+ } from "./chunk-I7J7E7OB.js";
8
8
 
9
9
  // src/tools/builtin/run-tests.ts
10
10
  import { spawn as spawn2 } from "child_process";
@@ -11,7 +11,7 @@ import {
11
11
  CONFIG_FILE_NAME,
12
12
  HISTORY_DIR_NAME,
13
13
  PLUGINS_DIR_NAME
14
- } from "./chunk-CVWR3VYH.js";
14
+ } from "./chunk-NFA6OCYA.js";
15
15
 
16
16
  // src/config/config-manager.ts
17
17
  import { readFileSync, existsSync, mkdirSync } from "fs";
@@ -390,7 +390,18 @@ ${err}`
390
390
  const DEEPSEEK_TARGET = "deepseek-flash";
391
391
  const LEGACY_KIMI = /* @__PURE__ */ new Set(["kimi-k2-0711-preview", "kimi-k2-turbo-preview"]);
392
392
  const KIMI_TARGET = "kimi-k2.6";
393
+ const LEGACY_CLAUDE = {
394
+ "claude-sonnet-4-5-20250929": "claude-sonnet-5-5",
395
+ "claude-sonnet-4-5": "claude-sonnet-5-5",
396
+ "claude-sonnet-4-20250514": "claude-sonnet-5-5",
397
+ "claude-3-7-sonnet-20250219": "claude-sonnet-5-5",
398
+ "claude-opus-4-20250514": "claude-opus-5-5",
399
+ "claude-opus-4-1-20250805": "claude-opus-5-5",
400
+ "claude-3-5-haiku-20241022": "claude-haiku-5-5",
401
+ "claude-3-haiku-20240307": "claude-haiku-5-5"
402
+ };
393
403
  let changed = false;
404
+ let claudeTarget;
394
405
  const dm = this.config.defaultModels;
395
406
  if (dm) {
396
407
  if (LEGACY_DEEPSEEK.has(dm.deepseek)) {
@@ -401,6 +412,17 @@ ${err}`
401
412
  dm.kimi = KIMI_TARGET;
402
413
  changed = true;
403
414
  }
415
+ const orTo = dm.openrouter ? { "anthropic/claude-opus-4": "anthropic/claude-opus-5.5", "anthropic/claude-haiku-4": "anthropic/claude-haiku-5.5" }[dm.openrouter] : void 0;
416
+ if (orTo) {
417
+ dm.openrouter = orTo;
418
+ changed = true;
419
+ }
420
+ const claudeTo = dm.claude ? LEGACY_CLAUDE[dm.claude] : void 0;
421
+ if (claudeTo) {
422
+ dm.claude = claudeTo;
423
+ claudeTarget = claudeTo;
424
+ changed = true;
425
+ }
404
426
  }
405
427
  const mp = this.config.modelParams;
406
428
  if (mp) {
@@ -422,10 +444,20 @@ ${err}`
422
444
  changed = true;
423
445
  }
424
446
  }
447
+ for (const [legacy, target] of Object.entries(LEGACY_CLAUDE)) {
448
+ if (legacy in mp) {
449
+ if (!(target in mp)) {
450
+ mp[target] = mp[legacy];
451
+ }
452
+ delete mp[legacy];
453
+ claudeTarget ??= target;
454
+ changed = true;
455
+ }
456
+ }
425
457
  }
426
458
  if (changed) {
427
459
  process.stderr.write(
428
- `[ai-cli] Migrated retired model ids in config.json (deepseek \u2192 ${DEEPSEEK_TARGET}, kimi \u2192 ${KIMI_TARGET})
460
+ `[ai-cli] Migrated retired model ids in config.json (deepseek \u2192 ${DEEPSEEK_TARGET}, kimi \u2192 ${KIMI_TARGET}` + (claudeTarget ? `, claude \u2192 ${claudeTarget}` : "") + `)
429
461
  `
430
462
  );
431
463
  }
@@ -12,7 +12,7 @@ import {
12
12
  MEMORY_FILE_NAME,
13
13
  MEMORY_MAX_CHARS,
14
14
  MEMORY_STORE_FILE_NAME
15
- } from "./chunk-GCYH5WOZ.js";
15
+ } from "./chunk-I7J7E7OB.js";
16
16
 
17
17
  // src/memory/persistent-memory.ts
18
18
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  VERSION
4
- } from "./chunk-CVWR3VYH.js";
4
+ } from "./chunk-NFA6OCYA.js";
5
5
 
6
6
  // src/cli/ci-format.ts
7
7
  var DEFAULT_CI_THRESHOLDS = {
@@ -1,5 +1,5 @@
1
1
  // src/core/constants.ts
2
- var VERSION = "0.4.325";
2
+ var VERSION = "0.4.327";
3
3
  var APP_NAME = "ai-cli";
4
4
  var CONFIG_DIR_NAME = ".aicli";
5
5
  var CONFIG_FILE_NAME = "config.json";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  evaluateCiGate,
4
4
  normalizeCiThresholds
5
- } from "./chunk-NBNRQ44O.js";
5
+ } from "./chunk-HN5A5ZXX.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-PIX4ZPFB.js";
16
+ } from "./chunk-AVVT7ZZT.js";
17
17
  import {
18
18
  ConfigManager
19
- } from "./chunk-N6QFHXSF.js";
19
+ } from "./chunk-C3EFGIJY.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-CVWR3VYH.js";
22
+ } from "./chunk-NFA6OCYA.js";
23
23
 
24
24
  // src/cli/ci.ts
25
25
  import { execFileSync } from "child_process";
@@ -8,13 +8,13 @@ import {
8
8
  listHooks,
9
9
  listInstalledPlugins,
10
10
  resetStats
11
- } from "./chunk-WDD76ALZ.js";
11
+ } from "./chunk-ZAZUWQBG.js";
12
12
  import {
13
13
  ProviderRegistry
14
- } from "./chunk-PIX4ZPFB.js";
14
+ } from "./chunk-AVVT7ZZT.js";
15
15
  import {
16
16
  ConfigManager
17
- } from "./chunk-N6QFHXSF.js";
17
+ } from "./chunk-C3EFGIJY.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-CVWR3VYH.js";
29
+ } from "./chunk-NFA6OCYA.js";
30
30
 
31
31
  // src/diagnostics/doctor-report.ts
32
32
  import { existsSync as existsSync3, statSync as statSync2 } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.325";
4
+ var VERSION = "0.4.327";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-CVWR3VYH.js";
4
+ } from "./chunk-NFA6OCYA.js";
5
5
  import {
6
6
  getExecutionConfigDir,
7
7
  getExecutionSignal