dskcode 0.1.11 → 0.1.13
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/README.md +1 -0
- package/dist/{chunk-DIZMSV5H.js → chunk-7QS2XBBX.js} +2 -4
- package/dist/{chunk-DIZMSV5H.js.map → chunk-7QS2XBBX.js.map} +1 -1
- package/dist/{chunk-FODNQIT4.js → chunk-HWZZJB6I.js} +2 -2
- package/dist/deepseek-OUOEENTK.js +8 -0
- package/dist/index.js +191 -40
- package/dist/index.js.map +1 -1
- package/dist/{models-NQGNKB4T.js → models-OL7DHYGK.js} +2 -2
- package/package.json +1 -1
- package/dist/deepseek-OIJOG3N5.js +0 -8
- /package/dist/{chunk-FODNQIT4.js.map → chunk-HWZZJB6I.js.map} +0 -0
- /package/dist/{deepseek-OIJOG3N5.js.map → deepseek-OUOEENTK.js.map} +0 -0
- /package/dist/{models-NQGNKB4T.js.map → models-OL7DHYGK.js.map} +0 -0
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
+

|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
## 特性
|
|
@@ -68,9 +68,7 @@ function calculateCost(usage, model) {
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
function formatCost(cost) {
|
|
71
|
-
|
|
72
|
-
const formatted = total < 0.01 ? total.toFixed(6) : total.toFixed(4);
|
|
73
|
-
return `\u2248\xA5${formatted}`;
|
|
71
|
+
return `\u2248\xA5${cost.totalCost.toFixed(4)}`;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
export {
|
|
@@ -82,4 +80,4 @@ export {
|
|
|
82
80
|
calculateCost,
|
|
83
81
|
formatCost
|
|
84
82
|
};
|
|
85
|
-
//# sourceMappingURL=chunk-
|
|
83
|
+
//# sourceMappingURL=chunk-7QS2XBBX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/models.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\r\n// 模型定义与校验\r\n// ---------------------------------------------------------------------------\r\n\r\nimport type { ModelId, ModelMeta } from \"./types.js\";\r\n\r\n/** 支持的模型及其元数据 */\r\nexport const SUPPORTED_MODELS: Record<ModelId, ModelMeta> = {\r\n \"deepseek-v4-flash\": {\r\n id: \"deepseek-v4-flash\",\r\n displayName: \"DeepSeek V4 Flash\",\r\n /** 上下文窗口大小(token) */\r\n contextWindow: 1_000_000,\r\n /** 输入价格(元 / 百万 token,缓存未命中) */\r\n inputPricePerMillion: 1,\r\n /** 输出价格(元 / 百万 token) */\r\n outputPricePerMillion: 2,\r\n /** 输入价格(元 / 百万 token,缓存命中) */\r\n cacheHitPricePerMillion: 0.02,\r\n },\r\n \"deepseek-v4-pro\": {\r\n id: \"deepseek-v4-pro\",\r\n displayName: \"DeepSeek V4 Pro\",\r\n /** 上下文窗口大小(token) */\r\n contextWindow: 1_000_000,\r\n /** 输入价格(元 / 百万 token,缓存未命中) */\r\n inputPricePerMillion: 3,\r\n /** 输出价格(元 / 百万 token) */\r\n outputPricePerMillion: 6,\r\n /** 输入价格(元 / 百万 token,缓存命中) */\r\n cacheHitPricePerMillion: 0.025,\r\n },\r\n};\r\n\r\n/** 支持的模型 ID 列表 */\r\nexport const SUPPORTED_MODEL_IDS: string[] = Object.keys(SUPPORTED_MODELS);\r\n\r\n/**\r\n * 判断模型标识是否受支持。\r\n * dskcode 仅支持 deepseek-v4-flash 和 deepseek-v4-pro 两个模型。\r\n */\r\nexport function isSupportedModel(model: string): model is ModelId {\r\n return model in SUPPORTED_MODELS;\r\n}\r\n\r\n/** 获取模型元数据(已校验) */\r\nexport function getModelMeta(model: ModelId): ModelMeta {\r\n return SUPPORTED_MODELS[model];\r\n}\r\n\r\n/**\r\n * CJK 字符 Unicode 范围检测。\r\n * 覆盖 CJK 统一汉字、扩展 A/B、兼容汉字等。\r\n */\r\nfunction isCJK(char: string): boolean {\r\n const code = char.codePointAt(0)!;\r\n // CJK 统一汉字\r\n return (\r\n (code >= 0x4e00 && code <= 0x9fff) ||\r\n // CJK 扩展 A\r\n (code >= 0x3400 && code <= 0x4dbf) ||\r\n // CJK 扩展 B 及其他\r\n (code >= 0x20000 && code <= 0x2a6df) ||\r\n // CJK 兼容汉字\r\n (code >= 0xf900 && code <= 0xfaff) ||\r\n // 全角字符\r\n (code >= 0xff01 && code <= 0xff60)\r\n );\r\n}\r\n\r\n/**\r\n * 估算文本的 token 数量。\r\n *\r\n * 根据 DeepSeek 官方文档的换算比例:\r\n * - 1 个英文字符 ≈ 0.3 个 token(即约 3.3 个字符 ≈ 1 token)\r\n * - 1 个中文字符 ≈ 0.6 个 token(即约 1.7 个字符 ≈ 1 token)\r\n *\r\n * 对文本中的 CJK 和非 CJK 字符分别估算后求和。\r\n */\r\nexport function estimateTokens(text: string): number {\r\n let cjkCount = 0;\r\n let otherCount = 0;\r\n for (const char of text) {\r\n if (isCJK(char)) {\r\n cjkCount++;\r\n } else {\r\n otherCount++;\r\n }\r\n }\r\n // CJK: 1 字符 ≈ 0.6 token → token 数 ≈ cjkCount × 0.6\r\n // 其他: 1 字符 ≈ 0.3 token → token 数 ≈ otherCount × 0.3\r\n const tokens = cjkCount * 0.6 + otherCount * 0.3;\r\n return Math.max(1, Math.ceil(tokens));\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// 费用计算\r\n// ---------------------------------------------------------------------------\r\n\r\nimport type { UsageInfo, CostInfo } from \"./types.js\";\r\n\r\n/**\r\n * 根据模型和 Token 使用量计算费用。\r\n *\r\n * 计费公式:\r\n * 输入费用(缓存未命中) = (promptTokens - cachedPromptTokens) × inputPrice / 1,000,000\r\n * 缓存命中费用 = cachedPromptTokens × cacheHitPrice / 1,000,000\r\n * 输出费用 = completionTokens × outputPrice / 1,000,000\r\n * 总费用 = 输入费用 + 缓存命中费用 + 输出费用\r\n *\r\n * @param usage Token 使用统计\r\n * @param model 模型标识\r\n * @returns 费用明细(单位:元)\r\n */\r\nexport function calculateCost(usage: UsageInfo, model: ModelId): CostInfo {\r\n const meta = SUPPORTED_MODELS[model];\r\n const cached = usage.cachedPromptTokens ?? 0;\r\n const nonCached = usage.promptTokens - cached;\r\n\r\n const inputCost = (nonCached * meta.inputPricePerMillion) / 1_000_000;\r\n const cacheHitCost = (cached * meta.cacheHitPricePerMillion) / 1_000_000;\r\n const outputCost = (usage.completionTokens * meta.outputPricePerMillion) / 1_000_000;\r\n\r\n return {\r\n inputCost,\r\n cacheHitCost,\r\n outputCost,\r\n totalCost: inputCost + cacheHitCost + outputCost,\r\n };\r\n}\r\n\r\n/**\r\n *
|
|
1
|
+
{"version":3,"sources":["../src/provider/models.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\r\n// 模型定义与校验\r\n// ---------------------------------------------------------------------------\r\n\r\nimport type { ModelId, ModelMeta } from \"./types.js\";\r\n\r\n/** 支持的模型及其元数据 */\r\nexport const SUPPORTED_MODELS: Record<ModelId, ModelMeta> = {\r\n \"deepseek-v4-flash\": {\r\n id: \"deepseek-v4-flash\",\r\n displayName: \"DeepSeek V4 Flash\",\r\n /** 上下文窗口大小(token) */\r\n contextWindow: 1_000_000,\r\n /** 输入价格(元 / 百万 token,缓存未命中) */\r\n inputPricePerMillion: 1,\r\n /** 输出价格(元 / 百万 token) */\r\n outputPricePerMillion: 2,\r\n /** 输入价格(元 / 百万 token,缓存命中) */\r\n cacheHitPricePerMillion: 0.02,\r\n },\r\n \"deepseek-v4-pro\": {\r\n id: \"deepseek-v4-pro\",\r\n displayName: \"DeepSeek V4 Pro\",\r\n /** 上下文窗口大小(token) */\r\n contextWindow: 1_000_000,\r\n /** 输入价格(元 / 百万 token,缓存未命中) */\r\n inputPricePerMillion: 3,\r\n /** 输出价格(元 / 百万 token) */\r\n outputPricePerMillion: 6,\r\n /** 输入价格(元 / 百万 token,缓存命中) */\r\n cacheHitPricePerMillion: 0.025,\r\n },\r\n};\r\n\r\n/** 支持的模型 ID 列表 */\r\nexport const SUPPORTED_MODEL_IDS: string[] = Object.keys(SUPPORTED_MODELS);\r\n\r\n/**\r\n * 判断模型标识是否受支持。\r\n * dskcode 仅支持 deepseek-v4-flash 和 deepseek-v4-pro 两个模型。\r\n */\r\nexport function isSupportedModel(model: string): model is ModelId {\r\n return model in SUPPORTED_MODELS;\r\n}\r\n\r\n/** 获取模型元数据(已校验) */\r\nexport function getModelMeta(model: ModelId): ModelMeta {\r\n return SUPPORTED_MODELS[model];\r\n}\r\n\r\n/**\r\n * CJK 字符 Unicode 范围检测。\r\n * 覆盖 CJK 统一汉字、扩展 A/B、兼容汉字等。\r\n */\r\nfunction isCJK(char: string): boolean {\r\n const code = char.codePointAt(0)!;\r\n // CJK 统一汉字\r\n return (\r\n (code >= 0x4e00 && code <= 0x9fff) ||\r\n // CJK 扩展 A\r\n (code >= 0x3400 && code <= 0x4dbf) ||\r\n // CJK 扩展 B 及其他\r\n (code >= 0x20000 && code <= 0x2a6df) ||\r\n // CJK 兼容汉字\r\n (code >= 0xf900 && code <= 0xfaff) ||\r\n // 全角字符\r\n (code >= 0xff01 && code <= 0xff60)\r\n );\r\n}\r\n\r\n/**\r\n * 估算文本的 token 数量。\r\n *\r\n * 根据 DeepSeek 官方文档的换算比例:\r\n * - 1 个英文字符 ≈ 0.3 个 token(即约 3.3 个字符 ≈ 1 token)\r\n * - 1 个中文字符 ≈ 0.6 个 token(即约 1.7 个字符 ≈ 1 token)\r\n *\r\n * 对文本中的 CJK 和非 CJK 字符分别估算后求和。\r\n */\r\nexport function estimateTokens(text: string): number {\r\n let cjkCount = 0;\r\n let otherCount = 0;\r\n for (const char of text) {\r\n if (isCJK(char)) {\r\n cjkCount++;\r\n } else {\r\n otherCount++;\r\n }\r\n }\r\n // CJK: 1 字符 ≈ 0.6 token → token 数 ≈ cjkCount × 0.6\r\n // 其他: 1 字符 ≈ 0.3 token → token 数 ≈ otherCount × 0.3\r\n const tokens = cjkCount * 0.6 + otherCount * 0.3;\r\n return Math.max(1, Math.ceil(tokens));\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// 费用计算\r\n// ---------------------------------------------------------------------------\r\n\r\nimport type { UsageInfo, CostInfo } from \"./types.js\";\r\n\r\n/**\r\n * 根据模型和 Token 使用量计算费用。\r\n *\r\n * 计费公式:\r\n * 输入费用(缓存未命中) = (promptTokens - cachedPromptTokens) × inputPrice / 1,000,000\r\n * 缓存命中费用 = cachedPromptTokens × cacheHitPrice / 1,000,000\r\n * 输出费用 = completionTokens × outputPrice / 1,000,000\r\n * 总费用 = 输入费用 + 缓存命中费用 + 输出费用\r\n *\r\n * @param usage Token 使用统计\r\n * @param model 模型标识\r\n * @returns 费用明细(单位:元)\r\n */\r\nexport function calculateCost(usage: UsageInfo, model: ModelId): CostInfo {\r\n const meta = SUPPORTED_MODELS[model];\r\n const cached = usage.cachedPromptTokens ?? 0;\r\n const nonCached = usage.promptTokens - cached;\r\n\r\n const inputCost = (nonCached * meta.inputPricePerMillion) / 1_000_000;\r\n const cacheHitCost = (cached * meta.cacheHitPricePerMillion) / 1_000_000;\r\n const outputCost = (usage.completionTokens * meta.outputPricePerMillion) / 1_000_000;\r\n\r\n return {\r\n inputCost,\r\n cacheHitCost,\r\n outputCost,\r\n totalCost: inputCost + cacheHitCost + outputCost,\r\n };\r\n}\r\n\r\n/**\r\n * 将费用格式化为易读的字符串,保留4位小数。\r\n */\r\nexport function formatCost(cost: CostInfo): string {\r\n return `≈¥${cost.totalCost.toFixed(4)}`;\r\n}"],"mappings":";AAOO,IAAM,mBAA+C;AAAA,EAC1D,qBAAqB;AAAA,IACnB,IAAI;AAAA,IACJ,aAAa;AAAA;AAAA,IAEb,eAAe;AAAA;AAAA,IAEf,sBAAsB;AAAA;AAAA,IAEtB,uBAAuB;AAAA;AAAA,IAEvB,yBAAyB;AAAA,EAC3B;AAAA,EACA,mBAAmB;AAAA,IACjB,IAAI;AAAA,IACJ,aAAa;AAAA;AAAA,IAEb,eAAe;AAAA;AAAA,IAEf,sBAAsB;AAAA;AAAA,IAEtB,uBAAuB;AAAA;AAAA,IAEvB,yBAAyB;AAAA,EAC3B;AACF;AAGO,IAAM,sBAAgC,OAAO,KAAK,gBAAgB;AAMlE,SAAS,iBAAiB,OAAiC;AAChE,SAAO,SAAS;AAClB;AAGO,SAAS,aAAa,OAA2B;AACtD,SAAO,iBAAiB,KAAK;AAC/B;AAMA,SAAS,MAAM,MAAuB;AACpC,QAAM,OAAO,KAAK,YAAY,CAAC;AAE/B,SACG,QAAQ,SAAU,QAAQ;AAAA,EAE1B,QAAQ,SAAU,QAAQ;AAAA,EAE1B,QAAQ,UAAW,QAAQ;AAAA,EAE3B,QAAQ,SAAU,QAAQ;AAAA,EAE1B,QAAQ,SAAU,QAAQ;AAE/B;AAWO,SAAS,eAAe,MAAsB;AACnD,MAAI,WAAW;AACf,MAAI,aAAa;AACjB,aAAW,QAAQ,MAAM;AACvB,QAAI,MAAM,IAAI,GAAG;AACf;AAAA,IACF,OAAO;AACL;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,WAAW,MAAM,aAAa;AAC7C,SAAO,KAAK,IAAI,GAAG,KAAK,KAAK,MAAM,CAAC;AACtC;AAqBO,SAAS,cAAc,OAAkB,OAA0B;AACxE,QAAM,OAAO,iBAAiB,KAAK;AACnC,QAAM,SAAS,MAAM,sBAAsB;AAC3C,QAAM,YAAY,MAAM,eAAe;AAEvC,QAAM,YAAa,YAAY,KAAK,uBAAwB;AAC5D,QAAM,eAAgB,SAAS,KAAK,0BAA2B;AAC/D,QAAM,aAAc,MAAM,mBAAmB,KAAK,wBAAyB;AAE3E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,YAAY,eAAe;AAAA,EACxC;AACF;AAKO,SAAS,WAAW,MAAwB;AACjD,SAAO,aAAK,KAAK,UAAU,QAAQ,CAAC,CAAC;AACvC;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
estimateTokens,
|
|
3
3
|
getModelMeta
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7QS2XBBX.js";
|
|
5
5
|
|
|
6
6
|
// src/provider/errors.ts
|
|
7
7
|
var ProviderError = class extends Error {
|
|
@@ -623,4 +623,4 @@ export {
|
|
|
623
623
|
ModelNotSupportedError,
|
|
624
624
|
DeepSeekProvider
|
|
625
625
|
};
|
|
626
|
-
//# sourceMappingURL=chunk-
|
|
626
|
+
//# sourceMappingURL=chunk-HWZZJB6I.js.map
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DeepSeekProvider,
|
|
4
4
|
ModelNotSupportedError
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HWZZJB6I.js";
|
|
6
6
|
import {
|
|
7
|
+
SUPPORTED_MODELS,
|
|
7
8
|
calculateCost,
|
|
8
9
|
estimateTokens,
|
|
9
10
|
getModelMeta,
|
|
10
11
|
isSupportedModel
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7QS2XBBX.js";
|
|
12
13
|
|
|
13
14
|
// src/cli/index.tsx
|
|
14
15
|
import { Command } from "commander";
|
|
@@ -303,6 +304,34 @@ async function saveApiKey(apiKey) {
|
|
|
303
304
|
await writeFile(configFile, JSON.stringify(configData, null, 2), "utf-8");
|
|
304
305
|
return configFile;
|
|
305
306
|
}
|
|
307
|
+
async function saveModelConfig(model) {
|
|
308
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "~";
|
|
309
|
+
const configDir = join(home, ".dskcode");
|
|
310
|
+
const configFile = join(configDir, "settings.json");
|
|
311
|
+
await mkdir(configDir, { recursive: true });
|
|
312
|
+
let configData;
|
|
313
|
+
try {
|
|
314
|
+
const raw = await readFile(configFile, "utf-8");
|
|
315
|
+
configData = JSON.parse(raw);
|
|
316
|
+
} catch {
|
|
317
|
+
configData = structuredClone(defaultConfig);
|
|
318
|
+
}
|
|
319
|
+
const providers = configData.providers ?? [];
|
|
320
|
+
const defaultProviderName = configData.defaultProvider ?? "deepseek";
|
|
321
|
+
const existing = providers.find((p) => p.name === defaultProviderName);
|
|
322
|
+
if (existing) {
|
|
323
|
+
existing.model = model;
|
|
324
|
+
} else {
|
|
325
|
+
providers.push({
|
|
326
|
+
name: defaultProviderName,
|
|
327
|
+
baseUrl: "https://api.deepseek.com",
|
|
328
|
+
model
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
configData.providers = providers;
|
|
332
|
+
await writeFile(configFile, JSON.stringify(configData, null, 2), "utf-8");
|
|
333
|
+
return configFile;
|
|
334
|
+
}
|
|
306
335
|
async function saveStockConfig(symbols) {
|
|
307
336
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "~";
|
|
308
337
|
const configDir = join(home, ".dskcode");
|
|
@@ -820,10 +849,7 @@ function createEmptyDailySummary(date) {
|
|
|
820
849
|
};
|
|
821
850
|
}
|
|
822
851
|
function formatMoney(yuan) {
|
|
823
|
-
|
|
824
|
-
if (yuan < 0.01) return `\xA5${yuan.toFixed(6)}`;
|
|
825
|
-
if (yuan < 1) return `\xA5${yuan.toFixed(4)}`;
|
|
826
|
-
return `\xA5${yuan.toFixed(2)}`;
|
|
852
|
+
return `\xA5${yuan.toFixed(4)}`;
|
|
827
853
|
}
|
|
828
854
|
|
|
829
855
|
// src/ui/ToolCallBlock.tsx
|
|
@@ -1308,6 +1334,14 @@ var IDLE_GRADIENT_STOPS = [
|
|
|
1308
1334
|
[189, 147, 249]
|
|
1309
1335
|
// #bd93f9
|
|
1310
1336
|
];
|
|
1337
|
+
var CMD_TIP_GRADIENT_STOPS = [
|
|
1338
|
+
[255, 245, 180],
|
|
1339
|
+
// #fff5b4 浅柠黄
|
|
1340
|
+
[255, 210, 80],
|
|
1341
|
+
// #ffd250 暖黄
|
|
1342
|
+
[255, 150, 50]
|
|
1343
|
+
// #ff9632 橙色
|
|
1344
|
+
];
|
|
1311
1345
|
var STREAMING_GRADIENT_STOPS = [
|
|
1312
1346
|
[255, 191, 0],
|
|
1313
1347
|
// #ffbf00 琥珀金
|
|
@@ -1324,7 +1358,11 @@ var GRADIENT_ANIMATION = {
|
|
|
1324
1358
|
/** 流式占位符动画:每帧相位步进 */
|
|
1325
1359
|
streamingPhaseStep: 0.05,
|
|
1326
1360
|
/** 流式占位符动画:帧间隔(ms) */
|
|
1327
|
-
streamingInterval: 40
|
|
1361
|
+
streamingInterval: 40,
|
|
1362
|
+
/** 命令提示条动画:每帧相位步进 */
|
|
1363
|
+
cmdTipPhaseStep: 0.05,
|
|
1364
|
+
/** 命令提示条动画:帧间隔(ms) */
|
|
1365
|
+
cmdTipInterval: 40
|
|
1328
1366
|
};
|
|
1329
1367
|
var SKIP_CHARS = /* @__PURE__ */ new Set([" ", "~", ".", "\u3002", "\uFF01", "\u{1F447}"]);
|
|
1330
1368
|
function lerpStopsToHex(t, stops) {
|
|
@@ -1351,7 +1389,7 @@ function getGradientColors(text, phase, stops) {
|
|
|
1351
1389
|
}
|
|
1352
1390
|
|
|
1353
1391
|
// src/ui/ChatSession.tsx
|
|
1354
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1392
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1355
1393
|
var commandRegistry = /* @__PURE__ */ new Map();
|
|
1356
1394
|
function registerCommand(name, cmd) {
|
|
1357
1395
|
commandRegistry.set(name, cmd);
|
|
@@ -1374,6 +1412,7 @@ registerCommand("/help", {
|
|
|
1374
1412
|
});
|
|
1375
1413
|
registerCommand("/clear", { desc: "\u6E05\u7A7A\u5BF9\u8BDD\u5386\u53F2", handler: () => ({ kind: "clear" }) });
|
|
1376
1414
|
registerCommand("/version", { desc: "\u663E\u793A\u7248\u672C\u4FE1\u606F", handler: () => ({ kind: "text", content: "dskcode v0.1.10" }) });
|
|
1415
|
+
registerCommand("/model", { desc: "\u5207\u6362\u6A21\u578B", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /model \u8FDB\u5165\u9009\u62E9\u754C\u9762" }) });
|
|
1377
1416
|
registerCommand("/game", { desc: "\u542F\u52A8\u6E38\u620F", handler: () => ({ kind: "navigate", target: "game" }) });
|
|
1378
1417
|
registerCommand("/stock", { desc: "\u67E5\u770B\u80A1\u7968\u884C\u60C5", handler: () => ({ kind: "navigate", target: "stock" }) });
|
|
1379
1418
|
var STREAMING_PLACEHOLDERS = [
|
|
@@ -1388,7 +1427,7 @@ var IDLE_PLACEHOLDERS = [
|
|
|
1388
1427
|
"\u60F3\u5E72\u5565\uFF1F\u76F4\u63A5\u8BF4~",
|
|
1389
1428
|
"\u6765\u5427\uFF0C\u5429\u5490\u70B9\u5565",
|
|
1390
1429
|
"\u968F\u65F6\u5F85\u547D...",
|
|
1391
|
-
"\u6233\u8FD9\u91CC\u5F00\u804A
|
|
1430
|
+
"\u6233\u8FD9\u91CC\u5F00\u804A...",
|
|
1392
1431
|
"\u7B49\u4F60\u5F00\u53E3...",
|
|
1393
1432
|
"\u5C3D\u7BA1\u4F7F\u5524~"
|
|
1394
1433
|
];
|
|
@@ -1410,6 +1449,7 @@ function ChatSession({
|
|
|
1410
1449
|
const dividerWidth = Math.max(termWidth - 2, 1);
|
|
1411
1450
|
const [offset, setOffset] = useState3(0);
|
|
1412
1451
|
const [displayMessages, setDisplayMessages] = useState3([]);
|
|
1452
|
+
const [staticKey, setStaticKey] = useState3(0);
|
|
1413
1453
|
const [input, setInput] = useState3("");
|
|
1414
1454
|
const [balance, setBalance] = useState3(null);
|
|
1415
1455
|
const [balanceLoading, setBalanceLoading] = useState3(false);
|
|
@@ -1426,8 +1466,16 @@ function ChatSession({
|
|
|
1426
1466
|
const [currentUsage, setCurrentUsage] = useState3(void 0);
|
|
1427
1467
|
const [currentElapsed, setCurrentElapsed] = useState3(void 0);
|
|
1428
1468
|
const [currentCost, setCurrentCost] = useState3(void 0);
|
|
1429
|
-
const [
|
|
1469
|
+
const [activeModel, setActiveModel] = useState3(model);
|
|
1470
|
+
const [streamingModel, setStreamingModel] = useState3(void 0);
|
|
1430
1471
|
const [streamError, setStreamError] = useState3(void 0);
|
|
1472
|
+
const cmdTips = Array.from(getRegisteredCommands()).filter(([name]) => name !== "/exit" && name !== "/quit").map(([name, cmd]) => ({ name, desc: cmd.desc }));
|
|
1473
|
+
const [cmdTipIndex, setCmdTipIndex] = useState3(0);
|
|
1474
|
+
const [cmdTipGradientColors, setCmdTipGradientColors] = useState3([]);
|
|
1475
|
+
const cmdTipPhaseRef = useRef2(0);
|
|
1476
|
+
const [selectingModel, setSelectingModel] = useState3(false);
|
|
1477
|
+
const [modelSelectIndex, setModelSelectIndex] = useState3(0);
|
|
1478
|
+
const modelOptions = ["deepseek-v4-flash", "deepseek-v4-pro"];
|
|
1431
1479
|
const sessionRef = useRef2(null);
|
|
1432
1480
|
const abortRef = useRef2(null);
|
|
1433
1481
|
const currentContentRef = useRef2("");
|
|
@@ -1443,6 +1491,34 @@ function ChatSession({
|
|
|
1443
1491
|
useInput(
|
|
1444
1492
|
useCallback2(
|
|
1445
1493
|
(_input, key) => {
|
|
1494
|
+
if (selectingModel) {
|
|
1495
|
+
if (key.upArrow) {
|
|
1496
|
+
setModelSelectIndex((prev) => (prev - 1 + modelOptions.length) % modelOptions.length);
|
|
1497
|
+
} else if (key.downArrow) {
|
|
1498
|
+
setModelSelectIndex((prev) => (prev + 1) % modelOptions.length);
|
|
1499
|
+
} else if (key.return) {
|
|
1500
|
+
const selected = modelOptions[modelSelectIndex];
|
|
1501
|
+
if (selected === activeModel) {
|
|
1502
|
+
setDisplayMessages((prev) => [
|
|
1503
|
+
...prev,
|
|
1504
|
+
{ role: "assistant", content: `\u5DF2\u7ECF\u5728\u4F7F\u7528 ${SUPPORTED_MODELS[selected].displayName}` }
|
|
1505
|
+
]);
|
|
1506
|
+
} else {
|
|
1507
|
+
setActiveModel(selected);
|
|
1508
|
+
sessionRef.current?.reset();
|
|
1509
|
+
saveModelConfig(selected).catch(() => {
|
|
1510
|
+
});
|
|
1511
|
+
setDisplayMessages((prev) => [
|
|
1512
|
+
...prev,
|
|
1513
|
+
{ role: "assistant", content: `\u6A21\u578B\u5DF2\u5207\u6362\u4E3A ${SUPPORTED_MODELS[selected].displayName}\uFF08${selected}\uFF09` }
|
|
1514
|
+
]);
|
|
1515
|
+
}
|
|
1516
|
+
setSelectingModel(false);
|
|
1517
|
+
} else if (key.escape) {
|
|
1518
|
+
setSelectingModel(false);
|
|
1519
|
+
}
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1446
1522
|
if (key.ctrl && _input === "c") {
|
|
1447
1523
|
if (isStreaming) {
|
|
1448
1524
|
abortRef.current?.abort();
|
|
@@ -1455,9 +1531,31 @@ function ChatSession({
|
|
|
1455
1531
|
setInput(_input);
|
|
1456
1532
|
}
|
|
1457
1533
|
},
|
|
1458
|
-
[isStreaming, handleCtrlC, input]
|
|
1534
|
+
[selectingModel, modelSelectIndex, modelOptions, activeModel, isStreaming, handleCtrlC, input]
|
|
1459
1535
|
)
|
|
1460
1536
|
);
|
|
1537
|
+
useEffect3(() => {
|
|
1538
|
+
if (cmdTips.length <= 1) return;
|
|
1539
|
+
const timer = setInterval(() => {
|
|
1540
|
+
setCmdTipIndex((prev) => (prev + 1) % cmdTips.length);
|
|
1541
|
+
}, 5e3);
|
|
1542
|
+
return () => clearInterval(timer);
|
|
1543
|
+
}, [cmdTips.length]);
|
|
1544
|
+
useEffect3(() => {
|
|
1545
|
+
const tip = cmdTips[cmdTipIndex % cmdTips.length];
|
|
1546
|
+
if (!tip) {
|
|
1547
|
+
setCmdTipGradientColors([]);
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
const text = `${tip.name} ${tip.desc}`;
|
|
1551
|
+
cmdTipPhaseRef.current = 0;
|
|
1552
|
+
setCmdTipGradientColors(getGradientColors(text, 1, CMD_TIP_GRADIENT_STOPS));
|
|
1553
|
+
const interval = setInterval(() => {
|
|
1554
|
+
cmdTipPhaseRef.current = (cmdTipPhaseRef.current + GRADIENT_ANIMATION.cmdTipPhaseStep) % 1;
|
|
1555
|
+
setCmdTipGradientColors(getGradientColors(text, 1 - cmdTipPhaseRef.current, CMD_TIP_GRADIENT_STOPS));
|
|
1556
|
+
}, GRADIENT_ANIMATION.cmdTipInterval);
|
|
1557
|
+
return () => clearInterval(interval);
|
|
1558
|
+
}, [cmdTipIndex, cmdTips.length]);
|
|
1461
1559
|
useEffect3(() => {
|
|
1462
1560
|
const timer = setInterval(() => {
|
|
1463
1561
|
setOffset((prev) => (prev + 1) % CYBER_PALETTE.length);
|
|
@@ -1470,7 +1568,7 @@ function ChatSession({
|
|
|
1470
1568
|
name: "deepseek",
|
|
1471
1569
|
apiKey,
|
|
1472
1570
|
baseUrl,
|
|
1473
|
-
model
|
|
1571
|
+
model: activeModel
|
|
1474
1572
|
});
|
|
1475
1573
|
const tracker = externalCostTracker ?? new CostTracker();
|
|
1476
1574
|
const session = new Session(provider, [], tracker, {
|
|
@@ -1480,12 +1578,12 @@ function ChatSession({
|
|
|
1480
1578
|
return () => {
|
|
1481
1579
|
sessionRef.current = null;
|
|
1482
1580
|
};
|
|
1483
|
-
}, [apiKey, baseUrl,
|
|
1581
|
+
}, [apiKey, baseUrl, activeModel, externalCostTracker]);
|
|
1484
1582
|
useEffect3(() => {
|
|
1485
1583
|
if (!apiKey || !baseUrl) return;
|
|
1486
1584
|
let cancelled = false;
|
|
1487
1585
|
setBalanceLoading(true);
|
|
1488
|
-
import("./deepseek-
|
|
1586
|
+
import("./deepseek-OUOEENTK.js").then(({ DeepSeekProvider: DeepSeekProvider2 }) => {
|
|
1489
1587
|
const provider = new DeepSeekProvider2({
|
|
1490
1588
|
apiKey,
|
|
1491
1589
|
baseUrl,
|
|
@@ -1530,10 +1628,10 @@ function ChatSession({
|
|
|
1530
1628
|
return;
|
|
1531
1629
|
}
|
|
1532
1630
|
gradientPhaseRef.current = 0;
|
|
1533
|
-
setGradientColors(getGradientColors(idlePlaceholder,
|
|
1631
|
+
setGradientColors(getGradientColors(idlePlaceholder, 1, IDLE_GRADIENT_STOPS));
|
|
1534
1632
|
const interval = setInterval(() => {
|
|
1535
1633
|
gradientPhaseRef.current = (gradientPhaseRef.current + GRADIENT_ANIMATION.idlePhaseStep) % 1;
|
|
1536
|
-
setGradientColors(getGradientColors(idlePlaceholder, gradientPhaseRef.current, IDLE_GRADIENT_STOPS));
|
|
1634
|
+
setGradientColors(getGradientColors(idlePlaceholder, 1 - gradientPhaseRef.current, IDLE_GRADIENT_STOPS));
|
|
1537
1635
|
}, GRADIENT_ANIMATION.idleInterval);
|
|
1538
1636
|
return () => clearInterval(interval);
|
|
1539
1637
|
}, [isStreaming, idlePlaceholder]);
|
|
@@ -1543,10 +1641,10 @@ function ChatSession({
|
|
|
1543
1641
|
return;
|
|
1544
1642
|
}
|
|
1545
1643
|
streamingPhaseRef.current = 0;
|
|
1546
|
-
setStreamingGradientColors(getGradientColors(streamingPlaceholder,
|
|
1644
|
+
setStreamingGradientColors(getGradientColors(streamingPlaceholder, 1, STREAMING_GRADIENT_STOPS));
|
|
1547
1645
|
const interval = setInterval(() => {
|
|
1548
1646
|
streamingPhaseRef.current = (streamingPhaseRef.current + GRADIENT_ANIMATION.streamingPhaseStep) % 1;
|
|
1549
|
-
setStreamingGradientColors(getGradientColors(streamingPlaceholder, streamingPhaseRef.current, STREAMING_GRADIENT_STOPS));
|
|
1647
|
+
setStreamingGradientColors(getGradientColors(streamingPlaceholder, 1 - streamingPhaseRef.current, STREAMING_GRADIENT_STOPS));
|
|
1550
1648
|
}, GRADIENT_ANIMATION.streamingInterval);
|
|
1551
1649
|
return () => clearInterval(interval);
|
|
1552
1650
|
}, [isStreaming, streamingPlaceholder]);
|
|
@@ -1554,6 +1652,13 @@ function ChatSession({
|
|
|
1554
1652
|
const trimmed = value.trim();
|
|
1555
1653
|
if (!trimmed) return;
|
|
1556
1654
|
if (trimmed.startsWith("/")) {
|
|
1655
|
+
if (trimmed.toLowerCase() === "/model") {
|
|
1656
|
+
const curIdx = modelOptions.indexOf(activeModel);
|
|
1657
|
+
setModelSelectIndex(curIdx >= 0 ? curIdx : 0);
|
|
1658
|
+
setSelectingModel(true);
|
|
1659
|
+
setInput("");
|
|
1660
|
+
return;
|
|
1661
|
+
}
|
|
1557
1662
|
const cmd = commandRegistry.get(trimmed.toLowerCase());
|
|
1558
1663
|
if (cmd) {
|
|
1559
1664
|
const result = cmd.handler();
|
|
@@ -1563,7 +1668,10 @@ function ChatSession({
|
|
|
1563
1668
|
return;
|
|
1564
1669
|
case "clear":
|
|
1565
1670
|
setDisplayMessages([]);
|
|
1671
|
+
setStaticKey((prev) => prev + 1);
|
|
1566
1672
|
setInput("");
|
|
1673
|
+
setStreamError(void 0);
|
|
1674
|
+
process.stdout.write("\x1B[2J\x1B[H\x1B[3J");
|
|
1567
1675
|
sessionRef.current?.reset();
|
|
1568
1676
|
return;
|
|
1569
1677
|
case "navigate":
|
|
@@ -1613,7 +1721,7 @@ function ChatSession({
|
|
|
1613
1721
|
setCurrentUsage(void 0);
|
|
1614
1722
|
setCurrentElapsed(void 0);
|
|
1615
1723
|
setCurrentCost(void 0);
|
|
1616
|
-
|
|
1724
|
+
setStreamingModel(void 0);
|
|
1617
1725
|
setStreamError(void 0);
|
|
1618
1726
|
currentContentRef.current = "";
|
|
1619
1727
|
currentToolCallsRef.current = [];
|
|
@@ -1645,7 +1753,7 @@ function ChatSession({
|
|
|
1645
1753
|
break;
|
|
1646
1754
|
case "usage":
|
|
1647
1755
|
setCurrentUsage(event.usage);
|
|
1648
|
-
|
|
1756
|
+
setStreamingModel(event.model);
|
|
1649
1757
|
currentUsageRef.current = event.usage;
|
|
1650
1758
|
currentModelRef.current = event.model;
|
|
1651
1759
|
break;
|
|
@@ -1696,14 +1804,14 @@ function ChatSession({
|
|
|
1696
1804
|
}
|
|
1697
1805
|
}, [isStreaming, externalCostTracker]);
|
|
1698
1806
|
useEffect3(() => {
|
|
1699
|
-
if (currentUsage &&
|
|
1700
|
-
import("./models-
|
|
1701
|
-
const cost = calculateCost2(currentUsage,
|
|
1807
|
+
if (currentUsage && streamingModel && !currentCost) {
|
|
1808
|
+
import("./models-OL7DHYGK.js").then(({ calculateCost: calculateCost2 }) => {
|
|
1809
|
+
const cost = calculateCost2(currentUsage, streamingModel);
|
|
1702
1810
|
setCurrentCost(cost.totalCost);
|
|
1703
1811
|
currentCostRef.current = cost.totalCost;
|
|
1704
1812
|
});
|
|
1705
1813
|
}
|
|
1706
|
-
}, [currentUsage,
|
|
1814
|
+
}, [currentUsage, streamingModel, currentCost]);
|
|
1707
1815
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingLeft: 1, paddingRight: 1, children: [
|
|
1708
1816
|
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "row", marginBottom: 1, children: [
|
|
1709
1817
|
/* @__PURE__ */ jsx5(Box5, { flexDirection: "column", marginRight: 4, children: LOGO_LINES.map((line, i) => {
|
|
@@ -1725,8 +1833,17 @@ function ChatSession({
|
|
|
1725
1833
|
] }),
|
|
1726
1834
|
/* @__PURE__ */ jsxs5(Text6, { color: "#00ffff", children: [
|
|
1727
1835
|
" \u{1F527} \u6A21\u578B ",
|
|
1728
|
-
|
|
1836
|
+
SUPPORTED_MODELS[activeModel]?.displayName ?? activeModel
|
|
1729
1837
|
] }),
|
|
1838
|
+
cmdTips.length > 0 && (() => {
|
|
1839
|
+
const tip = cmdTips[cmdTipIndex % cmdTips.length];
|
|
1840
|
+
if (!tip) return null;
|
|
1841
|
+
const text = `${tip.name} ${tip.desc}`;
|
|
1842
|
+
return /* @__PURE__ */ jsxs5(Text6, { children: [
|
|
1843
|
+
/* @__PURE__ */ jsx5(Text6, { color: "#808080", children: " \u{1F4A1} " }),
|
|
1844
|
+
cmdTipGradientColors.length > 0 ? text.split("").map((ch, i) => /* @__PURE__ */ jsx5(Text6, { color: cmdTipGradientColors[i] || void 0, children: ch }, i)) : /* @__PURE__ */ jsx5(Text6, { color: "#808080", children: text })
|
|
1845
|
+
] });
|
|
1846
|
+
})(),
|
|
1730
1847
|
verbose ? /* @__PURE__ */ jsx5(Text6, { color: "#ff1493", children: " \u26A1 Verbose" }) : null
|
|
1731
1848
|
] }),
|
|
1732
1849
|
/* @__PURE__ */ jsxs5(Box5, { flexGrow: 1, flexDirection: "column", justifyContent: "center", alignItems: "flex-end", children: [
|
|
@@ -1741,7 +1858,7 @@ function ChatSession({
|
|
|
1741
1858
|
/* @__PURE__ */ jsx5(Text6, { color: "cyan", children: "\u{1F4CA} " }),
|
|
1742
1859
|
/* @__PURE__ */ jsxs5(Text6, { color: "cyan", children: [
|
|
1743
1860
|
"\u4ECA\u65E5 \xA5",
|
|
1744
|
-
|
|
1861
|
+
todayCost.toFixed(2)
|
|
1745
1862
|
] })
|
|
1746
1863
|
] }) : null
|
|
1747
1864
|
] })
|
|
@@ -1768,7 +1885,7 @@ function ChatSession({
|
|
|
1768
1885
|
},
|
|
1769
1886
|
i
|
|
1770
1887
|
);
|
|
1771
|
-
} }),
|
|
1888
|
+
} }, staticKey),
|
|
1772
1889
|
isStreaming && /* @__PURE__ */ jsx5(
|
|
1773
1890
|
AssistantMessage,
|
|
1774
1891
|
{
|
|
@@ -1783,20 +1900,54 @@ function ChatSession({
|
|
|
1783
1900
|
streamError
|
|
1784
1901
|
] }) })
|
|
1785
1902
|
] }),
|
|
1786
|
-
/* @__PURE__ */
|
|
1787
|
-
|
|
1788
|
-
/* @__PURE__ */
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1903
|
+
selectingModel ? /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, flexDirection: "column", children: [
|
|
1904
|
+
/* @__PURE__ */ jsx5(Text6, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }),
|
|
1905
|
+
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
1906
|
+
/* @__PURE__ */ jsx5(Text6, { bold: true, color: "#00ffff", children: "\u9009\u62E9\u6A21\u578B\uFF1A" }),
|
|
1907
|
+
modelOptions.map((id, i) => {
|
|
1908
|
+
const meta = SUPPORTED_MODELS[id];
|
|
1909
|
+
const isCurrent = id === activeModel;
|
|
1910
|
+
const isSelected = i === modelSelectIndex;
|
|
1911
|
+
const marker = isSelected ? " > " : " ";
|
|
1912
|
+
const suffix = isCurrent ? " (\u5F53\u524D)" : "";
|
|
1913
|
+
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
1914
|
+
/* @__PURE__ */ jsxs5(
|
|
1915
|
+
Text6,
|
|
1916
|
+
{
|
|
1917
|
+
color: isSelected ? "#00ff41" : void 0,
|
|
1918
|
+
bold: isSelected,
|
|
1919
|
+
children: [
|
|
1920
|
+
marker,
|
|
1921
|
+
meta.displayName,
|
|
1922
|
+
suffix
|
|
1923
|
+
]
|
|
1924
|
+
}
|
|
1925
|
+
),
|
|
1926
|
+
isSelected && /* @__PURE__ */ jsxs5(Text6, { color: "#808080", children: [
|
|
1927
|
+
" \u2014 ",
|
|
1928
|
+
id
|
|
1929
|
+
] })
|
|
1930
|
+
] }, id);
|
|
1931
|
+
}),
|
|
1932
|
+
/* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "#808080", dimColor: true, children: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u786E\u8BA4 \xB7 Esc \u53D6\u6D88" }) })
|
|
1933
|
+
] }),
|
|
1934
|
+
/* @__PURE__ */ jsx5(Text6, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) })
|
|
1935
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1936
|
+
/* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
|
|
1937
|
+
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
1938
|
+
/* @__PURE__ */ jsx5(Box5, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx5(Text6, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
|
|
1939
|
+
/* @__PURE__ */ jsx5(Box5, { flexGrow: 1, children: !input && !isStreaming && idlePlaceholder && gradientColors.length > 0 ? /* @__PURE__ */ jsx5(Text6, { children: idlePlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx5(Text6, { color: gradientColors[i] ?? void 0, children: ch }, i)) }) : !input && isStreaming && streamingPlaceholder && streamingGradientColors.length > 0 ? /* @__PURE__ */ jsx5(Text6, { children: streamingPlaceholder.split("").map((ch, i) => /* @__PURE__ */ jsx5(Text6, { color: streamingGradientColors[i] ?? void 0, children: ch }, i)) }) : /* @__PURE__ */ jsx5(
|
|
1940
|
+
TextInput,
|
|
1941
|
+
{
|
|
1942
|
+
value: input,
|
|
1943
|
+
onChange: setInput,
|
|
1944
|
+
onSubmit: handleSubmit,
|
|
1945
|
+
placeholder: ""
|
|
1946
|
+
}
|
|
1947
|
+
) })
|
|
1948
|
+
] }),
|
|
1949
|
+
/* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text6, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) })
|
|
1798
1950
|
] }),
|
|
1799
|
-
/* @__PURE__ */ jsx5(Box5, { children: /* @__PURE__ */ jsx5(Text6, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
|
|
1800
1951
|
doubleCtrlC && !isStreaming && /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "#ff1493", bold: true, children: " \u26A0 \u518D\u6309\u4E00\u6B21 Ctrl+C \u9000\u51FA dskcode" }) }),
|
|
1801
1952
|
isStreaming && /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text6, { color: "yellow", dimColor: true, children: " \u63D0\u793A\uFF1A\u6309 Ctrl+C \u53D6\u6D88\u5F53\u524D\u8BF7\u6C42" }) })
|
|
1802
1953
|
] });
|