@ww_nero/mini-cli 1.0.91 → 1.0.92

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 CHANGED
File without changes
package/bin/mini.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ww_nero/mini-cli",
3
- "version": "1.0.91",
3
+ "version": "1.0.92",
4
4
  "description": "极简的 AI 命令行助手",
5
5
  "bin": {
6
6
  "mini": "bin/mini.js"
package/src/chat.js CHANGED
@@ -26,7 +26,7 @@ const {
26
26
  mergeReasoningContent,
27
27
  renderAssistantOutput,
28
28
  sanitizeContentWithThink,
29
- printUsageTokens
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 = '⌛ 回答中...(按 Esc 取消)';
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(LOADING_PROMPT_BASE_TEXT);
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 = (loadingPromptFrame + 1) % loadingPromptCharCount;
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(
@@ -1000,7 +1020,6 @@ const startChatSession = async ({
1000
1020
  content: toolContent
1001
1021
  });
1002
1022
  }
1003
- printUsageTokens(result.usage);
1004
1023
  persistHistorySafely();
1005
1024
 
1006
1025
  // 检测是否需要触发 compact
@@ -1052,7 +1071,6 @@ const startChatSession = async ({
1052
1071
  );
1053
1072
  messages.push(assistantMessage);
1054
1073
  persistHistorySafely();
1055
- printUsageTokens(result.usage);
1056
1074
  break;
1057
1075
  }
1058
1076
  };
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);
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
File without changes
package/src/tools/mcp.js CHANGED
File without changes
package/src/tools/read.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
package/src/utils/git.js CHANGED
File without changes
File without changes
File without changes
package/src/utils/menu.js CHANGED
File without changes
File without changes
@@ -77,7 +77,7 @@ const printReasoningContent = (text, ensureNewline) => {
77
77
 
78
78
  if (!normalized) return;
79
79
  ensureNewline();
80
- console.log(chalk.gray(`思考:\n${normalized}`));
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 printUsageTokens = (usage) => {
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
- console.log(chalk.gray(`已使用tokens: ${formatted}`));
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
- printUsageTokens
137
+ formatUsageTokens
138
138
  };
File without changes
File without changes
File without changes
File without changes