@eddyskywalker/dsh-chatgpt-subscription 0.37.0 → 0.38.1

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/lib/client.js CHANGED
@@ -3691,7 +3691,7 @@ window.__ModuleLoader__.load({
3691
3691
  * exactly one and rejects the others, so the label states which one this model
3692
3692
  * actually uses.
3693
3693
  */
3694
- function wireLabel(wire, t) {
3694
+ function wireLabel$1(wire, t) {
3695
3695
  if (wire === "anthropic") return t.wireAnthropic;
3696
3696
  if (wire === "responses") return t.wireResponses;
3697
3697
  return t.wireOpenai;
@@ -4120,7 +4120,7 @@ window.__ModuleLoader__.load({
4120
4120
  items: (status?.models ?? []).map((model) => ({
4121
4121
  id: model.id,
4122
4122
  name: model.name,
4123
- hint: wireLabel(model.wire, t),
4123
+ hint: wireLabel$1(model.wire, t),
4124
4124
  enabled: model.enabled
4125
4125
  })),
4126
4126
  busy: busy !== null,
@@ -4277,15 +4277,6 @@ window.__ModuleLoader__.load({
4277
4277
  });
4278
4278
  }
4279
4279
  //#endregion
4280
- //#region src/shared/kimi-code-contracts.ts
4281
- /** Every level, in escalating order; the settings card renders exactly these. */
4282
- const KIMI_CODE_REASONING_EFFORTS = [
4283
- "low",
4284
- "high",
4285
- "max",
4286
- "none"
4287
- ];
4288
- //#endregion
4289
4280
  //#region src/client/kimi-code/locales.ts
4290
4281
  const NS_KIMI_CODE = "dsh-kimi-code";
4291
4282
  const zh$10 = {
@@ -4336,10 +4327,13 @@ window.__ModuleLoader__.load({
4336
4327
  wireAnthropic: "Anthropic",
4337
4328
  wireOpenai: "OpenAI",
4338
4329
  capVideo: "视频*",
4330
+ capThinkingOnly: "只支持思考",
4331
+ capEfforts: "档位 {list}",
4339
4332
  capDynamicTools: "动态工具",
4340
4333
  capImageOnly: "仅图片",
4341
4334
  capNone: "—",
4342
4335
  capVideoFootnote: "* 视频输入需先由 kimi_attach_video 工具挂载(本地绝对路径或 http(s) 链接);直接粘贴的上传路径仍只支持图片。",
4336
+ capThinkingOnlyFootnote: "* 「只支持思考」的模型不能关闭思考:请求里带 none 会被服务端拒绝(400),所以它的档位里没有「关闭思考」。",
4343
4337
  capabilitiesTitle: "模型能力",
4344
4338
  capColMedia: "多模态",
4345
4339
  capColTools: "动态工具",
@@ -4350,13 +4344,16 @@ window.__ModuleLoader__.load({
4350
4344
  speedRegular: "标准",
4351
4345
  speedHighspeed: "高速 (约 6×)",
4352
4346
  quotaCost: "额度倍率",
4347
+ quotaUnknown: "未公布",
4353
4348
  minimumPlan: "所需套餐",
4354
4349
  enhanced: "思考设置",
4355
4350
  defaultReasoningEffort: "默认思考档位",
4356
- defaultReasoningEffortHint: "Kimi Code 只接受 low / high / max 三档;none 表示关闭思考。切换档位会使上下文缓存失效,建议在同一会话中保持一致。",
4351
+ defaultReasoningEffortHint: "可用档位跟随勾选的模型自己声明的能力(一个都没勾时按 low / high / max / none 全列);none 表示关闭思考,只对允许关闭的模型有效。切换档位会使上下文缓存失效,建议在同一会话中保持一致。",
4352
+ effortThinkingOnlyNote: "勾选的模型里有只支持思考模式的:{models}。它们没有「关闭思考」这一档,请求关闭思考会被服务端拒绝(400),所以这里不提供。",
4353
+ effortNotOffered: "当前勾选的模型不接受",
4357
4354
  cacheTtl: "上下文缓存时长",
4358
- cacheTtlHint: "Kimi 按前缀自动缓存,这里选择写入时长。1h 写入约为 5m 的两倍价,只有当同一前缀会在一小时内被反复读取才划算;档位在首次写入时锁定,之后无法改写。留空表示不指定,由 Kimi 自己决定(实测有效期约 5–30 分钟)。依据回合间隔选:间隔通常短于约 30 分钟就留空或选 5 分钟;调度、等子代理这类会出现长空闲的会话选 1 小时。",
4359
- cacheTtlDefault: "不指定(Kimi 默认)",
4355
+ cacheTtlHint: "Kimi 按前缀自动缓存,这里选择写入档位(只有 5m / 1h 两档)。不传时服务端按 5 分钟档写入。1h 写入单价约为 5m 的两倍,只有当同一前缀会在一小时内被反复读取才划算。档位在首次写入时锁定,之后命中按原 TTL 续期,无法改写。依据回合间隔选:间隔通常短于约 30 分钟选 5 分钟;调度、等子代理这类会出现长空闲的会话选 1 小时。",
4356
+ cacheTtlDefault: "不传(服务端按 5 分钟档写入)",
4360
4357
  cacheTtl5m: "5 分钟",
4361
4358
  cacheTtl1h: "1 小时",
4362
4359
  defaultEffortAuto: "使用模型默认值",
@@ -4382,6 +4379,11 @@ window.__ModuleLoader__.load({
4382
4379
  cacheFresh: "新处理 tokens",
4383
4380
  cacheOutput: "输出 tokens",
4384
4381
  cacheRequests: "请求数",
4382
+ cacheWrite: "缓存写入",
4383
+ cacheWrite5m: "5 分钟档",
4384
+ cacheWrite1h: "1 小时档",
4385
+ cacheWriteHint: "写入是独立计费项:1h 写入单价约为 5m 的两倍,命中后会按原 TTL 续期。分档显示 0 表示服务端没有回报该档的写入数(响应头缺失就是静默),不等于该档确实没写入。",
4386
+ unknownMetric: "暂无",
4385
4387
  cacheHint: "同一会话内:系统提示与工具列表一旦变化会使缓存整体失效,因此保持工具集合稳定、把新增内容追加在末尾,命中率最高。",
4386
4388
  cacheExpired: "本会话已空闲超过缓存有效期,下一轮将重新处理约 {tokens} 个 token。",
4387
4389
  cacheDrift: "最近前缀状态",
@@ -4459,10 +4461,13 @@ window.__ModuleLoader__.load({
4459
4461
  wireAnthropic: "Anthropic",
4460
4462
  wireOpenai: "OpenAI",
4461
4463
  capVideo: "Video*",
4464
+ capThinkingOnly: "Thinking only",
4465
+ capEfforts: "Levels {list}",
4462
4466
  capDynamicTools: "Dynamic tools",
4463
4467
  capImageOnly: "Images",
4464
4468
  capNone: "—",
4465
4469
  capVideoFootnote: "* Video input is attached with the kimi_attach_video tool (an absolute local path or an http(s) URL); the paste/upload path still accepts images only.",
4470
+ capThinkingOnlyFootnote: "* A \"thinking only\" model cannot switch thinking off: a request carrying none is rejected by the service with HTTP 400, so \"thinking off\" is not among its levels.",
4466
4471
  capabilitiesTitle: "Capabilities",
4467
4472
  capColMedia: "Multimodal",
4468
4473
  capColTools: "Dynamic tools",
@@ -4473,13 +4478,16 @@ window.__ModuleLoader__.load({
4473
4478
  speedRegular: "Regular",
4474
4479
  speedHighspeed: "HighSpeed (~6x)",
4475
4480
  quotaCost: "Quota cost",
4481
+ quotaUnknown: "Not published",
4476
4482
  minimumPlan: "Required plan",
4477
4483
  enhanced: "Thinking",
4478
4484
  defaultReasoningEffort: "Default thinking level",
4479
- defaultReasoningEffortHint: "Kimi Code accepts only low / high / max; none disables thinking. Switching the level invalidates the context cache, so keep it steady within a session.",
4485
+ defaultReasoningEffortHint: "The levels offered follow what the checked models declare (all of low / high / max / none when none is checked); none disables thinking and only applies to models that allow it. Switching the level invalidates the context cache, so keep it steady within a session.",
4486
+ effortThinkingOnlyNote: "Some checked models think at every level: {models}. They have no \"thinking off\" — the service rejects that request with HTTP 400 — so it is not offered here.",
4487
+ effortNotOffered: "not accepted by the checked models",
4480
4488
  cacheTtl: "Context cache duration",
4481
- cacheTtlHint: "Kimi caches prefixes automatically; this chooses the write duration. A 1h write costs about twice a 5m one and only pays off when the same prefix is re-read within the hour. The tier is locked when first written and cannot be changed afterwards. Leave unset to send no cache field and let Kimi decide (measured lifetime is roughly 5-30 minutes). Choose by the gap between turns: leave unset or use 5 minutes when turns are normally less than about 30 minutes apart, and pick 1 hour for a session that idles for long stretches, such as dispatch work waiting on subagents.",
4482
- cacheTtlDefault: "Unset (Kimi default)",
4489
+ cacheTtlHint: "Kimi caches prefixes automatically; this chooses the write tier, and there are only two (5m and 1h). Unset sends no cache field, and the service then writes at the 5-minute tier. A 1h write costs about twice a 5m one and only pays off when the same prefix is re-read within the hour. The tier is locked at the first write, and later hits renew it under that original TTL. Choose by the gap between turns: 5 minutes when turns are normally less than about 30 minutes apart, 1 hour for a session that idles for long stretches, such as dispatch work waiting on subagents.",
4490
+ cacheTtlDefault: "Unset (service writes at the 5-minute tier)",
4483
4491
  cacheTtl5m: "5 minutes",
4484
4492
  cacheTtl1h: "1 hour",
4485
4493
  defaultEffortAuto: "Use the model default",
@@ -4506,6 +4514,11 @@ window.__ModuleLoader__.load({
4506
4514
  cacheFresh: "Fresh tokens",
4507
4515
  cacheOutput: "Output tokens",
4508
4516
  cacheRequests: "Requests",
4517
+ cacheWrite: "Cache writes",
4518
+ cacheWrite5m: "5-minute tier",
4519
+ cacheWrite1h: "1-hour tier",
4520
+ cacheWriteHint: "A write is billed separately: a 1h write costs about twice a 5m one, and a hit renews the entry under its original TTL. A tier showing 0 means the service did not report a write for it (a missing response header is silence), not that nothing was written there.",
4521
+ unknownMetric: "n/a",
4509
4522
  cacheHint: "Within one session: any change to the system prompt or the tool list invalidates the whole prefix cache, so keep the tool set stable and append new material at the tail for the best hit rate.",
4510
4523
  cacheDrift: "Last prefix state",
4511
4524
  cacheDriftFirst: "First request (cache cold)",
@@ -4541,6 +4554,95 @@ window.__ModuleLoader__.load({
4541
4554
  "en-US": en$10
4542
4555
  };
4543
4556
  //#endregion
4557
+ //#region src/shared/kimi-code-contracts.ts
4558
+ /** Every level, in escalating order; the settings card renders exactly these. */
4559
+ const KIMI_CODE_REASONING_EFFORTS = [
4560
+ "low",
4561
+ "high",
4562
+ "max",
4563
+ "none"
4564
+ ];
4565
+ //#endregion
4566
+ //#region src/client/kimi-code/labels.ts
4567
+ /**
4568
+ * Name of the request/response dialect a model is served over.
4569
+ *
4570
+ * @param wire - dialect the adapter reports for this model.
4571
+ * @param t - dictionary of the card rendering it.
4572
+ */
4573
+ function wireLabel(wire, t) {
4574
+ return wire === "anthropic" ? t.wireAnthropic : t.wireOpenai;
4575
+ }
4576
+ /** Human label for one thinking level. */
4577
+ function effortLabel(effort, t) {
4578
+ switch (effort) {
4579
+ case "low": return t.effortLow;
4580
+ case "high": return t.effortHigh;
4581
+ case "max": return t.effortMax;
4582
+ case "none": return t.effortNone;
4583
+ default: return effort;
4584
+ }
4585
+ }
4586
+ /**
4587
+ * Thinking levels one model publishes, in the order the card renders them.
4588
+ *
4589
+ * The ladder is read, never assumed: a model that declares no levels gets an
4590
+ * empty list, and the picker then offers none of them rather than the generic
4591
+ * four. `none` is dropped for a thinking-only model — the host already strips
4592
+ * it, and filtering again is what keeps an older host, or a live catalog that
4593
+ * says nothing about thinking, from putting "thinking off" back on a menu whose
4594
+ * request the service answers with HTTP 400.
4595
+ *
4596
+ * @param model - one entry from the model directory.
4597
+ */
4598
+ function effortLadder(model) {
4599
+ const declared = model.reasoningEfforts ?? [];
4600
+ const known = KIMI_CODE_REASONING_EFFORTS.filter((effort) => declared.includes(effort));
4601
+ return model.thinkingType === "only" ? known.filter((effort) => effort !== "none") : known;
4602
+ }
4603
+ /**
4604
+ * Whether one model may be asked to stop reasoning.
4605
+ *
4606
+ * Read from the model's own declaration rather than assumed: `only` is the one
4607
+ * value that makes the question a hard no — the service answers a
4608
+ * disabled-thinking request with HTTP 400 and names the model — while `no`
4609
+ * describes a model that never reasons, so there is no switch to offer either.
4610
+ * `both`, and a registry that says nothing about the id, keep the switch,
4611
+ * because that is what this line offered before the flag existed and the
4612
+ * service, not the card, is the authority on refusing a level.
4613
+ *
4614
+ * @param model - one entry from the model directory.
4615
+ */
4616
+ function canDisableThinking(model) {
4617
+ return model.thinkingType !== "only" && model.thinkingType !== "no";
4618
+ }
4619
+ /**
4620
+ * Thinking levels a conversation can actually be set to.
4621
+ *
4622
+ * The setting is one level for the whole line, so the three thinking levels are
4623
+ * the union of what the CHECKED models declare: a level no checked model
4624
+ * declares would be stored and then rejected on the first turn. "Thinking off"
4625
+ * is not one of those declared levels on most rows — it is a switch, not a
4626
+ * ladder rung — so it is decided by {@link canDisableThinking} instead, and it
4627
+ * disappears exactly when every checked model refuses to be switched off.
4628
+ *
4629
+ * With nothing checked there is no model to narrow it down and the full ladder
4630
+ * is offered.
4631
+ *
4632
+ * @param models - every model in the directory, checked or not.
4633
+ */
4634
+ function effortOptions(models) {
4635
+ const enabled = models.filter((model) => model.enabled);
4636
+ if (enabled.length === 0) return [...KIMI_CODE_REASONING_EFFORTS];
4637
+ const declared = new Set(enabled.flatMap((model) => effortLadder(model)));
4638
+ const switchable = enabled.some((model) => canDisableThinking(model));
4639
+ return KIMI_CODE_REASONING_EFFORTS.filter((effort) => effort === "none" ? switchable : declared.has(effort));
4640
+ }
4641
+ /** Models that reason at every level, and so have no "thinking off". */
4642
+ function thinkingOnlyModels(models) {
4643
+ return models.filter((model) => model.thinkingType === "only");
4644
+ }
4645
+ //#endregion
4544
4646
  //#region src/client/kimi-code/KimiModelCapabilities.tsx
4545
4647
  /**
4546
4648
  * Capability table for the Kimi model list.
@@ -4564,54 +4666,71 @@ window.__ModuleLoader__.load({
4564
4666
  const t = useLineDict(NS_KIMI_CODE, zh$10);
4565
4667
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4566
4668
  className: "dsha-cap-table",
4567
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4568
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capabilitiesTitle }),
4569
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColMedia }),
4570
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColTools }),
4571
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColNotes })
4572
- ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: models.map((model) => {
4573
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4574
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4575
- title: [
4576
- model.id,
4577
- model.wire === "anthropic" ? t.wireAnthropic : t.wireOpenai,
4578
- ...model.defaultReasoningEffort ? [t.defaultReasoningEffort + ": " + model.defaultReasoningEffort] : [],
4579
- ...model.maxInputTokens === void 0 ? [] : [t.capInputCap.replace("{tokens}", String(model.maxInputTokens))],
4580
- ...model.minimumPlan ? [t.capPlan.replace("{plan}", model.minimumPlan)] : [],
4581
- ...model.quotaMultiplier === null ? [] : [`${t.quotaCost}: ${formatMultiplier(model.quotaMultiplier)}`]
4582
- ].join(" · "),
4583
- children: model.name
4584
- }),
4585
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4586
- className: model.supportsVideo ? "dsha-cap-on" : "dsha-cap-off",
4587
- children: model.supportsVideo ? t.capVideo : t.capImageOnly
4588
- }) }),
4589
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: model.supportsDynamicTools ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4590
- className: "dsha-cap-on",
4591
- children: t.capDynamicTools
4592
- }) : model.supportsToolUse ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4593
- className: "dsha-cap-off",
4594
- children: t.capNone
4595
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4596
- className: "dsha-cap-off",
4597
- children: t.capNoTools
4598
- }) }),
4599
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
4600
- className: "dsha-cap-notes",
4601
- children: [model.quotaMultiplier === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4602
- className: "dsha-cap-cost",
4603
- children: [
4604
- t.quotaCost,
4605
- " ",
4606
- formatMultiplier(model.quotaMultiplier)
4607
- ]
4608
- }), model.description ?? ""]
4609
- })
4610
- ] }, model.id);
4611
- }) })] }), models.some((model) => model.supportsVideo) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4612
- className: "dsha-muted dsha-cap-footnote",
4613
- children: t.capVideoFootnote
4614
- })]
4669
+ children: [
4670
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4671
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capabilitiesTitle }),
4672
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColMedia }),
4673
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColTools }),
4674
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t.capColNotes })
4675
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: models.map((model) => {
4676
+ const ladder = effortLadder(model);
4677
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
4678
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
4679
+ title: [
4680
+ model.id,
4681
+ wireLabel(model.wire, t),
4682
+ ...model.thinkingType === "only" ? [t.capThinkingOnly] : [],
4683
+ ...ladder.length === 0 ? [] : [t.capEfforts.replace("{list}", ladder.join(" / "))],
4684
+ ...model.defaultReasoningEffort ? [t.defaultReasoningEffort + ": " + model.defaultReasoningEffort] : [],
4685
+ ...model.maxInputTokens === void 0 ? [] : [t.capInputCap.replace("{tokens}", String(model.maxInputTokens))],
4686
+ ...model.minimumPlan ? [t.capPlan.replace("{plan}", model.minimumPlan)] : [],
4687
+ ...model.quotaMultiplier === null ? [] : [`${t.quotaCost}: ${formatMultiplier(model.quotaMultiplier)}`]
4688
+ ].join(" · "),
4689
+ children: model.name
4690
+ }),
4691
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4692
+ className: model.supportsVideo ? "dsha-cap-on" : "dsha-cap-off",
4693
+ children: model.supportsVideo ? t.capVideo : t.capImageOnly
4694
+ }) }),
4695
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: model.supportsDynamicTools ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4696
+ className: "dsha-cap-on",
4697
+ children: t.capDynamicTools
4698
+ }) : model.supportsToolUse ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4699
+ className: "dsha-cap-off",
4700
+ children: t.capNone
4701
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4702
+ className: "dsha-cap-off",
4703
+ children: t.capNoTools
4704
+ }) }),
4705
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("td", {
4706
+ className: "dsha-cap-notes",
4707
+ children: [model.quotaMultiplier === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4708
+ className: "dsha-cap-off",
4709
+ children: [
4710
+ t.quotaCost,
4711
+ " ",
4712
+ t.quotaUnknown
4713
+ ]
4714
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4715
+ className: "dsha-cap-cost",
4716
+ children: [
4717
+ t.quotaCost,
4718
+ " ",
4719
+ formatMultiplier(model.quotaMultiplier)
4720
+ ]
4721
+ }), model.description ?? ""]
4722
+ })
4723
+ ] }, model.id);
4724
+ }) })] }),
4725
+ models.some((model) => model.supportsVideo) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4726
+ className: "dsha-muted dsha-cap-footnote",
4727
+ children: t.capVideoFootnote
4728
+ }),
4729
+ models.some((model) => model.thinkingType === "only") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4730
+ className: "dsha-muted dsha-cap-footnote",
4731
+ children: t.capThinkingOnlyFootnote
4732
+ })
4733
+ ]
4615
4734
  });
4616
4735
  }
4617
4736
  //#endregion
@@ -4630,14 +4749,15 @@ window.__ModuleLoader__.load({
4630
4749
  return `${(cents / 100).toFixed(2)} ${code}`;
4631
4750
  }
4632
4751
  }
4633
- function effortLabel(effort, t) {
4634
- switch (effort) {
4635
- case "low": return t.effortLow;
4636
- case "high": return t.effortHigh;
4637
- case "max": return t.effortMax;
4638
- case "none": return t.effortNone;
4639
- default: return effort;
4640
- }
4752
+ /**
4753
+ * One token count as the card prints it.
4754
+ *
4755
+ * A reported zero prints as "0": zero writes is a reading, while a blank cell
4756
+ * reads as "nothing was measured", and the two are different claims. Only a
4757
+ * number this build cannot read at all falls back to "暂无".
4758
+ */
4759
+ function tokenCount(value, t) {
4760
+ return typeof value === "number" && Number.isFinite(value) ? value.toLocaleString() : t.unknownMetric;
4641
4761
  }
4642
4762
  /** Human label for the last request's prefix-drift cause. */
4643
4763
  function driftLabel(cause, t) {
@@ -4984,8 +5104,13 @@ window.__ModuleLoader__.load({
4984
5104
  });
4985
5105
  const quota = status?.quota;
4986
5106
  status?.account;
4987
- status?.models.filter((model) => model.enabled).length;
5107
+ const models = status?.models ?? [];
5108
+ models.filter((model) => model.enabled).length;
4988
5109
  const loginPending = flow?.status === "pending";
5110
+ const offeredEfforts = effortOptions(models);
5111
+ const savedEffort = status?.defaultReasoningEffort ?? null;
5112
+ const staleEffort = savedEffort !== null && !offeredEfforts.includes(savedEffort) ? savedEffort : null;
5113
+ const thinkingOnly = thinkingOnlyModels(models.filter((model) => model.enabled));
4989
5114
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4990
5115
  className: "dsha-page",
4991
5116
  children: [
@@ -5181,6 +5306,30 @@ window.__ModuleLoader__.load({
5181
5306
  children: driftLabel(status.cache.lastDrift, t)
5182
5307
  })]
5183
5308
  }),
5309
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5310
+ className: "dsha-row",
5311
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5312
+ className: "dsha-label",
5313
+ children: t.cacheWrite
5314
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5315
+ className: "dsha-value",
5316
+ children: [
5317
+ tokenCount(status.cache.cacheWriteTokens, t),
5318
+ " · ",
5319
+ t.cacheWrite5m,
5320
+ " ",
5321
+ tokenCount(status.cache.cacheWrite5mTokens, t),
5322
+ " · ",
5323
+ t.cacheWrite1h,
5324
+ " ",
5325
+ tokenCount(status.cache.cacheWrite1hTokens, t)
5326
+ ]
5327
+ })]
5328
+ }),
5329
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5330
+ className: "dsha-muted",
5331
+ children: t.cacheWriteHint
5332
+ }),
5184
5333
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5185
5334
  className: "dsha-muted",
5186
5335
  children: t.cacheHint
@@ -5206,11 +5355,12 @@ window.__ModuleLoader__.load({
5206
5355
  children: t.modelsHint
5207
5356
  }),
5208
5357
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelChecklist, {
5209
- items: (status?.models ?? []).map((model) => ({
5358
+ items: models.map((model) => ({
5210
5359
  id: model.id,
5211
5360
  name: model.name,
5212
5361
  hint: [
5213
- model.wire === "anthropic" ? t.wireAnthropic : t.wireOpenai,
5362
+ wireLabel(model.wire, t),
5363
+ ...model.thinkingType === "only" ? [t.capThinkingOnly] : [],
5214
5364
  ...model.supportsVideo ? [t.capVideo] : [],
5215
5365
  ...model.supportsDynamicTools ? [t.capDynamicTools] : [],
5216
5366
  ...model.minimumPlan ? [t.capPlan.replace("{plan}", model.minimumPlan)] : []
@@ -5226,7 +5376,7 @@ window.__ModuleLoader__.load({
5226
5376
  list: t.modelsSection
5227
5377
  }
5228
5378
  }),
5229
- status !== null && status.models.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KimiModelCapabilities, { models: status.models })
5379
+ status !== null && models.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KimiModelCapabilities, { models })
5230
5380
  ]
5231
5381
  }),
5232
5382
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
@@ -5250,15 +5400,30 @@ window.__ModuleLoader__.load({
5250
5400
  const value = event.currentTarget.value;
5251
5401
  handleUpdateEffort(value === "" ? null : value);
5252
5402
  },
5253
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5254
- value: "",
5255
- children: t.defaultEffortAuto
5256
- }), KIMI_CODE_REASONING_EFFORTS.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5257
- value: effort,
5258
- children: effortLabel(effort, t)
5259
- }, effort))]
5403
+ children: [
5404
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5405
+ value: "",
5406
+ children: t.defaultEffortAuto
5407
+ }),
5408
+ offeredEfforts.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5409
+ value: effort,
5410
+ children: effortLabel(effort, t)
5411
+ }, effort)),
5412
+ staleEffort !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
5413
+ value: staleEffort,
5414
+ children: [
5415
+ effortLabel(staleEffort, t),
5416
+ " · ",
5417
+ t.effortNotOffered
5418
+ ]
5419
+ })
5420
+ ]
5260
5421
  })]
