jinzd-ai-cli 0.4.324 → 0.4.326

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-TXSH37GQ.js → batch-D3HG4I6J.js} +6 -4
  4. package/dist/{chunk-AYDP3HFZ.js → chunk-2IGHZDPR.js} +1 -1
  5. package/dist/{chunk-PIX4ZPFB.js → chunk-5CE64V7X.js} +129 -72
  6. package/dist/{chunk-MX3SLCEP.js → chunk-5EDSZ3JF.js} +4 -4
  7. package/dist/{chunk-JYDLKJEQ.js → chunk-7OY3WOJD.js} +1 -1
  8. package/dist/{chunk-YCGWWBHF.js → chunk-BGFFD3IL.js} +1 -1
  9. package/dist/{chunk-NFPJ6KUU.js → chunk-BRZZ3QAI.js} +23 -5
  10. package/dist/{chunk-IOPPS6ST.js → chunk-DHJFMW3F.js} +14 -11
  11. package/dist/{chunk-IVVPYBGG.js → chunk-ERHFJIEP.js} +1 -1
  12. package/dist/{chunk-2C7NMQBY.js → chunk-FBT5VPT4.js} +34 -2
  13. package/dist/{chunk-IAI2FAX4.js → chunk-LCI2GVAU.js} +1 -1
  14. package/dist/{chunk-IBKFJFLM.js → chunk-LZ5667Z2.js} +1 -1
  15. package/dist/{chunk-RFJV47EQ.js → chunk-MGFFZFOA.js} +1 -1
  16. package/dist/{chunk-4YKQD5RW.js → chunk-NZGSCXA4.js} +7 -5
  17. package/dist/{chunk-CSXGOHLG.js → chunk-OIYQX2HM.js} +1 -1
  18. package/dist/{chunk-TEJHNHNO.js → chunk-OW3PAC3K.js} +4 -4
  19. package/dist/{ci-7TNQQRFB.js → ci-B4P35VVJ.js} +5 -5
  20. package/dist/{ci-format-K56H66E3.js → ci-format-JD7DKDNT.js} +2 -2
  21. package/dist/{constants-ZC7ZATE4.js → constants-2BVJTZJT.js} +1 -1
  22. package/dist/{constants-7WO66DLZ.js → constants-XOD3IIW5.js} +1 -1
  23. package/dist/{doctor-cli-JSXZ45K3.js → doctor-cli-GPFJF7WP.js} +5 -5
  24. package/dist/electron-server.js +203 -93
  25. package/dist/{hub-IJSXOA4J.js → hub-GQ2XUS4M.js} +1 -1
  26. package/dist/index.js +21 -20
  27. package/dist/{persistent-memory-MTYZ3CSO.js → persistent-memory-RY2JLUL4.js} +2 -2
  28. package/dist/{persistent-memory-7UQU5XVH.js → persistent-memory-SAP3R57F.js} +2 -2
  29. package/dist/{pr-2MGEREWJ.js → pr-AMY7JRQQ.js} +5 -5
  30. package/dist/{run-tests-66SUUBDO.js → run-tests-3BB4LUZT.js} +2 -2
  31. package/dist/{run-tests-WOPRQ64C.js → run-tests-5HMWO676.js} +2 -2
  32. package/dist/{server-6J4542BD.js → server-2NHQYAZN.js} +5 -5
  33. package/dist/{server-Y63DU44H.js → server-GSIQOYEV.js} +17 -16
  34. package/dist/{task-orchestrator-G7TSF5Q3.js → task-orchestrator-VRPSFGNY.js} +5 -5
  35. package/dist/{usage-SODWISIA.js → usage-2RJRDXIT.js} +3 -3
  36. package/dist/wasm/web-tree-sitter.wasm +0 -0
  37. package/package.json +5 -5
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-2C7NMQBY.js";
7
+ } from "./chunk-FBT5VPT4.js";
8
8
  import "./chunk-TU3L3PW7.js";
9
9
  import {
10
10
  atomicWriteFileSync
11
11
  } from "./chunk-BMLQPSHP.js";
