dskcode 0.1.23 → 0.1.25
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/dist/{chunk-I6HEIOSU.js → chunk-EF6NIFOH.js} +1 -1
- package/dist/chunk-EF6NIFOH.js.map +1 -0
- package/dist/deepseek-MG4NT5YC.js +7 -0
- package/dist/index.js +284 -168
- package/dist/index.js.map +1 -1
- package/package.json +5 -6
- package/dist/chunk-I6HEIOSU.js.map +0 -1
- package/dist/deepseek-YTT76XDE.js +0 -7
- /package/dist/{deepseek-YTT76XDE.js.map → deepseek-MG4NT5YC.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
estimateTokens,
|
|
8
8
|
getModelMeta,
|
|
9
9
|
isSupportedModel
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EF6NIFOH.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/index.tsx
|
|
13
13
|
import { Command } from "commander";
|
|
@@ -785,15 +785,6 @@ function renderApp(node) {
|
|
|
785
785
|
import { Text } from "ink";
|
|
786
786
|
import InkSpinner from "ink-spinner";
|
|
787
787
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
788
|
-
function Spinner({ type = "dots", label }) {
|
|
789
|
-
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
790
|
-
/* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(InkSpinner, { type }) }),
|
|
791
|
-
label ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
792
|
-
" ",
|
|
793
|
-
label
|
|
794
|
-
] }) : null
|
|
795
|
-
] });
|
|
796
|
-
}
|
|
797
788
|
|
|
798
789
|
// src/ui/StatusMessage.tsx
|
|
799
790
|
import { Box, Text as Text2 } from "ink";
|
|
@@ -1344,7 +1335,7 @@ function AssistantMessage({
|
|
|
1344
1335
|
usage,
|
|
1345
1336
|
elapsed,
|
|
1346
1337
|
cost,
|
|
1347
|
-
model
|
|
1338
|
+
model: _model
|
|
1348
1339
|
}) {
|
|
1349
1340
|
if (!content && (!toolCalls || toolCalls.length === 0) && !isStreaming) {
|
|
1350
1341
|
return null;
|
|
@@ -1430,7 +1421,7 @@ function SkillSelector({ skills, input, selectedIndex }) {
|
|
|
1430
1421
|
const query = match[1].toLowerCase().trim();
|
|
1431
1422
|
if (skills.length === 0) return null;
|
|
1432
1423
|
const matched = !query && input.startsWith("/") ? skills.slice(0, 3) : skills.filter((s) => s.name.toLowerCase().includes(query)).slice(0, 3);
|
|
1433
|
-
if (query && matched.
|
|
1424
|
+
if (query && matched.some((s) => s.name.toLowerCase() === query)) return null;
|
|
1434
1425
|
if (matched.length === 0) return null;
|
|
1435
1426
|
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginLeft: 4, marginTop: 1, children: [
|
|
1436
1427
|
/* @__PURE__ */ jsx7(Text8, { color: "#808080", dimColor: true, children: "\u652F\u6301\u7684 Skill\uFF1A" }),
|
|
@@ -1508,6 +1499,7 @@ defaultRegistry.register("deepseek", (config) => {
|
|
|
1508
1499
|
return new DeepSeekProvider({
|
|
1509
1500
|
apiKey: config.apiKey,
|
|
1510
1501
|
baseUrl: config.baseUrl,
|
|
1502
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1511
1503
|
model: config.model
|
|
1512
1504
|
});
|
|
1513
1505
|
});
|
|
@@ -1540,7 +1532,7 @@ function eraseTool(tool) {
|
|
|
1540
1532
|
return tool.execute(args, ctx);
|
|
1541
1533
|
},
|
|
1542
1534
|
initialTitle(args) {
|
|
1543
|
-
return tool.initialTitle?.(args) ??
|
|
1535
|
+
return tool.initialTitle?.(args) ?? tool.name;
|
|
1544
1536
|
}
|
|
1545
1537
|
};
|
|
1546
1538
|
}
|
|
@@ -1559,8 +1551,12 @@ import Handlebars from "handlebars";
|
|
|
1559
1551
|
// src/agent/prompts/system-prompt.hbs
|
|
1560
1552
|
var system_prompt_default = '\u4F60\u662F dskcode\uFF0C\u4E00\u4E2A\u57FA\u4E8E DeepSeek \u7684 AI \u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u7EC8\u7AEF\u4E2D\u3002\u4F60\u7684\u804C\u8D23\u662F\u5E2E\u52A9\u5F00\u53D1\u8005\u7F16\u5199\u3001\u7406\u89E3\u3001\u8C03\u8BD5\u548C\u91CD\u6784\u4EE3\u7801\u3002\r\n\r\n## \u6838\u5FC3\u539F\u5219\r\n- \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587\r\n- \u63D0\u4F9B\u51C6\u786E\u3001\u5B9E\u7528\u3001\u53EF\u64CD\u4F5C\u7684\u5EFA\u8BAE\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u5185\u5BB9\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- \u4EE3\u7801\u793A\u4F8B\u4FDD\u6301\u7B80\u6D01\uFF0C\u9644\u5E26\u5FC5\u8981\u7684\u6CE8\u91CA\r\n\r\n## \u5DE5\u4F5C\u6D41\u7A0B\r\n\r\n\u4F60\u5904\u4E8E\u4E00\u4E2A\u5DE5\u5177\u8C03\u7528\u5FAA\u73AF\u4E2D\uFF1A\r\n1. \u6536\u5230\u7528\u6237\u8BF7\u6C42\r\n2. \u8C03\u7528\u5DE5\u5177\u83B7\u53D6\u4FE1\u606F\u6216\u4FEE\u6539\u6587\u4EF6\r\n3. \u5DE5\u5177\u7ED3\u679C\u8FD4\u56DE\u7ED9\u4F60\r\n4. \u6839\u636E\u7ED3\u679C\u51B3\u5B9A\u4E0B\u4E00\u6B65\uFF08\u7EE7\u7EED\u8C03\u7528\u5DE5\u5177\u6216\u7ED9\u51FA\u6700\u7EC8\u56DE\u7B54\uFF09\r\n5. \u4E00\u8F6E\u6700\u591A {{maxToolRounds}} \u6B21\u5DE5\u5177\u8C03\u7528\r\n\r\n## \u5DE5\u5177\u4F7F\u7528\u7B56\u7565\r\n\r\n{{#if tools}}\r\n\u5F53\u524D\u53EF\u7528\u7684\u5DE5\u5177\uFF1A\r\n{{#each tools}}\r\n- **{{name}}**\uFF1A{{description}}{{#if params}}\uFF08\u53C2\u6570\uFF1A{{params}}\uFF09{{/if}}\r\n{{/each}}\r\n\r\n\u4F7F\u7528\u539F\u5219\uFF1A\r\n- **\u5148\u641C\u7D22\u518D\u8BFB\u53D6** \u2014 \u4E0D\u786E\u5B9A\u76EE\u6807\u4F4D\u7F6E\u65F6\u5148\u7528 grep/glob \u5B9A\u4F4D\uFF0C\u518D\u7528 read_file \u8BFB\u53D6\r\n- **\u5148\u8BFB\u53D6\u518D\u4FEE\u6539** \u2014 \u7F16\u8F91\u6587\u4EF6\u524D\u5148 read_file \u786E\u8BA4\u5F53\u524D\u5185\u5BB9\r\n- **\u6279\u91CF\u64CD\u4F5C\u4E00\u6B21\u5B8C\u6210** \u2014 \u540C\u4E00\u6587\u4EF6\u7684\u591A\u5904\u6539\u52A8\u5728\u5355\u6B21 edit_file \u4E2D\u5B8C\u6210\r\n- **\u5DE5\u5177\u51FA\u9519\u65F6** \u2014 \u5206\u6790\u9519\u8BEF\u539F\u56E0\uFF08\u8DEF\u5F84\u4E0D\u5BF9\uFF1F\u683C\u5F0F\u4E0D\u5BF9\uFF1F\u6743\u9650\u4E0D\u8DB3\uFF1F\uFF09\uFF0C\u4FEE\u6B63\u540E\u91CD\u8BD5\uFF0C\u4E0D\u8981\u91CD\u590D\u76F8\u540C\u7684\u9519\u8BEF\u8C03\u7528\r\n- **\u5BA1\u614E\u6267\u884C** \u2014 bash \u6267\u884C\u5371\u9669\u547D\u4EE4\uFF08rm -rf\u3001\u5F3A\u5236\u5199\u5165\u7B49\uFF09\u524D\u5148\u786E\u8BA4\r\n{{/if}}\r\n\r\n{{#if projectContext}}\r\n## \u9879\u76EE\u4E0A\u4E0B\u6587\r\n\r\n{{projectContext}}\r\n{{/if}}\r\n\r\n## \u56DE\u7B54\u683C\u5F0F\r\n\r\n\u7EC8\u7AEF\u4E0D\u652F\u6301 Markdown \u6E32\u67D3\u3002\u56DE\u590D\u683C\u5F0F\u8981\u6C42\uFF1A\r\n\r\n- \u7528 emoji \u505A\u89C6\u89C9\u6807\u8BB0\uFF08\u{1F4CC} \u8981\u70B9 \u26A0\uFE0F \u6CE8\u610F \u{1F4DD} \u5F85\u529E \u2705 \u5B8C\u6210\uFF09\r\n- \u7528\u6570\u5B57\u5E8F\u53F7\u6216\u77ED\u6A2A\u7EBF\u7EC4\u7EC7\u5217\u8868\r\n- \u4EE3\u7801\u6807\u8BC6\u7B26\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u7C7B\u578B\u540D\u7528\u5355\u4E2A\u53CD\u5F15\u53F7 ` \u5305\u88F9\uFF0C\u4F1A\u88AB\u81EA\u52A8\u9AD8\u4EAE\r\n- \u5F3A\u8C03\u5185\u5BB9\u7528 **\u52A0\u7C97** \u5305\u88F9\uFF0C\u4F1A\u88AB\u81EA\u52A8\u9AD8\u4EAE\r\n- \u591A\u884C\u4EE3\u7801\u7528\u7F29\u8FDB 4 \u4E2A\u7A7A\u683C\u8868\u793A\uFF0C\u4E0D\u8981\u7528\u4E09\u53CD\u5F15\u53F7\u4EE3\u7801\u5757\r\n- \u6BB5\u843D\u95F4\u7528\u7A7A\u884C\u5206\u9694\uFF0C\u4E0D\u8981\u7528\u6807\u9898\u7B26\u53F7\r\n\r\n\u6B63\u786E\u793A\u4F8B\uFF1A\r\n\r\n\u{1F4CC} \u9700\u8981\u4FEE\u6539\u4E24\u4E2A\u5730\u65B9\uFF1A\r\n1. \u7B2C 12 \u884C\u7684 `interface FileDiff` \u6539\u4E3A `interface Diff`\r\n2. \u7B2C 432 \u884C\u7684 `): FileDiff` \u6539\u4E3A `): Diff`\r\n\r\n \u4EE3\u7801\u793A\u4F8B\uFF1A\r\n const pool = new Pool({ max: 20 });\r\n await pool.query("SELECT * FROM users");\r\n\r\n## \u884C\u4E3A\u7EA6\u675F\r\n- \u5982\u679C\u7528\u6237\u8BF7\u6C42\u4E0D\u660E\u786E\uFF0C\u4E3B\u52A8\u8BE2\u95EE\u6F84\u6E05\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u4FE1\u606F\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- \u4E0D\u6267\u884C\u53EF\u80FD\u9020\u6210\u4E0D\u53EF\u9006\u635F\u5BB3\u7684\u64CD\u4F5C\uFF08\u5982 rm -rf\uFF09\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u9010\u6761\u786E\u8BA4\r\n- \u5DE5\u5177\u8C03\u7528\u8FD4\u56DE\u9519\u8BEF\u65F6\uFF0C\u5148\u5206\u6790\u539F\u56E0\u518D\u91CD\u8BD5\uFF0C\u4E0D\u8981\u76F2\u76EE\u91CD\u8BD5\r\n\r\n## \u5F53\u524D\u6A21\u578B\r\n- \u6A21\u578B\uFF1A{{model}}\r\n\r\n## \u65F6\u95F4\u4E0A\u4E0B\u6587\r\n- \u5F53\u524D\u65E5\u671F\uFF1A{{date}}\r\n- \u5F53\u524D\u65F6\u95F4\uFF1A{{time}}\r\n- \u5DE5\u4F5C\u76EE\u5F55\uFF1A{{cwd}}\r\n';
|
|
1561
1553
|
|
|
1554
|
+
// src/agent/prompts/plan-prompt.hbs
|
|
1555
|
+
var plan_prompt_default = "\u4F60\u662F dskcode\uFF0C\u5F53\u524D\u5DE5\u4F5C\u5728**\u8BA1\u5212\u6A21\u5F0F\uFF08Plan Mode\uFF09**\u3002\r\n\r\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C**\u4F60\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u80FD\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u64CD\u4F5C**\u3002\u4F60\u7684\u804C\u8D23\u662F\u5E2E\u52A9\u7528\u6237\u7406\u89E3\u4EE3\u7801\u3001\u8BBE\u8BA1\u67B6\u6784\u3001\u89C4\u5212\u4EFB\u52A1\u3001\u8BC4\u4F30\u65B9\u6848\u3002\r\n\r\n## \u6838\u5FC3\u539F\u5219\r\n- \u56DE\u7B54\u4F7F\u7528\u4E2D\u6587\uFF0C\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u82F1\u6587\r\n- \u63D0\u4F9B\u51C6\u786E\u3001\u5B9E\u7528\u3001\u53EF\u64CD\u4F5C\u7684\u5EFA\u8BAE\r\n- \u5BF9\u4E0D\u786E\u5B9A\u7684\u5185\u5BB9\u660E\u786E\u6807\u6CE8\uFF0C\u4E0D\u7F16\u9020\u4E8B\u5B9E\r\n- **\u7EDD\u4E0D\u6267\u884C\u4EFB\u4F55\u5199\u64CD\u4F5C** \u2014 \u4F60\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\r\n\r\n## \u5DE5\u4F5C\u6D41\u7A0B\r\n1. \u6536\u5230\u7528\u6237\u8BF7\u6C42\r\n2. \u4F7F\u7528\u8BFB\u5DE5\u5177\uFF08read-file, grep, glob, ls, fetch\uFF09\u63A2\u7D22\u4EE3\u7801\u5E93\r\n3. \u6839\u636E\u53D1\u73B0\u7684\u4FE1\u606F\u63D0\u4F9B\u7ED3\u6784\u5316\u7684\u5206\u6790\u6216\u8BA1\u5212\r\n4. \u5DE5\u5177\u8FD4\u56DE\u51FA\u9519\u65F6\u5206\u6790\u539F\u56E0\u5E76\u4FEE\u6B63\u540E\u91CD\u8BD5\r\n5. \u5B8C\u6210\u540E\u8F93\u51FA\u6700\u7EC8\u5206\u6790\u7ED3\u679C\r\n\r\n## \u5DE5\u5177\u9650\u5236\r\n**\u4F60\u53EA\u80FD\u4F7F\u7528\u8BFB\u5DE5\u5177**\uFF0C\u4E0D\u80FD\u4F7F\u7528\u4EFB\u4F55\u5199\u5DE5\u5177\uFF08write-file, edit-file, multi-edit, delete-range, bash\uFF09\u3002\r\n\u5982\u679C\u7528\u6237\u8BF7\u6C42\u4FEE\u6539\u4EE3\u7801\uFF0C\u8BF7\uFF1A\r\n- \u63D0\u4F9B\u4FEE\u6539\u5EFA\u8BAE\u548C\u65B9\u6848\r\n- \u6307\u51FA\u9700\u8981\u4FEE\u6539\u7684\u6587\u4EF6\u548C\u4F4D\u7F6E\r\n- \u89E3\u91CA\u4FEE\u6539\u7684\u5F71\u54CD\r\n- \u4F46\u4E0D\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\r\n\r\n## \u8BA1\u5212\u8F93\u51FA\u683C\u5F0F\r\n\r\n\u5F53\u7528\u6237\u8BF7\u6C42\u8BA1\u5212/\u65B9\u6848\u65F6\uFF0C\u5EFA\u8BAE\u6309\u7167\u4EE5\u4E0B\u7ED3\u6784\u7EC4\u7EC7\u8F93\u51FA\uFF1A\r\n\r\n\u{1F4CB} **\u6982\u8FF0**\r\n 1-2 \u53E5\u8BDD\u8BF4\u660E\u8981\u505A\u4EC0\u4E48\u4EE5\u53CA\u4E3A\u4EC0\u4E48\u8981\u505A\r\n\r\n\u{1F50D} **\u73B0\u72B6\u5206\u6790**\r\n \u5F53\u524D\u4EE3\u7801\u7684\u7EC4\u7EC7\u7ED3\u6784\u548C\u5173\u952E\u53D1\u73B0\r\n\r\n\u26A1 **\u5F71\u54CD\u8303\u56F4**\r\n \u54EA\u4E9B\u6587\u4EF6/\u6A21\u5757\u4F1A\u53D7\u5230\u5F71\u54CD\r\n\r\n\u{1F4DD} **\u5B9E\u65BD\u6B65\u9AA4**\r\n 1. \u7B2C\u4E00\u6B65\uFF08\u6587\u4EF6\u8DEF\u5F84/\u53D8\u66F4\u8BF4\u660E\uFF09\r\n 2. \u7B2C\u4E8C\u6B65\uFF08\u6587\u4EF6\u8DEF\u5F84/\u53D8\u66F4\u8BF4\u660E\uFF09\r\n 3. ...\r\n\r\n\u26A0\uFE0F **\u98CE\u9669\u4E0E\u6CE8\u610F\u4E8B\u9879**\r\n \u53EF\u80FD\u7684\u98CE\u9669\u70B9\u3001\u4F9D\u8D56\u5173\u7CFB\u3001\u56DE\u9000\u7B56\u7565\r\n\r\n## \u56DE\u7B54\u683C\u5F0F\r\n\r\n\u7EC8\u7AEF\u4E0D\u652F\u6301 Markdown \u6E32\u67D3\u3002\u56DE\u590D\u683C\u5F0F\u8981\u6C42\uFF1A\r\n- \u7528 emoji \u505A\u89C6\u89C9\u6807\u8BB0\r\n- \u7528\u6570\u5B57\u5E8F\u53F7\u6216\u77ED\u6A2A\u7EBF\u7EC4\u7EC7\u5217\u8868\r\n- \u4EE3\u7801\u6807\u8BC6\u7B26\u3001\u6587\u4EF6\u8DEF\u5F84\u7528\u5355\u4E2A\u53CD\u5F15\u53F7 ` \u5305\u88F9\r\n- \u591A\u884C\u4EE3\u7801\u7528\u7F29\u8FDB 4 \u4E2A\u7A7A\u683C\u8868\u793A\r\n- \u6BB5\u843D\u95F4\u7528\u7A7A\u884C\u5206\u9694\r\n\r\n## \u5F53\u524D\u6A21\u578B\r\n- \u6A21\u578B\uFF1A{{model}}\r\n\r\n## \u65F6\u95F4\u4E0A\u4E0B\u6587\r\n- \u5F53\u524D\u65E5\u671F\uFF1A{{date}}\r\n- \u5F53\u524D\u65F6\u95F4\uFF1A{{time}}\r\n- \u5DE5\u4F5C\u76EE\u5F55\uFF1A{{cwd}}\r\n";
|
|
1556
|
+
|
|
1562
1557
|
// src/agent/system-prompt.ts
|
|
1563
1558
|
var compiledTemplate = Handlebars.compile(system_prompt_default);
|
|
1559
|
+
var compiledPlanTemplate = Handlebars.compile(plan_prompt_default);
|
|
1564
1560
|
function formatTools(tools) {
|
|
1565
1561
|
return tools.map((t) => {
|
|
1566
1562
|
const params = t.parameters && Object.keys(t.parameters.properties ?? {}).join(", ");
|
|
@@ -1571,7 +1567,7 @@ function formatTools(tools) {
|
|
|
1571
1567
|
};
|
|
1572
1568
|
});
|
|
1573
1569
|
}
|
|
1574
|
-
function
|
|
1570
|
+
function buildTemplateVars(opts) {
|
|
1575
1571
|
const now = /* @__PURE__ */ new Date();
|
|
1576
1572
|
const date = now.toLocaleDateString("zh-CN", {
|
|
1577
1573
|
year: "numeric",
|
|
@@ -1583,7 +1579,7 @@ function buildSystemPrompt(opts) {
|
|
|
1583
1579
|
hour: "2-digit",
|
|
1584
1580
|
minute: "2-digit"
|
|
1585
1581
|
});
|
|
1586
|
-
return
|
|
1582
|
+
return {
|
|
1587
1583
|
model: opts.model,
|
|
1588
1584
|
maxToolRounds: opts.maxToolRounds,
|
|
1589
1585
|
cwd: opts.cwd,
|
|
@@ -1591,7 +1587,13 @@ function buildSystemPrompt(opts) {
|
|
|
1591
1587
|
time,
|
|
1592
1588
|
tools: opts.tools ? formatTools(opts.tools) : void 0,
|
|
1593
1589
|
projectContext: opts.projectContext ?? void 0
|
|
1594
|
-
}
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
function buildSystemPrompt(opts) {
|
|
1593
|
+
return compiledTemplate(buildTemplateVars(opts));
|
|
1594
|
+
}
|
|
1595
|
+
function buildPlanSystemPrompt(opts) {
|
|
1596
|
+
return compiledPlanTemplate(buildTemplateVars(opts));
|
|
1595
1597
|
}
|
|
1596
1598
|
|
|
1597
1599
|
// src/tool/registry.ts
|
|
@@ -1770,6 +1772,8 @@ var Session = class {
|
|
|
1770
1772
|
#abortController = new AbortController();
|
|
1771
1773
|
// 风暴检测:记录每轮的工具调用错误
|
|
1772
1774
|
#stormRecords = [];
|
|
1775
|
+
/** 当前会话模式:code(代码模式)或 plan(计划模式) */
|
|
1776
|
+
#mode = "code";
|
|
1773
1777
|
constructor(provider, tools = [], costTracker, options) {
|
|
1774
1778
|
this.#provider = provider;
|
|
1775
1779
|
if (tools instanceof ToolRegistry) {
|
|
@@ -1808,6 +1812,15 @@ var Session = class {
|
|
|
1808
1812
|
get toolRegistry() {
|
|
1809
1813
|
return this.#toolRegistry;
|
|
1810
1814
|
}
|
|
1815
|
+
/** 获取当前会话模式 */
|
|
1816
|
+
get mode() {
|
|
1817
|
+
return this.#mode;
|
|
1818
|
+
}
|
|
1819
|
+
/** 切换会话模式,返回新模式 */
|
|
1820
|
+
setMode(mode) {
|
|
1821
|
+
this.#mode = mode;
|
|
1822
|
+
return this.#mode;
|
|
1823
|
+
}
|
|
1811
1824
|
// -------------------------------------------------------------------------
|
|
1812
1825
|
// 流式对话 — Agent 主循环
|
|
1813
1826
|
// -------------------------------------------------------------------------
|
|
@@ -1833,6 +1846,7 @@ var Session = class {
|
|
|
1833
1846
|
const [trimmed] = trimMessages(
|
|
1834
1847
|
[...this.#messages],
|
|
1835
1848
|
{
|
|
1849
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
1836
1850
|
model: this.#provider.model(),
|
|
1837
1851
|
reservedForOutput: this.#options.reservedForOutput,
|
|
1838
1852
|
systemPrompt,
|
|
@@ -1852,7 +1866,7 @@ var Session = class {
|
|
|
1852
1866
|
let accumulatedText = "";
|
|
1853
1867
|
let lastUsage;
|
|
1854
1868
|
let lastToolCalls;
|
|
1855
|
-
let
|
|
1869
|
+
let _lastFinishReason = null;
|
|
1856
1870
|
for await (const chunk of stream) {
|
|
1857
1871
|
if (chunk.content) {
|
|
1858
1872
|
accumulatedText += chunk.content;
|
|
@@ -1865,7 +1879,7 @@ var Session = class {
|
|
|
1865
1879
|
lastUsage = chunk.usage;
|
|
1866
1880
|
}
|
|
1867
1881
|
if (chunk.finishReason) {
|
|
1868
|
-
|
|
1882
|
+
_lastFinishReason = chunk.finishReason;
|
|
1869
1883
|
}
|
|
1870
1884
|
}
|
|
1871
1885
|
if (lastUsage) {
|
|
@@ -2071,6 +2085,7 @@ ${item.result.diff.patch}`;
|
|
|
2071
2085
|
const toolDescs = enabledTools.map((t) => ({
|
|
2072
2086
|
name: t.name,
|
|
2073
2087
|
description: t.description,
|
|
2088
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2074
2089
|
parameters: t.parameters
|
|
2075
2090
|
}));
|
|
2076
2091
|
const opts = {
|
|
@@ -2080,15 +2095,23 @@ ${item.result.diff.patch}`;
|
|
|
2080
2095
|
projectContext: this.#options.projectContext ?? void 0,
|
|
2081
2096
|
cwd: this.#options.cwd
|
|
2082
2097
|
};
|
|
2098
|
+
if (this.#mode === "plan") {
|
|
2099
|
+
return buildPlanSystemPrompt(opts);
|
|
2100
|
+
}
|
|
2083
2101
|
return buildSystemPrompt(opts);
|
|
2084
2102
|
}
|
|
2085
|
-
/**
|
|
2103
|
+
/**
|
|
2104
|
+
* 将注册的工具转为 ToolDefinition 格式(预留给 function calling)。
|
|
2105
|
+
* 计划模式下只返回读工具,禁止非读工具暴露给 LLM。
|
|
2106
|
+
*/
|
|
2086
2107
|
#buildToolDefinitions() {
|
|
2087
|
-
|
|
2108
|
+
const tools = this.#mode === "plan" ? this.#toolRegistry.listReadTools() : this.#toolRegistry.list();
|
|
2109
|
+
return tools.map((t) => ({
|
|
2088
2110
|
type: "function",
|
|
2089
2111
|
function: {
|
|
2090
2112
|
name: t.name,
|
|
2091
2113
|
description: t.description,
|
|
2114
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2092
2115
|
parameters: t.parameters
|
|
2093
2116
|
}
|
|
2094
2117
|
}));
|
|
@@ -2152,7 +2175,7 @@ function getDefaultTimeout() {
|
|
|
2152
2175
|
return DEFAULT_TIMEOUT_MS;
|
|
2153
2176
|
}
|
|
2154
2177
|
async function execCommand(command, args, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, signal, isShellCommand) {
|
|
2155
|
-
return new Promise((
|
|
2178
|
+
return new Promise((_resolve) => {
|
|
2156
2179
|
let spawnCmd;
|
|
2157
2180
|
let spawnArgs;
|
|
2158
2181
|
let useShell;
|
|
@@ -2195,13 +2218,13 @@ async function execCommand(command, args, cwd, timeoutMs = DEFAULT_TIMEOUT_MS, s
|
|
|
2195
2218
|
}
|
|
2196
2219
|
child.on("close", (code) => {
|
|
2197
2220
|
clearTimeout(timeout);
|
|
2198
|
-
|
|
2221
|
+
_resolve({ stdout, stderr, exitCode: code });
|
|
2199
2222
|
});
|
|
2200
2223
|
child.on("error", (err) => {
|
|
2201
2224
|
clearTimeout(timeout);
|
|
2202
2225
|
stderr += `
|
|
2203
2226
|
\u8FDB\u7A0B\u542F\u52A8\u5931\u8D25\uFF1A${err.message}`;
|
|
2204
|
-
|
|
2227
|
+
_resolve({ stdout, stderr, exitCode: null });
|
|
2205
2228
|
});
|
|
2206
2229
|
});
|
|
2207
2230
|
}
|
|
@@ -2244,42 +2267,41 @@ function computeLineDiff(oldLines, newLines) {
|
|
|
2244
2267
|
const V = new Array(2 * maxD + 2).fill(-1);
|
|
2245
2268
|
const offset = maxD;
|
|
2246
2269
|
V[offset + 1] = 0;
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
return backtrack(trace, N, M, oldLines, newLines, offset);
|
|
2270
|
-
}
|
|
2270
|
+
for (let d = 0; d <= maxD; d++) {
|
|
2271
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
2272
|
+
const kStart = -d;
|
|
2273
|
+
const kEnd = d;
|
|
2274
|
+
for (let k = kStart; k <= kEnd; k += 2) {
|
|
2275
|
+
const ki = k + offset;
|
|
2276
|
+
let x;
|
|
2277
|
+
if (k === -d || k !== d && V[ki - 1] < V[ki + 1]) {
|
|
2278
|
+
x = V[ki + 1];
|
|
2279
|
+
} else {
|
|
2280
|
+
x = V[ki - 1] + 1;
|
|
2281
|
+
}
|
|
2282
|
+
let y = x - k;
|
|
2283
|
+
while (x < N && y < M && oldLines[x] === newLines[y]) {
|
|
2284
|
+
x++;
|
|
2285
|
+
y++;
|
|
2286
|
+
}
|
|
2287
|
+
V[ki] = x;
|
|
2288
|
+
snapshot.set(k, x);
|
|
2289
|
+
if (x >= N && y >= M) {
|
|
2290
|
+
trace.push(snapshot);
|
|
2291
|
+
return backtrack(trace, N, M, oldLines, newLines, offset);
|
|
2271
2292
|
}
|
|
2272
|
-
trace.push(snapshot);
|
|
2273
2293
|
}
|
|
2294
|
+
trace.push(snapshot);
|
|
2295
|
+
}
|
|
2274
2296
|
return oldLines.map((line) => ({ op: "remove", line })).concat(newLines.map((line) => ({ op: "add", line })));
|
|
2275
2297
|
}
|
|
2276
|
-
function backtrack(trace, N, M, oldLines, newLines,
|
|
2298
|
+
function backtrack(trace, N, M, oldLines, newLines, _offset) {
|
|
2277
2299
|
const result = [];
|
|
2278
2300
|
let x = N;
|
|
2279
2301
|
let y = M;
|
|
2280
2302
|
for (let d = trace.length - 1; d >= 1; d--) {
|
|
2281
2303
|
const k = x - y;
|
|
2282
|
-
const prevSnapshot =
|
|
2304
|
+
const prevSnapshot = trace[d - 1];
|
|
2283
2305
|
const prevKDown = prevSnapshot.get(k - 1);
|
|
2284
2306
|
const prevKUp = prevSnapshot.get(k + 1);
|
|
2285
2307
|
let prevK;
|
|
@@ -2668,7 +2690,7 @@ var writeFileTool = {
|
|
|
2668
2690
|
} catch {
|
|
2669
2691
|
}
|
|
2670
2692
|
await mkdir4(dirname(filePath), { recursive: true });
|
|
2671
|
-
const content =
|
|
2693
|
+
const content = args.content;
|
|
2672
2694
|
await writeFileWithEol(filePath, oldContent, content);
|
|
2673
2695
|
const diff = computeFileDiff(oldContent, content, filePath);
|
|
2674
2696
|
diff.existedBefore = existedBefore;
|
|
@@ -3187,7 +3209,7 @@ var globTool = {
|
|
|
3187
3209
|
// src/tool/builtins/grep.ts
|
|
3188
3210
|
import { readdir as readdir3, readFile as readFile9, stat as stat3 } from "fs/promises";
|
|
3189
3211
|
import { join as join5, relative as relative5, isAbsolute as isAbsolute3 } from "path";
|
|
3190
|
-
async function collectFiles(dir,
|
|
3212
|
+
async function collectFiles(dir, extension, maxFiles = 200) {
|
|
3191
3213
|
const results = [];
|
|
3192
3214
|
let entries;
|
|
3193
3215
|
try {
|
|
@@ -3202,7 +3224,7 @@ async function collectFiles(dir, baseDir, extension, maxFiles = 200) {
|
|
|
3202
3224
|
}
|
|
3203
3225
|
const fullPath = join5(dir, entry.name);
|
|
3204
3226
|
if (entry.isDirectory()) {
|
|
3205
|
-
results.push(...await collectFiles(fullPath,
|
|
3227
|
+
results.push(...await collectFiles(fullPath, extension, maxFiles - results.length));
|
|
3206
3228
|
} else {
|
|
3207
3229
|
if (extension && !entry.name.endsWith(`.${extension}`)) {
|
|
3208
3230
|
continue;
|
|
@@ -3256,7 +3278,7 @@ var grepTool = {
|
|
|
3256
3278
|
if (!dirStat.isDirectory()) {
|
|
3257
3279
|
return { success: false, data: `\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\uFF1A${searchDir}`, error: "NOT_DIRECTORY" };
|
|
3258
3280
|
}
|
|
3259
|
-
const files = await collectFiles(searchDir,
|
|
3281
|
+
const files = await collectFiles(searchDir, args.include, maxFiles);
|
|
3260
3282
|
const matches = [];
|
|
3261
3283
|
for (const filePath of files) {
|
|
3262
3284
|
try {
|
|
@@ -3264,7 +3286,7 @@ var grepTool = {
|
|
|
3264
3286
|
const lines = content.split("\n");
|
|
3265
3287
|
const relPath = relative5(searchDir, filePath);
|
|
3266
3288
|
for (let i = 0; i < lines.length; i++) {
|
|
3267
|
-
if (regex.test(lines[i])) {
|
|
3289
|
+
if (regex.test(lines[i] ?? "")) {
|
|
3268
3290
|
regex.lastIndex = 0;
|
|
3269
3291
|
matches.push({
|
|
3270
3292
|
file: relPath,
|
|
@@ -3333,7 +3355,7 @@ var lsTool = {
|
|
|
3333
3355
|
try {
|
|
3334
3356
|
const entries = await readdir4(dirPath, { withFileTypes: true });
|
|
3335
3357
|
const lines = [];
|
|
3336
|
-
const sorted = [...entries].
|
|
3358
|
+
const sorted = [...entries].toSorted((a, b) => {
|
|
3337
3359
|
if (a.isDirectory() !== b.isDirectory()) {
|
|
3338
3360
|
return a.isDirectory() ? -1 : 1;
|
|
3339
3361
|
}
|
|
@@ -3548,6 +3570,12 @@ function getGradientColors(text, phase, stops) {
|
|
|
3548
3570
|
|
|
3549
3571
|
// src/ui/ChatSession.tsx
|
|
3550
3572
|
import { Fragment, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3573
|
+
var PHASE_CONFIG = {
|
|
3574
|
+
thinking: { icon: "\u{1F9E0}", label: "\u601D\u8003\u4E2D", color: "#ff9800" },
|
|
3575
|
+
generating: { icon: "\u2728", label: "\u751F\u6210\u4E2D", color: "#00ff41" },
|
|
3576
|
+
calling_tools: { icon: "\u{1F6E0}", label: "\u8C03\u7528\u5DE5\u5177", color: "#f59e0b" },
|
|
3577
|
+
executing_tools: { icon: "\u26A1", label: "\u6267\u884C\u5DE5\u5177", color: "#00ffff" }
|
|
3578
|
+
};
|
|
3551
3579
|
var commandRegistry = /* @__PURE__ */ new Map();
|
|
3552
3580
|
function registerCommand(name, cmd) {
|
|
3553
3581
|
commandRegistry.set(name, cmd);
|
|
@@ -3575,6 +3603,8 @@ registerCommand("/thinking", { desc: "\u5207\u6362\u6DF1\u5EA6\u601D\u8003\u6A21
|
|
|
3575
3603
|
registerCommand("/effort", { desc: "\u5207\u6362\u63A8\u7406\u7B49\u7EA7 High/Max", handler: () => ({ kind: "text", content: "\u8BF7\u76F4\u63A5\u8F93\u5165 /effort \u5207\u6362" }) });
|
|
3576
3604
|
registerCommand("/game", { desc: "\u542F\u52A8\u6E38\u620F", handler: () => ({ kind: "navigate", target: "game" }) });
|
|
3577
3605
|
registerCommand("/stock", { desc: "\u67E5\u770B\u80A1\u7968\u884C\u60C5", handler: () => ({ kind: "navigate", target: "stock" }) });
|
|
3606
|
+
registerCommand("/plan", { desc: "\u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F\uFF08Shift+Tab\uFF09", handler: () => ({ kind: "text", content: "\u8F93\u5165 /plan \u6216\u6309 Shift+Tab \u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F" }) });
|
|
3607
|
+
registerCommand("/code", { desc: "\u5207\u6362\u56DE\u4EE3\u7801\u6A21\u5F0F\uFF08Shift+Tab\uFF09", handler: () => ({ kind: "text", content: "\u8F93\u5165 /code \u6216\u6309 Shift+Tab \u5207\u6362\u56DE\u4EE3\u7801\u6A21\u5F0F" }) });
|
|
3578
3608
|
var STREAMING_PLACEHOLDERS = [
|
|
3579
3609
|
"\u8BA9\u5B50\u5F39\u98DE\u4E00\u4F1A\u513F...",
|
|
3580
3610
|
"\u9A6C\u4E0A\u5C31\u597D...",
|
|
@@ -3617,6 +3647,7 @@ function ChatSession({
|
|
|
3617
3647
|
const [balanceLoading, setBalanceLoading] = useState3(false);
|
|
3618
3648
|
const [todayCost, setTodayCost] = useState3(null);
|
|
3619
3649
|
const [isStreaming, setIsStreaming] = useState3(false);
|
|
3650
|
+
const [streamingPhase, setStreamingPhase] = useState3(null);
|
|
3620
3651
|
const [streamingPlaceholder, setStreamingPlaceholder] = useState3("");
|
|
3621
3652
|
const [idlePlaceholder, setIdlePlaceholder] = useState3(() => pickRandom(IDLE_PLACEHOLDERS));
|
|
3622
3653
|
const [gradientColors, setGradientColors] = useState3([]);
|
|
@@ -3625,15 +3656,16 @@ function ChatSession({
|
|
|
3625
3656
|
const streamingPhaseRef = useRef2(0);
|
|
3626
3657
|
const [currentContent, setCurrentContent] = useState3("");
|
|
3627
3658
|
const [currentToolCalls, setCurrentToolCalls] = useState3([]);
|
|
3628
|
-
const [
|
|
3629
|
-
const [
|
|
3630
|
-
const [
|
|
3659
|
+
const [_currentUsage, setCurrentUsage] = useState3(void 0);
|
|
3660
|
+
const [_currentElapsed, setCurrentElapsed] = useState3(void 0);
|
|
3661
|
+
const [_currentCost, setCurrentCost] = useState3(void 0);
|
|
3631
3662
|
const [activeModel, setActiveModel] = useState3(model);
|
|
3632
|
-
const [
|
|
3663
|
+
const [_streamingModel, setStreamingModel] = useState3(void 0);
|
|
3633
3664
|
const [streamError, setStreamError] = useState3(void 0);
|
|
3665
|
+
const [sessionMode, setSessionMode] = useState3("code");
|
|
3634
3666
|
const [thinkingEnabled, setThinkingEnabled] = useState3(true);
|
|
3635
3667
|
const [thinkingEffort, setThinkingEffort] = useState3("high");
|
|
3636
|
-
const [responseFormat
|
|
3668
|
+
const [responseFormat] = useState3("text");
|
|
3637
3669
|
const [toolChoice, setToolChoice] = useState3(void 0);
|
|
3638
3670
|
const sessionCost = useMemo(() => {
|
|
3639
3671
|
return displayMessages.reduce((sum, msg) => {
|
|
@@ -3788,11 +3820,28 @@ function ChatSession({
|
|
|
3788
3820
|
}
|
|
3789
3821
|
return;
|
|
3790
3822
|
}
|
|
3823
|
+
if (key.shift && key.tab) {
|
|
3824
|
+
if (!isStreaming) {
|
|
3825
|
+
const newMode = sessionMode === "plan" ? "code" : "plan";
|
|
3826
|
+
setSessionMode(newMode);
|
|
3827
|
+
sessionRef.current?.setMode(newMode);
|
|
3828
|
+
setToolChoice(void 0);
|
|
3829
|
+
sessionRef.current?.reset();
|
|
3830
|
+
setDisplayMessages((prev) => [
|
|
3831
|
+
...prev,
|
|
3832
|
+
{
|
|
3833
|
+
role: "assistant",
|
|
3834
|
+
content: newMode === "plan" ? "\u{1F4CB} \u5DF2\u5207\u6362\u4E3A **\u8BA1\u5212\u6A21\u5F0F**\uFF08Shift+Tab\uFF09\n\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C\u6211\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u4F1A\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u3002" : "\u{1F6E0} \u5DF2\u5207\u6362\u4E3A **\u4EE3\u7801\u6A21\u5F0F**\uFF08Shift+Tab\uFF09\n\n\u73B0\u5728\u53EF\u4EE5\u6B63\u5E38\u8BFB\u53D6\u548C\u4FEE\u6539\u4EE3\u7801\u4E86\u3002"
|
|
3835
|
+
}
|
|
3836
|
+
]);
|
|
3837
|
+
}
|
|
3838
|
+
return;
|
|
3839
|
+
}
|
|
3791
3840
|
if (!input && !isStreaming && _input) {
|
|
3792
3841
|
setInput(_input);
|
|
3793
3842
|
}
|
|
3794
3843
|
},
|
|
3795
|
-
[selectingModel, modelSelectIndex, modelOptions, activeModel, isStreaming, handleCtrlC, input, skills, skillSelectIndex, fileSelectIndex, getFilteredSkills, getFilteredFiles]
|
|
3844
|
+
[selectingModel, modelSelectIndex, modelOptions, activeModel, isStreaming, handleCtrlC, input, skills, skillSelectIndex, fileSelectIndex, getFilteredSkills, getFilteredFiles, sessionMode, setSessionMode]
|
|
3796
3845
|
)
|
|
3797
3846
|
);
|
|
3798
3847
|
useEffect3(() => {
|
|
@@ -3846,7 +3895,7 @@ function ChatSession({
|
|
|
3846
3895
|
if (!apiKey || !baseUrl) return;
|
|
3847
3896
|
let cancelled = false;
|
|
3848
3897
|
setBalanceLoading(true);
|
|
3849
|
-
import("./deepseek-
|
|
3898
|
+
import("./deepseek-MG4NT5YC.js").then(({ DeepSeekProvider: DeepSeekProvider2 }) => {
|
|
3850
3899
|
const provider = new DeepSeekProvider2({
|
|
3851
3900
|
apiKey,
|
|
3852
3901
|
baseUrl,
|
|
@@ -3944,6 +3993,48 @@ function ChatSession({
|
|
|
3944
3993
|
setInput("");
|
|
3945
3994
|
return;
|
|
3946
3995
|
}
|
|
3996
|
+
if (cmdLower === "/plan") {
|
|
3997
|
+
if (sessionMode === "plan") {
|
|
3998
|
+
setDisplayMessages((prev) => [
|
|
3999
|
+
...prev,
|
|
4000
|
+
{ role: "user", content: trimmed },
|
|
4001
|
+
{ role: "assistant", content: "\u5DF2\u7ECF\u5728\u8BA1\u5212\u6A21\u5F0F\u4E2D\u3002\u8F93\u5165 /code \u5207\u56DE\u4EE3\u7801\u6A21\u5F0F\u3002" }
|
|
4002
|
+
]);
|
|
4003
|
+
} else {
|
|
4004
|
+
setSessionMode("plan");
|
|
4005
|
+
sessionRef.current?.setMode("plan");
|
|
4006
|
+
setToolChoice(void 0);
|
|
4007
|
+
setDisplayMessages((prev) => [
|
|
4008
|
+
...prev,
|
|
4009
|
+
{ role: "user", content: trimmed },
|
|
4010
|
+
{ role: "assistant", content: "\u{1F4CB} \u5DF2\u5207\u6362\u4E3A **\u8BA1\u5212\u6A21\u5F0F**\n\n\u5728\u6B64\u6A21\u5F0F\u4E0B\uFF0C\u6211\u53EA\u80FD\u8BFB\u53D6\u548C\u5206\u6790\u4EE3\u7801\uFF0C\u4E0D\u4F1A\u6267\u884C\u4EFB\u4F55\u4FEE\u6539\u3002\n\u8F93\u5165 /code \u5207\u56DE\u4EE3\u7801\u6A21\u5F0F\u3002" }
|
|
4011
|
+
]);
|
|
4012
|
+
sessionRef.current?.reset();
|
|
4013
|
+
}
|
|
4014
|
+
setInput("");
|
|
4015
|
+
return;
|
|
4016
|
+
}
|
|
4017
|
+
if (cmdLower === "/code") {
|
|
4018
|
+
if (sessionMode === "code") {
|
|
4019
|
+
setDisplayMessages((prev) => [
|
|
4020
|
+
...prev,
|
|
4021
|
+
{ role: "user", content: trimmed },
|
|
4022
|
+
{ role: "assistant", content: "\u5DF2\u7ECF\u5728\u4EE3\u7801\u6A21\u5F0F\u4E2D\u3002\u8F93\u5165 /plan \u5207\u56DE\u8BA1\u5212\u6A21\u5F0F\u3002" }
|
|
4023
|
+
]);
|
|
4024
|
+
} else {
|
|
4025
|
+
setSessionMode("code");
|
|
4026
|
+
sessionRef.current?.setMode("code");
|
|
4027
|
+
setToolChoice(void 0);
|
|
4028
|
+
setDisplayMessages((prev) => [
|
|
4029
|
+
...prev,
|
|
4030
|
+
{ role: "user", content: trimmed },
|
|
4031
|
+
{ role: "assistant", content: "\u{1F6E0} \u5DF2\u5207\u6362\u4E3A **\u4EE3\u7801\u6A21\u5F0F**\n\n\u73B0\u5728\u53EF\u4EE5\u6B63\u5E38\u8BFB\u53D6\u548C\u4FEE\u6539\u4EE3\u7801\u4E86\u3002\n\u8F93\u5165 /plan \u5207\u6362\u4E3A\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u5206\u6790\uFF09\u3002" }
|
|
4032
|
+
]);
|
|
4033
|
+
sessionRef.current?.reset();
|
|
4034
|
+
}
|
|
4035
|
+
setInput("");
|
|
4036
|
+
return;
|
|
4037
|
+
}
|
|
3947
4038
|
if (cmdLower === "/tools") {
|
|
3948
4039
|
const next = toolChoice === void 0 ? "none" : toolChoice === "none" ? "required" : toolChoice === "required" ? "auto" : void 0;
|
|
3949
4040
|
setToolChoice(next);
|
|
@@ -4012,6 +4103,7 @@ function ChatSession({
|
|
|
4012
4103
|
]);
|
|
4013
4104
|
setInput("");
|
|
4014
4105
|
setIsStreaming(true);
|
|
4106
|
+
setStreamingPhase("thinking");
|
|
4015
4107
|
setStreamingPlaceholder(pickRandom(STREAMING_PLACEHOLDERS));
|
|
4016
4108
|
setCurrentContent("");
|
|
4017
4109
|
setCurrentToolCalls([]);
|
|
@@ -4040,6 +4132,7 @@ function ChatSession({
|
|
|
4040
4132
|
if (abortController.signal.aborted) break;
|
|
4041
4133
|
switch (event.type) {
|
|
4042
4134
|
case "text_delta":
|
|
4135
|
+
setStreamingPhase("generating");
|
|
4043
4136
|
setCurrentContent((prev) => {
|
|
4044
4137
|
const next = prev + event.content;
|
|
4045
4138
|
currentContentRef.current = next;
|
|
@@ -4047,6 +4140,7 @@ function ChatSession({
|
|
|
4047
4140
|
});
|
|
4048
4141
|
break;
|
|
4049
4142
|
case "tool_calls":
|
|
4143
|
+
setStreamingPhase("calling_tools");
|
|
4050
4144
|
setCurrentToolCalls((prev) => {
|
|
4051
4145
|
const next = [...prev, ...event.calls];
|
|
4052
4146
|
currentToolCallsRef.current = next;
|
|
@@ -4054,6 +4148,8 @@ function ChatSession({
|
|
|
4054
4148
|
});
|
|
4055
4149
|
break;
|
|
4056
4150
|
case "tool_result":
|
|
4151
|
+
setStreamingPhase("executing_tools");
|
|
4152
|
+
setTimeout(() => setStreamingPhase("thinking"), 300);
|
|
4057
4153
|
setCurrentContent("");
|
|
4058
4154
|
currentContentRef.current = "";
|
|
4059
4155
|
setCurrentToolCalls([]);
|
|
@@ -4096,6 +4192,7 @@ function ChatSession({
|
|
|
4096
4192
|
streamErrorRef.current = msg;
|
|
4097
4193
|
} finally {
|
|
4098
4194
|
setIsStreaming(false);
|
|
4195
|
+
setStreamingPhase(null);
|
|
4099
4196
|
setIdlePlaceholder(pickRandom(IDLE_PLACEHOLDERS));
|
|
4100
4197
|
abortRef.current = null;
|
|
4101
4198
|
const finContent = currentContentRef.current;
|
|
@@ -4120,7 +4217,7 @@ function ChatSession({
|
|
|
4120
4217
|
]);
|
|
4121
4218
|
}
|
|
4122
4219
|
}
|
|
4123
|
-
}, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills, thinkingEnabled, thinkingEffort, responseFormat, toolChoice, activeModel]);
|
|
4220
|
+
}, [onLaunchGame, onLaunchStock, currentContent, currentToolCalls, skills, skillSelectIndex, getFilteredSkills, thinkingEnabled, thinkingEffort, responseFormat, toolChoice, activeModel, sessionMode]);
|
|
4124
4221
|
useEffect3(() => {
|
|
4125
4222
|
if (!isStreaming && externalCostTracker) {
|
|
4126
4223
|
setTodayCost(externalCostTracker.todayTotalCost);
|
|
@@ -4153,6 +4250,7 @@ function ChatSession({
|
|
|
4153
4250
|
" \u{1F9E0} \u6DF1\u5EA6\u601D\u8003 ",
|
|
4154
4251
|
thinkingEffort === "max" ? "Max" : "High"
|
|
4155
4252
|
] }),
|
|
4253
|
+
sessionMode === "plan" && /* @__PURE__ */ jsx9(Text10, { color: "#ff69b4", bold: true, children: " \u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" }),
|
|
4156
4254
|
responseFormat === "json_object" && /* @__PURE__ */ jsx9(Text10, { color: "#4caf50", children: " \u{1F4C4} JSON" }),
|
|
4157
4255
|
toolChoice !== void 0 && /* @__PURE__ */ jsxs8(Text10, { color: "#e91e63", children: [
|
|
4158
4256
|
" \u{1F6E0} ",
|
|
@@ -4226,7 +4324,6 @@ function ChatSession({
|
|
|
4226
4324
|
isStreaming: true
|
|
4227
4325
|
}
|
|
4228
4326
|
),
|
|
4229
|
-
isStreaming && !currentContent && currentToolCalls.length === 0 && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, marginLeft: 4, children: /* @__PURE__ */ jsx9(Spinner, { type: "dots", label: "\u601D\u8003\u4E2D..." }) }),
|
|
4230
4327
|
!isStreaming && streamError && /* @__PURE__ */ jsx9(Box8, { marginTop: 1, marginLeft: 3, children: /* @__PURE__ */ jsxs8(Text10, { color: "red", children: [
|
|
4231
4328
|
"\u26A0 ",
|
|
4232
4329
|
streamError
|
|
@@ -4265,8 +4362,15 @@ function ChatSession({
|
|
|
4265
4362
|
] }),
|
|
4266
4363
|
/* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) })
|
|
4267
4364
|
] }) : /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
4268
|
-
/* @__PURE__ */ jsx9(Box8, { marginTop: 1,
|
|
4269
|
-
|
|
4365
|
+
(hasConversationStarted || sessionMode === "plan") && isStreaming && streamingPhase ? /* @__PURE__ */ jsx9(Box8, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsxs8(Text10, { bold: true, color: PHASE_CONFIG[streamingPhase].color, children: [
|
|
4366
|
+
PHASE_CONFIG[streamingPhase].icon,
|
|
4367
|
+
" ",
|
|
4368
|
+
PHASE_CONFIG[streamingPhase].label,
|
|
4369
|
+
" ",
|
|
4370
|
+
/* @__PURE__ */ jsx9(InkSpinner2, { type: "dots" })
|
|
4371
|
+
] }) }) : null,
|
|
4372
|
+
/* @__PURE__ */ jsx9(Box8, { marginTop: 1, children: hasConversationStarted || sessionMode === "plan" ? /* @__PURE__ */ jsxs8(Text10, { color: sessionMode === "plan" ? "#ff69b4" : "#00ffff", dimColor: sessionMode !== "plan", children: [
|
|
4373
|
+
/* @__PURE__ */ jsx9(Text10, { children: sessionMode === "plan" ? "\u2500".repeat(Math.max(dividerWidth - 48, 1)) : "\u2500".repeat(Math.max(dividerWidth - 35, 10)) }),
|
|
4270
4374
|
balance !== null && /* @__PURE__ */ jsxs8(Text10, { color: "yellow", children: [
|
|
4271
4375
|
" \u{1F4B0} \u4F59\u989D \xA5",
|
|
4272
4376
|
balance.toFixed(2)
|
|
@@ -4278,7 +4382,8 @@ function ChatSession({
|
|
|
4278
4382
|
] }) : sessionCost > 0 ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", children: [
|
|
4279
4383
|
" \u{1F4CA} \u672C\u6B21 \xA5",
|
|
4280
4384
|
sessionCost.toFixed(4)
|
|
4281
|
-
] }) : null
|
|
4385
|
+
] }) : null,
|
|
4386
|
+
sessionMode === "plan" && /* @__PURE__ */ jsx9(Text10, { color: "#ff69b4", bold: true, children: " \u{1F4CB} \u8BA1\u5212\u6A21\u5F0F" })
|
|
4282
4387
|
] }) : /* @__PURE__ */ jsx9(Text10, { color: "#00ffff", dimColor: true, children: "\u2500".repeat(dividerWidth) }) }),
|
|
4283
4388
|
/* @__PURE__ */ jsxs8(Box8, { children: [
|
|
4284
4389
|
/* @__PURE__ */ jsx9(Box8, { width: 4, flexShrink: 0, children: /* @__PURE__ */ jsx9(Text10, { bold: true, color: "#00ff41", children: "\u26A1" }) }),
|
|
@@ -4407,7 +4512,7 @@ function createBricks(level) {
|
|
|
4407
4512
|
function createInitialState(level) {
|
|
4408
4513
|
const def = getLevel(level);
|
|
4409
4514
|
const totalW = def.cols * def.bw + (def.cols - 1) * 2;
|
|
4410
|
-
const
|
|
4515
|
+
const _startX = Math.floor((GAME_WIDTH - totalW) / 2);
|
|
4411
4516
|
return {
|
|
4412
4517
|
level,
|
|
4413
4518
|
bricks: createBricks(level),
|
|
@@ -5534,7 +5639,7 @@ import chalk5 from "chalk";
|
|
|
5534
5639
|
|
|
5535
5640
|
// src/stock/StockList.tsx
|
|
5536
5641
|
import { Box as Box12, Text as Text14, useInput as useInput5 } from "ink";
|
|
5537
|
-
import { useState as useState7, useCallback as useCallback6, useEffect as useEffect6 } from "react";
|
|
5642
|
+
import { useState as useState7, useCallback as useCallback6, useEffect as useEffect6, useMemo as useMemo2 } from "react";
|
|
5538
5643
|
import asciichart from "asciichart";
|
|
5539
5644
|
import os from "os";
|
|
5540
5645
|
import { join as join7 } from "path";
|
|
@@ -5654,6 +5759,13 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5654
5759
|
() => (/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour12: false })
|
|
5655
5760
|
);
|
|
5656
5761
|
const [dimMode, setDimMode] = useState7(false);
|
|
5762
|
+
const [sortOrder, setSortOrder] = useState7("default");
|
|
5763
|
+
const sortedStocks = useMemo2(() => {
|
|
5764
|
+
if (sortOrder === "default") return stocks;
|
|
5765
|
+
return [...stocks].toSorted(
|
|
5766
|
+
(a, b) => sortOrder === "desc" ? b.changePercent - a.changePercent : a.changePercent - b.changePercent
|
|
5767
|
+
);
|
|
5768
|
+
}, [stocks, sortOrder]);
|
|
5657
5769
|
const { doubleCtrlC, handleCtrlC } = useDoubleCtrlC(onExit);
|
|
5658
5770
|
useEffect6(() => {
|
|
5659
5771
|
const timer = setInterval(() => {
|
|
@@ -5672,13 +5784,13 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5672
5784
|
setLoading(false);
|
|
5673
5785
|
}, [codes]);
|
|
5674
5786
|
useEffect6(() => {
|
|
5675
|
-
loadData();
|
|
5787
|
+
void loadData();
|
|
5676
5788
|
}, [loadData]);
|
|
5677
5789
|
useEffect6(() => {
|
|
5678
5790
|
const interval = setInterval(() => {
|
|
5679
5791
|
setCountdown((prev) => {
|
|
5680
5792
|
if (prev <= 1) {
|
|
5681
|
-
loadData();
|
|
5793
|
+
void loadData();
|
|
5682
5794
|
return 5;
|
|
5683
5795
|
}
|
|
5684
5796
|
return prev - 1;
|
|
@@ -5687,24 +5799,23 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5687
5799
|
return () => clearInterval(interval);
|
|
5688
5800
|
}, [loadData]);
|
|
5689
5801
|
useEffect6(() => {
|
|
5690
|
-
if (
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5802
|
+
if (detailView) {
|
|
5803
|
+
const loadDetail = () => {
|
|
5804
|
+
minuteCache.delete(detailView.code);
|
|
5805
|
+
void fetchStockMinute(detailView.code).then((data) => {
|
|
5806
|
+
if (data && data.prices.length > 0) {
|
|
5807
|
+
cacheMinute(detailView.code, data.prices);
|
|
5808
|
+
setDetailPrices(data.prices);
|
|
5809
|
+
}
|
|
5810
|
+
});
|
|
5811
|
+
};
|
|
5812
|
+
loadDetail();
|
|
5813
|
+
setDetailCountdown(10);
|
|
5814
|
+
const timer = setInterval(loadDetail, 1e4);
|
|
5815
|
+
return () => clearInterval(timer);
|
|
5694
5816
|
}
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
fetchStockMinute(detailView.code).then((data) => {
|
|
5698
|
-
if (data && data.prices.length > 0) {
|
|
5699
|
-
cacheMinute(detailView.code, data.prices);
|
|
5700
|
-
setDetailPrices(data.prices);
|
|
5701
|
-
}
|
|
5702
|
-
});
|
|
5703
|
-
};
|
|
5704
|
-
loadDetail();
|
|
5705
|
-
setDetailCountdown(10);
|
|
5706
|
-
const timer = setInterval(loadDetail, 1e4);
|
|
5707
|
-
return () => clearInterval(timer);
|
|
5817
|
+
setDetailPrices(null);
|
|
5818
|
+
setDetailLoading(false);
|
|
5708
5819
|
}, [detailView]);
|
|
5709
5820
|
useEffect6(() => {
|
|
5710
5821
|
if (!detailView) return;
|
|
@@ -5739,7 +5850,9 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5739
5850
|
else onExit();
|
|
5740
5851
|
} else if (input === "r") {
|
|
5741
5852
|
setCountdown(5);
|
|
5742
|
-
loadData();
|
|
5853
|
+
void loadData();
|
|
5854
|
+
} else if (input === "o") {
|
|
5855
|
+
setSortOrder((prev) => prev === "default" ? "desc" : prev === "desc" ? "asc" : "default");
|
|
5743
5856
|
} else if (input === "h") {
|
|
5744
5857
|
setDimMode((v) => !v);
|
|
5745
5858
|
}
|
|
@@ -5768,14 +5881,17 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5768
5881
|
/* @__PURE__ */ jsx13(Box12, { width: 9, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u4EE3\u7801" }) }),
|
|
5769
5882
|
/* @__PURE__ */ jsx13(Box12, { width: 16, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u540D\u79F0" }) }),
|
|
5770
5883
|
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u65B0\u4EF7" }) }),
|
|
5771
|
-
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */
|
|
5884
|
+
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsxs12(Text14, { dimColor: true, children: [
|
|
5885
|
+
"\u6DA8\u8DCC\u5E45",
|
|
5886
|
+
sortOrder === "desc" ? " \u25BC" : sortOrder === "asc" ? " \u25B2" : ""
|
|
5887
|
+
] }) }),
|
|
5772
5888
|
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6DA8\u8DCC\u989D" }) }),
|
|
5773
5889
|
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u9AD8" }) }),
|
|
5774
5890
|
/* @__PURE__ */ jsx13(Box12, { width: 12, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6700\u4F4E" }) }),
|
|
5775
5891
|
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: "\u6210\u4EA4\u989D" }) })
|
|
5776
5892
|
] }),
|
|
5777
5893
|
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: " " + "\u2500".repeat(100) }) }),
|
|
5778
|
-
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children:
|
|
5894
|
+
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: sortedStocks.map((stock, index) => {
|
|
5779
5895
|
const isSelected = index === selectedIndex;
|
|
5780
5896
|
const isUp = stock.changePercent >= 0;
|
|
5781
5897
|
const color = isUp ? "#ff1493" : "#00ff41";
|
|
@@ -5798,7 +5914,7 @@ function StockList({ codes, onExit, onBackToChat }) {
|
|
|
5798
5914
|
/* @__PURE__ */ jsx13(Box12, { children: /* @__PURE__ */ jsx13(Text14, { ...cp2("#888888"), children: formatAmount(stock.amount) }) })
|
|
5799
5915
|
] }, stock.code);
|
|
5800
5916
|
}) }),
|
|
5801
|
-
/* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u2191/\u2193 \u9009\u62E9 Enter \u8BE6\u60C5 r \u624B\u52A8\u5237\u65B0 h \u7F6E\u7070/\u6062\u590D q \u8FD4\u56DE` }) }),
|
|
5917
|
+
/* @__PURE__ */ jsx13(Box12, { marginTop: 1, children: /* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u2191/\u2193 \u9009\u62E9 Enter \u8BE6\u60C5 r \u624B\u52A8\u5237\u65B0 o \u6392\u5E8F h \u7F6E\u7070/\u6062\u590D q \u8FD4\u56DE` }) }),
|
|
5802
5918
|
/* @__PURE__ */ jsxs12(Box12, { children: [
|
|
5803
5919
|
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: ` \u6700\u540E\u66F4\u65B0: ${lastUpdate} \u7F16\u8F91\u81EA\u9009\u80A1: ` }),
|
|
5804
5920
|
/* @__PURE__ */ jsx13(Text14, { ...cp2("#c792ea"), children: osc8Link(toFileUrl(SETTINGS_PATH), SETTINGS_PATH) })
|
|
@@ -5973,81 +6089,8 @@ function createCli() {
|
|
|
5973
6089
|
budgetLimit: ctx?.config.budgetLimit ?? 0,
|
|
5974
6090
|
tokenBudgetLimit: ctx?.config.tokenBudgetLimit ?? 0
|
|
5975
6091
|
});
|
|
5976
|
-
startChat(ctx, costTracker);
|
|
6092
|
+
void startChat(ctx, costTracker);
|
|
5977
6093
|
});
|
|
5978
|
-
async function startChat(ctx, costTracker) {
|
|
5979
|
-
const [globalSkillCount, localSkillCount, skills, files] = await Promise.all([
|
|
5980
|
-
countDskcodeSkills(),
|
|
5981
|
-
countProjectLocalSkills(process.cwd()),
|
|
5982
|
-
getAllSkills(process.cwd()),
|
|
5983
|
-
scanProjectFiles(process.cwd())
|
|
5984
|
-
]);
|
|
5985
|
-
const skillCount = globalSkillCount + localSkillCount;
|
|
5986
|
-
const defaultProvider = ctx?.config.providers.find(
|
|
5987
|
-
(p) => p.name === (ctx?.config.defaultProvider ?? "deepseek")
|
|
5988
|
-
);
|
|
5989
|
-
const model = defaultProvider?.model ?? "deepseek-v4-flash";
|
|
5990
|
-
const chatApp = renderApp(
|
|
5991
|
-
/* @__PURE__ */ jsx14(
|
|
5992
|
-
ChatSession,
|
|
5993
|
-
{
|
|
5994
|
-
skillCount,
|
|
5995
|
-
skills,
|
|
5996
|
-
files,
|
|
5997
|
-
toolCount: ctx?.config.tools.length ?? 0,
|
|
5998
|
-
verbose: ctx?.verbose ?? false,
|
|
5999
|
-
apiKey: defaultProvider?.apiKey,
|
|
6000
|
-
baseUrl: defaultProvider?.baseUrl ?? "https://api.deepseek.com",
|
|
6001
|
-
costTracker,
|
|
6002
|
-
model,
|
|
6003
|
-
onLaunchGame: () => {
|
|
6004
|
-
chatApp.unmount();
|
|
6005
|
-
setImmediate(() => {
|
|
6006
|
-
initGames();
|
|
6007
|
-
const games = listGames();
|
|
6008
|
-
const { unmount } = render4(
|
|
6009
|
-
/* @__PURE__ */ jsx14(
|
|
6010
|
-
GamePicker,
|
|
6011
|
-
{
|
|
6012
|
-
games,
|
|
6013
|
-
onSelect: async (game) => {
|
|
6014
|
-
unmount();
|
|
6015
|
-
await game.play();
|
|
6016
|
-
startChat(ctx, costTracker);
|
|
6017
|
-
},
|
|
6018
|
-
onBackToChat: () => {
|
|
6019
|
-
unmount();
|
|
6020
|
-
setImmediate(() => startChat(ctx, costTracker));
|
|
6021
|
-
}
|
|
6022
|
-
}
|
|
6023
|
-
),
|
|
6024
|
-
{ exitOnCtrlC: false }
|
|
6025
|
-
);
|
|
6026
|
-
});
|
|
6027
|
-
},
|
|
6028
|
-
onLaunchStock: () => {
|
|
6029
|
-
chatApp.unmount();
|
|
6030
|
-
setImmediate(() => {
|
|
6031
|
-
const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
6032
|
-
const stockApp = renderApp(
|
|
6033
|
-
/* @__PURE__ */ jsx14(
|
|
6034
|
-
StockList,
|
|
6035
|
-
{
|
|
6036
|
-
codes: defaultStockCodes,
|
|
6037
|
-
onBackToChat: () => {
|
|
6038
|
-
stockApp.unmount();
|
|
6039
|
-
setImmediate(() => startChat(ctx, costTracker));
|
|
6040
|
-
},
|
|
6041
|
-
onExit: () => process.exit(0)
|
|
6042
|
-
}
|
|
6043
|
-
)
|
|
6044
|
-
);
|
|
6045
|
-
});
|
|
6046
|
-
}
|
|
6047
|
-
}
|
|
6048
|
-
)
|
|
6049
|
-
);
|
|
6050
|
-
}
|
|
6051
6094
|
program2.command("run").description("\u6267\u884C\u4E00\u6B21\u6027\u4EFB\u52A1").argument("[prompt...]", "\u4EFB\u52A1\u63CF\u8FF0").option("--model <name>", "\u6307\u5B9A\u4F7F\u7528\u7684\u6A21\u578B").action(async function(_prompt) {
|
|
6052
6095
|
console.log("dskcode run \u2014 \u5F85\u5B9E\u73B0\uFF08\u7B2C07\u7AE0\uFF09");
|
|
6053
6096
|
});
|
|
@@ -6092,7 +6135,7 @@ compdef _dskcode_completion dskcode`);
|
|
|
6092
6135
|
}
|
|
6093
6136
|
});
|
|
6094
6137
|
program2.command("stock").description("\u67E5\u770B\u81EA\u9009\u80A1\u5B9E\u65F6\u884C\u60C5").argument("[codes...]", "\u80A1\u7968\u4EE3\u7801\uFF08\u7A7A\u683C\u5206\u9694\uFF09\uFF0C\u5982 513090 600519").action(async function(codes) {
|
|
6095
|
-
const
|
|
6138
|
+
const _ctx = this.dskcodeCtx;
|
|
6096
6139
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "~";
|
|
6097
6140
|
const globalConfigPath = join9(home, ".dskcode", "settings.json");
|
|
6098
6141
|
let globalConfigHasStock = false;
|
|
@@ -6173,6 +6216,79 @@ compdef _dskcode_completion dskcode`);
|
|
|
6173
6216
|
});
|
|
6174
6217
|
return program2;
|
|
6175
6218
|
}
|
|
6219
|
+
async function startChat(ctx, costTracker) {
|
|
6220
|
+
const [globalSkillCount, localSkillCount, skills, files] = await Promise.all([
|
|
6221
|
+
countDskcodeSkills(),
|
|
6222
|
+
countProjectLocalSkills(process.cwd()),
|
|
6223
|
+
getAllSkills(process.cwd()),
|
|
6224
|
+
scanProjectFiles(process.cwd())
|
|
6225
|
+
]);
|
|
6226
|
+
const skillCount = globalSkillCount + localSkillCount;
|
|
6227
|
+
const defaultProvider = ctx?.config.providers.find(
|
|
6228
|
+
(p) => p.name === (ctx?.config.defaultProvider ?? "deepseek")
|
|
6229
|
+
);
|
|
6230
|
+
const model = defaultProvider?.model ?? "deepseek-v4-flash";
|
|
6231
|
+
const chatApp = renderApp(
|
|
6232
|
+
/* @__PURE__ */ jsx14(
|
|
6233
|
+
ChatSession,
|
|
6234
|
+
{
|
|
6235
|
+
skillCount,
|
|
6236
|
+
skills,
|
|
6237
|
+
files,
|
|
6238
|
+
toolCount: ctx?.config.tools.length ?? 0,
|
|
6239
|
+
verbose: ctx?.verbose ?? false,
|
|
6240
|
+
apiKey: defaultProvider?.apiKey,
|
|
6241
|
+
baseUrl: defaultProvider?.baseUrl ?? "https://api.deepseek.com",
|
|
6242
|
+
costTracker,
|
|
6243
|
+
model,
|
|
6244
|
+
onLaunchGame: () => {
|
|
6245
|
+
chatApp.unmount();
|
|
6246
|
+
setImmediate(() => {
|
|
6247
|
+
initGames();
|
|
6248
|
+
const games = listGames();
|
|
6249
|
+
const { unmount } = render4(
|
|
6250
|
+
/* @__PURE__ */ jsx14(
|
|
6251
|
+
GamePicker,
|
|
6252
|
+
{
|
|
6253
|
+
games,
|
|
6254
|
+
onSelect: async (game) => {
|
|
6255
|
+
unmount();
|
|
6256
|
+
await game.play();
|
|
6257
|
+
void startChat(ctx, costTracker);
|
|
6258
|
+
},
|
|
6259
|
+
onBackToChat: () => {
|
|
6260
|
+
unmount();
|
|
6261
|
+
setImmediate(() => startChat(ctx, costTracker));
|
|
6262
|
+
}
|
|
6263
|
+
}
|
|
6264
|
+
),
|
|
6265
|
+
{ exitOnCtrlC: false }
|
|
6266
|
+
);
|
|
6267
|
+
});
|
|
6268
|
+
},
|
|
6269
|
+
onLaunchStock: () => {
|
|
6270
|
+
chatApp.unmount();
|
|
6271
|
+
setImmediate(() => {
|
|
6272
|
+
const defaultStockCodes = ctx?.config.stock?.symbols?.map((s) => s.code) ?? ["sh000001", "sz399006", "sh601688"];
|
|
6273
|
+
const stockApp = renderApp(
|
|
6274
|
+
/* @__PURE__ */ jsx14(
|
|
6275
|
+
StockList,
|
|
6276
|
+
{
|
|
6277
|
+
codes: defaultStockCodes,
|
|
6278
|
+
onBackToChat: () => {
|
|
6279
|
+
stockApp.unmount();
|
|
6280
|
+
setImmediate(() => startChat(ctx, costTracker));
|
|
6281
|
+
},
|
|
6282
|
+
onExit: () => process.exit(0)
|
|
6283
|
+
}
|
|
6284
|
+
)
|
|
6285
|
+
);
|
|
6286
|
+
});
|
|
6287
|
+
}
|
|
6288
|
+
}
|
|
6289
|
+
)
|
|
6290
|
+
);
|
|
6291
|
+
}
|
|
6176
6292
|
|
|
6177
6293
|
// src/cli/exit-codes.ts
|
|
6178
6294
|
var ExitCode = {
|