@ww_nero/mini-cli 1.0.91 → 1.0.93
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 +0 -0
- package/bin/mini.js +0 -0
- package/package.json +1 -1
- package/src/chat.js +35 -8
- package/src/config.js +0 -0
- package/src/index.js +0 -0
- package/src/llm.js +6 -1
- package/src/prompt/tool.js +0 -0
- package/src/request.js +4 -0
- package/src/tools/bash.js +0 -0
- package/src/tools/edit.js +0 -0
- package/src/tools/index.js +0 -0
- package/src/tools/mcp.js +0 -0
- package/src/tools/read.js +0 -0
- package/src/tools/skills.js +0 -0
- package/src/tools/write.js +0 -0
- package/src/utils/cliOptions.js +0 -0
- package/src/utils/commands.js +0 -0
- package/src/utils/git.js +0 -0
- package/src/utils/helpers.js +0 -0
- package/src/utils/history.js +0 -0
- package/src/utils/menu.js +0 -0
- package/src/utils/model.js +0 -0
- package/src/utils/output.js +6 -6
- package/src/utils/renderer.js +0 -0
- package/src/utils/settings.js +0 -0
- package/src/utils/skills.js +0 -0
- package/src/utils/think.js +0 -0
package/README.md
CHANGED
|
File without changes
|
package/bin/mini.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/src/chat.js
CHANGED
|
@@ -26,7 +26,7 @@ const {
|
|
|
26
26
|
mergeReasoningContent,
|
|
27
27
|
renderAssistantOutput,
|
|
28
28
|
sanitizeContentWithThink,
|
|
29
|
-
|
|
29
|
+
formatUsageTokens
|
|
30
30
|
} = require('./utils/output');
|
|
31
31
|
const {
|
|
32
32
|
createHistoryFilePath,
|
|
@@ -598,21 +598,29 @@ const startChatSession = async ({
|
|
|
598
598
|
const DEFAULT_PROMPT = `${chalk.cyan('用户>')} `;
|
|
599
599
|
rl.setPrompt(DEFAULT_PROMPT);
|
|
600
600
|
|
|
601
|
-
const LOADING_PROMPT_BASE_TEXT = '
|
|
601
|
+
const LOADING_PROMPT_BASE_TEXT = '思考中...';
|
|
602
602
|
const FLOW_GRADIENT_COLORS = ['#FFF7CC', '#FFE58F', '#FFD666', '#FFC53D', '#FFA940', '#FF7A45'];
|
|
603
603
|
const FLOW_DIM_COLOR = '#5F5F6A';
|
|
604
|
-
const loadingPromptCharacters = Array.from(LOADING_PROMPT_BASE_TEXT);
|
|
605
|
-
const loadingPromptCharCount = loadingPromptCharacters.length || 1;
|
|
606
604
|
const supportsHexColor = typeof chalk.hex === 'function';
|
|
607
605
|
const flowGradientFns = supportsHexColor
|
|
608
606
|
? FLOW_GRADIENT_COLORS.map((hex) => chalk.hex(hex))
|
|
609
607
|
: [];
|
|
610
608
|
const dimTextFn = supportsHexColor ? chalk.hex(FLOW_DIM_COLOR) : chalk.yellow;
|
|
611
609
|
|
|
610
|
+
const buildLoadingPromptText = () => {
|
|
611
|
+
if (!loadingPromptTokensText) {
|
|
612
|
+
return `${LOADING_PROMPT_BASE_TEXT}(按Esc取消)`;
|
|
613
|
+
}
|
|
614
|
+
return `${LOADING_PROMPT_BASE_TEXT}(${loadingPromptTokensText},按Esc取消)`;
|
|
615
|
+
};
|
|
616
|
+
|
|
612
617
|
const formatLoadingPrompt = (frame) => {
|
|
618
|
+
const promptText = buildLoadingPromptText();
|
|
613
619
|
if (!supportsHexColor) {
|
|
614
|
-
return chalk.yellow(
|
|
620
|
+
return chalk.yellow(promptText);
|
|
615
621
|
}
|
|
622
|
+
const loadingPromptCharacters = Array.from(promptText);
|
|
623
|
+
const loadingPromptCharCount = loadingPromptCharacters.length || 1;
|
|
616
624
|
const gradientLength = Math.min(flowGradientFns.length, loadingPromptCharCount);
|
|
617
625
|
const startIndex = frame % loadingPromptCharCount;
|
|
618
626
|
return loadingPromptCharacters.map((char, index) => {
|
|
@@ -628,6 +636,7 @@ const startChatSession = async ({
|
|
|
628
636
|
let loadingPromptFrame = 0;
|
|
629
637
|
let loadingPromptTimer = null;
|
|
630
638
|
let loadingPromptVisible = false;
|
|
639
|
+
let loadingPromptTokensText = '';
|
|
631
640
|
|
|
632
641
|
const getCurrentLoadingPromptText = () => formatLoadingPrompt(loadingPromptFrame);
|
|
633
642
|
|
|
@@ -635,7 +644,7 @@ const startChatSession = async ({
|
|
|
635
644
|
if (!loadingPromptVisible || !supportsHexColor) {
|
|
636
645
|
return;
|
|
637
646
|
}
|
|
638
|
-
loadingPromptFrame
|
|
647
|
+
loadingPromptFrame += 1;
|
|
639
648
|
refreshLoadingPrompt();
|
|
640
649
|
};
|
|
641
650
|
|
|
@@ -681,6 +690,15 @@ const startChatSession = async ({
|
|
|
681
690
|
writeLoadingPrompt();
|
|
682
691
|
};
|
|
683
692
|
|
|
693
|
+
const updateLoadingPromptTokens = (usage) => {
|
|
694
|
+
const nextText = formatUsageTokens(usage) || '';
|
|
695
|
+
if (nextText === loadingPromptTokensText) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
loadingPromptTokensText = nextText;
|
|
699
|
+
refreshLoadingPrompt();
|
|
700
|
+
};
|
|
701
|
+
|
|
684
702
|
const clearLoadingPrompt = () => {
|
|
685
703
|
if (!loadingPromptVisible) {
|
|
686
704
|
return;
|
|
@@ -908,6 +926,7 @@ const startChatSession = async ({
|
|
|
908
926
|
tools: toolSchemas,
|
|
909
927
|
onToken: handleStreamChunk,
|
|
910
928
|
onReasoningToken: handleReasoningChunk,
|
|
929
|
+
onUsage: updateLoadingPromptTokens,
|
|
911
930
|
onRetry: (retryCount, error) => {
|
|
912
931
|
const detail = error ? `(${error.message})` : '';
|
|
913
932
|
process.stdout.write(`\n${chalk.yellow(`请求失败,${retryCount} 次重试中${detail}...`)}\n`);
|
|
@@ -915,6 +934,7 @@ const startChatSession = async ({
|
|
|
915
934
|
});
|
|
916
935
|
|
|
917
936
|
finalizeStreamState();
|
|
937
|
+
updateLoadingPromptTokens(result.usage);
|
|
918
938
|
|
|
919
939
|
const rawReasoning = (reasoningFromModel || result.reasoningContent || '').trim();
|
|
920
940
|
const mergedReasoning = mergeReasoningContent(
|
|
@@ -985,6 +1005,15 @@ const startChatSession = async ({
|
|
|
985
1005
|
if (editOutput) {
|
|
986
1006
|
console.log(editOutput);
|
|
987
1007
|
}
|
|
1008
|
+
} else if (functionName === 'read') {
|
|
1009
|
+
// read 工具特殊处理:成功时显示行数,失败时显示错误信息
|
|
1010
|
+
const normalized = rawToolContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n').trim();
|
|
1011
|
+
const lineCount = countLines(normalized);
|
|
1012
|
+
if (normalized && !normalized.startsWith('读取失败') && !normalized.startsWith('无效路径') && !normalized.startsWith('filePath 参数不能为空')) {
|
|
1013
|
+
console.log(chalk.gray(`已读取,共${lineCount}行`));
|
|
1014
|
+
} else {
|
|
1015
|
+
console.log(chalk.gray(indentToolResult(rawToolContent)));
|
|
1016
|
+
}
|
|
988
1017
|
} else {
|
|
989
1018
|
const displayResult = formatToolResultForDisplay(rawToolContent, 100);
|
|
990
1019
|
if (displayResult) {
|
|
@@ -1000,7 +1029,6 @@ const startChatSession = async ({
|
|
|
1000
1029
|
content: toolContent
|
|
1001
1030
|
});
|
|
1002
1031
|
}
|
|
1003
|
-
printUsageTokens(result.usage);
|
|
1004
1032
|
persistHistorySafely();
|
|
1005
1033
|
|
|
1006
1034
|
// 检测是否需要触发 compact
|
|
@@ -1052,7 +1080,6 @@ const startChatSession = async ({
|
|
|
1052
1080
|
);
|
|
1053
1081
|
messages.push(assistantMessage);
|
|
1054
1082
|
persistHistorySafely();
|
|
1055
|
-
printUsageTokens(result.usage);
|
|
1056
1083
|
break;
|
|
1057
1084
|
}
|
|
1058
1085
|
};
|
package/src/config.js
CHANGED
|
File without changes
|
package/src/index.js
CHANGED
|
File without changes
|
package/src/llm.js
CHANGED
|
@@ -68,7 +68,7 @@ const sanitizeOptions = (options = {}) => {
|
|
|
68
68
|
}, {});
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
const chatCompletion = async ({ endpoint, messages, abortController, onToken, onReasoningToken, onRetry, onComplete, tools = [] }) => {
|
|
71
|
+
const chatCompletion = async ({ endpoint, messages, abortController, onToken, onReasoningToken, onUsage, onRetry, onComplete, tools = [] }) => {
|
|
72
72
|
const controller = abortController || new AbortController();
|
|
73
73
|
const includeToolCalls = Array.isArray(tools) && tools.length > 0;
|
|
74
74
|
|
|
@@ -112,6 +112,11 @@ const chatCompletion = async ({ endpoint, messages, abortController, onToken, on
|
|
|
112
112
|
onReasoningToken(chunk, aggregate);
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
|
+
onUsage: (usage) => {
|
|
116
|
+
if (onUsage) {
|
|
117
|
+
onUsage(usage);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
115
120
|
onComplete: () => {
|
|
116
121
|
if (onComplete) {
|
|
117
122
|
onComplete(fullContent);
|
package/src/prompt/tool.js
CHANGED
|
File without changes
|
package/src/request.js
CHANGED
|
@@ -88,6 +88,7 @@ const processStreamResponse = (response, options = {}) => {
|
|
|
88
88
|
const {
|
|
89
89
|
onContent = null,
|
|
90
90
|
onReasoningContent = null,
|
|
91
|
+
onUsage = null,
|
|
91
92
|
onComplete = null,
|
|
92
93
|
abortController = null,
|
|
93
94
|
includeToolCalls = false
|
|
@@ -138,6 +139,9 @@ const processStreamResponse = (response, options = {}) => {
|
|
|
138
139
|
const payload = JSON.parse(event.data);
|
|
139
140
|
if (payload.usage && typeof payload.usage === 'object') {
|
|
140
141
|
usage = payload.usage;
|
|
142
|
+
if (onUsage) {
|
|
143
|
+
onUsage(usage);
|
|
144
|
+
}
|
|
141
145
|
}
|
|
142
146
|
const choice = payload.choices && payload.choices[0];
|
|
143
147
|
if (!choice || !choice.delta) return;
|
package/src/tools/bash.js
CHANGED
|
File without changes
|
package/src/tools/edit.js
CHANGED
|
File without changes
|
package/src/tools/index.js
CHANGED
|
File without changes
|
package/src/tools/mcp.js
CHANGED
|
File without changes
|
package/src/tools/read.js
CHANGED
|
File without changes
|
package/src/tools/skills.js
CHANGED
|
File without changes
|
package/src/tools/write.js
CHANGED
|
File without changes
|
package/src/utils/cliOptions.js
CHANGED
|
File without changes
|
package/src/utils/commands.js
CHANGED
|
File without changes
|
package/src/utils/git.js
CHANGED
|
File without changes
|
package/src/utils/helpers.js
CHANGED
|
File without changes
|
package/src/utils/history.js
CHANGED
|
File without changes
|
package/src/utils/menu.js
CHANGED
|
File without changes
|
package/src/utils/model.js
CHANGED
|
File without changes
|
package/src/utils/output.js
CHANGED
|
@@ -77,7 +77,7 @@ const printReasoningContent = (text, ensureNewline) => {
|
|
|
77
77
|
|
|
78
78
|
if (!normalized) return;
|
|
79
79
|
ensureNewline();
|
|
80
|
-
console.log(chalk.gray(
|
|
80
|
+
console.log(chalk.gray(normalized));
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
const printAssistantContent = (text, ensureNewline) => {
|
|
@@ -116,16 +116,16 @@ const formatTokensToK = (totalTokens) => {
|
|
|
116
116
|
return `${(totalTokens / 1000).toFixed(1)}k`;
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
-
const
|
|
119
|
+
const formatUsageTokens = (usage) => {
|
|
120
120
|
if (!usage || typeof usage !== 'object') {
|
|
121
|
-
return;
|
|
121
|
+
return null;
|
|
122
122
|
}
|
|
123
123
|
const totalTokens = usage.total_tokens;
|
|
124
124
|
const formatted = formatTokensToK(totalTokens);
|
|
125
125
|
if (!formatted) {
|
|
126
|
-
return;
|
|
126
|
+
return null;
|
|
127
127
|
}
|
|
128
|
-
|
|
128
|
+
return `会话tokens: ${formatted}`;
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
module.exports = {
|
|
@@ -134,5 +134,5 @@ module.exports = {
|
|
|
134
134
|
printAssistantContent,
|
|
135
135
|
renderAssistantOutput,
|
|
136
136
|
sanitizeContentWithThink,
|
|
137
|
-
|
|
137
|
+
formatUsageTokens
|
|
138
138
|
};
|
package/src/utils/renderer.js
CHANGED
|
File without changes
|
package/src/utils/settings.js
CHANGED
|
File without changes
|
package/src/utils/skills.js
CHANGED
|
File without changes
|
package/src/utils/think.js
CHANGED
|
File without changes
|