12
- import "./chunk-IAI2FAX4.js";
12
+ import "./chunk-LCI2GVAU.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
  }
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-IAI2FAX4.js";
4
+ } from "./chunk-LCI2GVAU.js";
5
5
  import {
6
6
  getExecutionConfigDir,
7
7
  getExecutionSignal
@@ -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-LCI2GVAU.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 },
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  evaluateCiGate,
4
4
  normalizeCiThresholds
5
- } from "./chunk-CSXGOHLG.js";
5
+ } from "./chunk-OIYQX2HM.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-5CE64V7X.js";
17
17
  import {
18
18
  ConfigManager
19
- } from "./chunk-2C7NMQBY.js";
19
+ } from "./chunk-FBT5VPT4.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-IAI2FAX4.js";
22
+ } from "./chunk-LCI2GVAU.js";
23
23
 
24
24
  // src/cli/ci.ts
25
25
  import { execFileSync } from "child_process";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-QMFMST2T.js";
5
5
  import {
6
6
  TEST_TIMEOUT
7
- } from "./chunk-RFJV47EQ.js";
7
+ } from "./chunk-MGFFZFOA.js";
8
8
 
9
9
  // src/tools/builtin/run-tests.ts
10
10
  import { spawn as spawn2 } from "child_process";
@@ -13,7 +13,7 @@ import {
13
13
  MEMORY_FILE_NAME,
14
14
  MEMORY_MAX_CHARS,
15
15
  MEMORY_STORE_FILE_NAME
16
- } from "./chunk-IAI2FAX4.js";
16
+ } from "./chunk-LCI2GVAU.js";
17
17
 
18
18
  // src/memory/persistent-memory.ts
19
19
  import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
@@ -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;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  computeCost,
4
4
  formatCost
5
- } from "./chunk-NFPJ6KUU.js";
5
+ } from "./chunk-BRZZ3QAI.js";
6
6
  import {
7
7
  clearRecentlyDeniedAutoActions,
8
8
  estimateTokens,
@@ -16,7 +16,7 @@ import {
16
16
  setPreferredAgentName,
17
17
  truncateForPersist,
18
18
  undoStack
19
- } from "./chunk-4YKQD5RW.js";
19
+ } from "./chunk-NZGSCXA4.js";
20
20
  import {
21
21
  buildReviewPrompt,
22
22
  buildSecurityReviewPrompt
@@ -51,7 +51,7 @@ import {
51
51
  touchMemoryReferences,
52
52
  updateMemoryApproval,
53
53
  updateMemoryEntry
54
- } from "./chunk-YCGWWBHF.js";
54
+ } from "./chunk-BGFFD3IL.js";
55
55
  import {
56
56
  theme
57
57
  } from "./chunk-5C76XDDF.js";
@@ -65,7 +65,7 @@ import {
65
65
  import {
66
66
  buildDoctorReport,
67
67
  formatDoctorReport
68
- } from "./chunk-TEJHNHNO.js";
68
+ } from "./chunk-OW3PAC3K.js";
69
69
  import {
70
70
  describePlugin,
71
71
  getActivePluginAssets,
@@ -80,7 +80,7 @@ import {
80
80
  trustHook,
81
81
  trustPlugin,
82
82
  untrustHook
83
- } from "./chunk-IVVPYBGG.js";
83
+ } from "./chunk-ERHFJIEP.js";
84
84
  import {
85
85
  isCleanDocumentBody,
86
86
  stripOuterCodeFence
@@ -109,7 +109,7 @@ import {
109
109
  MCP_TOOL_PREFIX,
110
110
  REPO_URL,
111
111
  VERSION
112
- } from "./chunk-IAI2FAX4.js";
112
+ } from "./chunk-LCI2GVAU.js";
113
113
 
114
114
  // src/skills/manager.ts
115
115
  import { existsSync, readdirSync, mkdirSync, statSync } from "fs";
@@ -1348,6 +1348,7 @@ function applyThinkCommand(sub, state) {
1348
1348
  details: effort && !state.supportsEffort ? [`Note: ${state.provider} has no reasoning-effort levels \u2014 the level is ignored.`] : [],
1349
1349
  changed: true
1350
1350
  });