5261
5422
  }),
5423
+ thinkingOnly.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5424
+ className: "dsha-notice",
5425
+ children: t.effortThinkingOnlyNote.replace("{models}", thinkingOnly.map((model) => model.name).join(" · "))
5426
+ }),
5262
5427
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5263
5428
  className: "dsha-pref-row",
5264
5429
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.cacheTtl }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -19071,10 +19236,13 @@ window.__ModuleLoader__.load({
19071
19236
  wireAnthropic: "Anthropic",
19072
19237
  wireOpenai: "OpenAI",
19073
19238
  capVideo: "Видео*",
19239
+ capThinkingOnly: "Только рассуждения",
19240
+ capEfforts: "Уровни {list}",
19074
19241
  capDynamicTools: "Динамические инструменты",
19075
19242
  capImageOnly: "Изображения",
19076
19243
  capNone: "—",
19077
19244
  capVideoFootnote: "* Видео подключается инструментом kimi_attach_video (абсолютный локальный путь или ссылка http(s)); вставка и загрузка по-прежнему принимают только изображения.",
19245
+ capThinkingOnlyFootnote: "* У модели с пометкой «только рассуждения» нельзя отключить рассуждения: запрос с none сервис отклоняет (HTTP 400), поэтому уровня «рассуждения выкл.» у неё нет.",
19078
19246
  capabilitiesTitle: "Возможности",
19079
19247
  capColMedia: "Мультимодальность",
19080
19248
  capColTools: "Динамические инструменты",
@@ -19085,13 +19253,16 @@ window.__ModuleLoader__.load({
19085
19253
  speedRegular: "Обычная",
19086
19254
  speedHighspeed: "Ускоренная (~6×)",
19087
19255
  quotaCost: "Множитель квоты",
19256
+ quotaUnknown: "Не опубликовано",
19088
19257
  minimumPlan: "Нужный тариф",
19089
19258
  enhanced: "Рассуждения",
19090
19259
  defaultReasoningEffort: "Уровень рассуждений по умолчанию",
19091
- defaultReasoningEffortHint: "Kimi Code принимает только low / high / max; none отключает рассуждения. Смена уровня сбрасывает кеш контекста, поэтому в пределах сессии держите его неизменным.",
19260
+ defaultReasoningEffortHint: "Набор уровней следует тому, что заявляют отмеченные модели (если не отмечено ни одной — все четыре: low / high / max / none); none отключает рассуждения и действует только для моделей, которые это позволяют. Смена уровня сбрасывает кеш контекста, поэтому в пределах сессии держите его неизменным.",
19261
+ effortThinkingOnlyNote: "Среди отмеченных моделей есть те, что рассуждают всегда: {models}. Уровня «рассуждения выкл.» у них нет — такой запрос сервис отклоняет (HTTP 400), поэтому здесь он не предлагается.",
19262
+ effortNotOffered: "отмеченные модели это не принимают",
19092
19263
  cacheTtl: "Время жизни кеша контекста",
19093
- cacheTtlHint: "Kimi кеширует префиксы автоматически, здесь выбирается время записи. Запись на 1 ч стоит примерно вдвое дороже записи на 5 мин и окупается, только если тот же префикс перечитывается в течение часа. Уровень фиксируется при первой записи и позже не меняется. Пустое значение — поле не отправляется, решает Kimi (измеренное время жизни — примерно 5–30 минут). Выбирайте по паузе между ходами: если она обычно короче ~30 минут, оставьте пусто или 5 минут; для сессий с долгим простоем, например диспетчера, ждущего субагентов, — 1 час.",
19094
- cacheTtlDefault: "Не задавать (по умолчанию Kimi)",
19264
+ cacheTtlHint: "Kimi кеширует префиксы автоматически, здесь выбирается уровень записи, и их всего два: 5m и 1h. Пустое значение — поле не отправляется, и тогда сервис пишет на уровне 5 минут. Запись на 1 ч стоит примерно вдвое дороже записи на 5 мин и окупается, только если тот же префикс перечитывается в течение часа. Уровень фиксируется при первой записи, а попадания продлевают её по исходному TTL. Выбирайте по паузе между ходами: 5 минут, если она обычно короче ~30 минут; 1 час для сессий с долгим простоем, например диспетчера, ждущего субагентов.",
19265
+ cacheTtlDefault: "Не передавать (сервис пишет на уровне 5 минут)",
19095
19266
  cacheTtl5m: "5 минут",
19096
19267
  cacheTtl1h: "1 час",
19097
19268
  defaultEffortAuto: "Как в модели по умолчанию",
@@ -19117,6 +19288,11 @@ window.__ModuleLoader__.load({
19117
19288
  cacheFresh: "Новые токены",
19118
19289
  cacheOutput: "Выходные токены",
19119
19290
  cacheRequests: "Запросы",
19291
+ cacheWrite: "Запись в кеш",
19292
+ cacheWrite5m: "Уровень 5 минут",
19293
+ cacheWrite1h: "Уровень 1 час",
19294
+ cacheWriteHint: "Запись — отдельная статья биллинга: запись на 1 ч стоит примерно вдвое дороже записи на 5 мин, а попадание продлевает её по исходному TTL. 0 на уровне означает, что сервис не сообщил запись для этого уровня (отсутствующий заголовок — молчание), а не то, что там ничего не записали.",
19295
+ unknownMetric: "нет данных",
19120
19296
  cacheHint: "В пределах одной сессии: любое изменение системного промпта или списка инструментов сбрасывает весь префиксный кеш, поэтому держите набор инструментов стабильным, а новое добавляйте в конец — так доля попаданий выше.",
19121
19297
  cacheExpired: "Сессия простаивала дольше времени жизни кеша, поэтому следующий ход заново обработает около {tokens} токенов.",
19122
19298
  cacheDrift: "Состояние последнего префикса",