1351
+ const alwaysThinksNote = state.alwaysThinks ? ["Note: this model always thinks and cannot turn it off \u2014 OFF only hides the thinking text; thinking tokens are still billed."] : [];
1351
1352
  const disable = () => ({
1352
1353
  runtimeThinking: false,
1353
1354
  // 刻意保留档位:重新开启时不该丢掉用户选过的档
@@ -1355,11 +1356,12 @@ function applyThinkCommand(sub, state) {
1355
1356
  effective: false,
1356
1357
  origin: "runtime override",
1357
1358
  summary: "Extended Thinking: OFF",
1358
- details: [],
1359
+ details: alwaysThinksNote,
1359
1360
  changed: true
1360
1361
  });
1361
1362
  if (key === "status") {
1362
1363
  const details = current.effective ? [effortLine(state, null)] : [
1364
+ ...alwaysThinksNote,
1363
1365
  "Enable with /think on | low | high | max, or set",
1364
1366
  "modelParams.<model>.thinking in ~/.aicli/config.json"
1365
1367
  ];
@@ -1506,7 +1508,7 @@ function parseRouteCommand(args) {
1506
1508
  }
1507
1509
  function routingEmptyRulesNote(routing) {
1508
1510
  if (routing && routing.rules.length > 0) return null;
1509
- return 'No rules configured yet. Add rules under `routing.rules` in ~/.aicli/config.json.\nExample: { match: { tag: "fast" }, model: "claude-haiku-4-5" }';
1511
+ return 'No rules configured yet. Add rules under `routing.rules` in ~/.aicli/config.json.\nExample: { match: { tag: "fast" }, model: "claude-haiku-5-5" }';
1510
1512
  }
1511
1513
  function describeRoutingRule(rule, index) {
1512
1514
  const parts = [];
@@ -2168,7 +2170,8 @@ function createProviderCommands() {
2168
2170
  configuredThinking: ctx.getConfiguredThinking(),
2169
2171
  configuredEffort: ctx.getConfiguredThinkingEffort(),
2170
2172
  supportsEffort: ctx.getProviderSupportsReasoningEffort(),
2171
- provider: ctx.getCurrentProvider()
2173
+ provider: ctx.getCurrentProvider(),
2174
+ alwaysThinks: ctx.getModelCanDisableThinking ? !ctx.getModelCanDisableThinking() : false
2172
2175
  });
2173
2176
  if (outcome.changed) {
2174
2177
  ctx.setThinkingMode(outcome.runtimeThinking);
@@ -2442,7 +2445,7 @@ No tools match "${filter}".
2442
2445
  const { join: join6 } = await import("path");
2443
2446
  const { existsSync: existsSync6 } = await import("fs");
2444
2447
  const { getGitRoot } = await import("./git-context-EXOEHQSF.js");
2445
- const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-7WO66DLZ.js");
2448
+ const { MCP_PROJECT_CONFIG_NAME } = await import("./constants-XOD3IIW5.js");
2446
2449
  const { approveProject, hashMcpFile } = await import("./project-trust-KGG2BWKC.js");
2447
2450
  const cwd = process.cwd();
2448
2451
  const projectRoot = getGitRoot(cwd) ?? cwd;
@@ -3550,7 +3553,7 @@ function createReviewCommands() {
3550
3553
  usage: "/test [command|filter]",
3551
3554
  async execute(args, ctx) {
3552
3555
  try {
3553
- const { executeTests } = await import("./run-tests-WOPRQ64C.js");
3556
+ const { executeTests } = await import("./run-tests-5HMWO676.js");
3554
3557
  const argStr = args.join(" ").trim();
3555
3558
  let testArgs = {};
3556
3559
  if (argStr) {
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  CONFIG_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-IAI2FAX4.js";
11
+ } from "./chunk-LCI2GVAU.js";
12
12
 
13
13
  // src/diagnostics/tool-stats.ts
14
14
  import { mkdirSync } from "fs";