@xagent-ai/cli 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  3. package/README.md +280 -280
  4. package/README_CN.md +3 -3
  5. package/dist/ai-client.d.ts.map +1 -1
  6. package/dist/ai-client.js +84 -82
  7. package/dist/ai-client.js.map +1 -1
  8. package/dist/auth.d.ts +0 -1
  9. package/dist/auth.d.ts.map +1 -1
  10. package/dist/auth.js +75 -105
  11. package/dist/auth.js.map +1 -1
  12. package/dist/cli.js +166 -13
  13. package/dist/cli.js.map +1 -1
  14. package/dist/config.d.ts +3 -1
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js +48 -7
  17. package/dist/config.js.map +1 -1
  18. package/dist/context-compressor.d.ts +5 -5
  19. package/dist/context-compressor.js +8 -8
  20. package/dist/context-compressor.js.map +1 -1
  21. package/dist/gui-subagent/action-parser/actionParser.d.ts +7 -0
  22. package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
  23. package/dist/gui-subagent/action-parser/actionParser.js +6 -3
  24. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
  25. package/dist/gui-subagent/action-parser/constants.d.ts +6 -0
  26. package/dist/gui-subagent/action-parser/constants.d.ts.map +1 -1
  27. package/dist/gui-subagent/action-parser/constants.js +5 -3
  28. package/dist/gui-subagent/action-parser/constants.js.map +1 -1
  29. package/dist/gui-subagent/action-parser/index.d.ts +6 -0
  30. package/dist/gui-subagent/action-parser/index.d.ts.map +1 -1
  31. package/dist/gui-subagent/action-parser/index.js +5 -3
  32. package/dist/gui-subagent/action-parser/index.js.map +1 -1
  33. package/dist/gui-subagent/action-parser/types.d.ts +4 -0
  34. package/dist/gui-subagent/action-parser/types.d.ts.map +1 -1
  35. package/dist/gui-subagent/action-parser/types.js +3 -3
  36. package/dist/gui-subagent/agent/gui-agent.d.ts +39 -0
  37. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
  38. package/dist/gui-subagent/agent/gui-agent.js +164 -89
  39. package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
  40. package/dist/gui-subagent/agent/index.d.ts +1 -1
  41. package/dist/gui-subagent/agent/index.d.ts.map +1 -1
  42. package/dist/gui-subagent/agent/index.js.map +1 -1
  43. package/dist/gui-subagent/index.d.ts +27 -1
  44. package/dist/gui-subagent/index.d.ts.map +1 -1
  45. package/dist/gui-subagent/index.js +6 -0
  46. package/dist/gui-subagent/index.js.map +1 -1
  47. package/dist/logger.js +1 -1
  48. package/dist/logger.js.map +1 -1
  49. package/dist/mcp.d.ts +1 -0
  50. package/dist/mcp.d.ts.map +1 -1
  51. package/dist/mcp.js +140 -29
  52. package/dist/mcp.js.map +1 -1
  53. package/dist/remote-ai-client.d.ts +111 -0
  54. package/dist/remote-ai-client.d.ts.map +1 -0
  55. package/dist/remote-ai-client.js +558 -0
  56. package/dist/remote-ai-client.js.map +1 -0
  57. package/dist/sdk-output-adapter.d.ts +232 -0
  58. package/dist/sdk-output-adapter.d.ts.map +1 -0
  59. package/dist/sdk-output-adapter.js +636 -0
  60. package/dist/sdk-output-adapter.js.map +1 -0
  61. package/dist/sdk-session-v2.d.ts +13 -0
  62. package/dist/sdk-session-v2.d.ts.map +1 -0
  63. package/dist/sdk-session-v2.js +46 -0
  64. package/dist/sdk-session-v2.js.map +1 -0
  65. package/dist/sdk-session.d.ts +13 -0
  66. package/dist/sdk-session.d.ts.map +1 -0
  67. package/dist/sdk-session.js +48 -0
  68. package/dist/sdk-session.js.map +1 -0
  69. package/dist/session-manager.js +3 -3
  70. package/dist/session-manager.js.map +1 -1
  71. package/dist/session.d.ts +46 -3
  72. package/dist/session.d.ts.map +1 -1
  73. package/dist/session.js +564 -117
  74. package/dist/session.js.map +1 -1
  75. package/dist/skill-invoker.d.ts +40 -4
  76. package/dist/skill-invoker.d.ts.map +1 -1
  77. package/dist/skill-invoker.js +310 -1184
  78. package/dist/skill-invoker.js.map +1 -1
  79. package/dist/skill-loader.d.ts +15 -1
  80. package/dist/skill-loader.d.ts.map +1 -1
  81. package/dist/skill-loader.js +49 -32
  82. package/dist/skill-loader.js.map +1 -1
  83. package/dist/slash-commands.d.ts +4 -2
  84. package/dist/slash-commands.d.ts.map +1 -1
  85. package/dist/slash-commands.js +149 -15
  86. package/dist/slash-commands.js.map +1 -1
  87. package/dist/smart-approval.d.ts +2 -1
  88. package/dist/smart-approval.d.ts.map +1 -1
  89. package/dist/smart-approval.js +29 -3
  90. package/dist/smart-approval.js.map +1 -1
  91. package/dist/system-prompt-generator.d.ts +4 -5
  92. package/dist/system-prompt-generator.d.ts.map +1 -1
  93. package/dist/system-prompt-generator.js +131 -81
  94. package/dist/system-prompt-generator.js.map +1 -1
  95. package/dist/tools.d.ts +17 -6
  96. package/dist/tools.d.ts.map +1 -1
  97. package/dist/tools.js +264 -211
  98. package/dist/tools.js.map +1 -1
  99. package/dist/types.d.ts +0 -1
  100. package/dist/types.d.ts.map +1 -1
  101. package/dist/types.js +0 -1
  102. package/dist/types.js.map +1 -1
  103. package/docs/architecture/mcp-integration-guide.md +194 -131
  104. package/docs/architecture/overview.md +169 -93
  105. package/docs/architecture/tool-system-design.md +56 -11
  106. package/docs/cli/commands.md +238 -189
  107. package/docs/smart-mode.md +281 -257
  108. package/docs/third-party-models.md +247 -256
  109. package/package.json +6 -2
  110. package/src/ai-client.ts +107 -105
  111. package/src/auth.ts +82 -116
  112. package/src/cancellation.ts +1 -1
  113. package/src/cli.ts +178 -13
  114. package/src/config.ts +57 -8
  115. package/src/context-compressor.ts +8 -8
  116. package/src/gui-subagent/action-parser/actionParser.ts +6 -3
  117. package/src/gui-subagent/action-parser/constants.ts +5 -3
  118. package/src/gui-subagent/action-parser/index.ts +5 -3
  119. package/src/gui-subagent/action-parser/types.ts +3 -3
  120. package/src/gui-subagent/agent/gui-agent.ts +210 -103
  121. package/src/gui-subagent/agent/index.ts +1 -1
  122. package/src/gui-subagent/index.ts +26 -2
  123. package/src/index.ts +18 -18
  124. package/src/logger.ts +1 -1
  125. package/src/mcp.ts +149 -30
  126. package/src/remote-ai-client.ts +671 -0
  127. package/src/session-manager.ts +3 -3
  128. package/src/session.ts +742 -178
  129. package/src/skill-invoker.ts +340 -1293
  130. package/src/skill-loader.ts +55 -34
  131. package/src/slash-commands.ts +165 -15
  132. package/src/smart-approval.ts +34 -3
  133. package/src/system-prompt-generator.ts +145 -88
  134. package/src/tools.ts +309 -224
  135. package/src/types.ts +0 -1
  136. package/scripts/init-skills-path.js +0 -58
package/dist/ai-client.js CHANGED
@@ -1,30 +1,31 @@
1
1
  import axios from 'axios';
2
- // Markdown渲染辅助函数
2
+ import https from 'https';
3
+ // Markdown rendering helper function
3
4
  function renderMarkdown(text) {
4
- // 代码块渲染
5
+ // Code block rendering
5
6
  text = text.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => {
6
7
  return `\n┌─[${lang || 'code'}]\n${code.trim().split('\n').map((l) => '│ ' + l).join('\n')}\n└─\n`;
7
8
  });
8
- // 行内代码渲染
9
+ // Inline code rendering
9
10
  text = text.replace(/`([^`]+)`/g, '`$1`');
10
- // 粗体渲染
11
+ // Bold rendering
11
12
  text = text.replace(/\*\*([^*]+)\*\*/g, '●$1○');
12
- // 斜体渲染
13
+ // Italic rendering
13
14
  text = text.replace(/\*([^*]+)\*/g, '/$1/');
14
- // 列表渲染
15
+ // List rendering
15
16
  text = text.replace(/^- (.*$)/gm, '○ $1');
16
17
  text = text.replace(/^\d+\. (.*$)/gm, '• $1');
17
- // 标题渲染
18
+ // Heading rendering
18
19
  text = text.replace(/^### (.*$)/gm, '\n━━━ $1 ━━━\n');
19
20
  text = text.replace(/^## (.*$)/gm, '\n━━━━━ $1 ━━━━━\n');
20
21
  text = text.replace(/^# (.*$)/gm, '\n━━━━━━━ $1 ━━━━━━━\n');
21
- // 引用渲染
22
+ // Quote rendering
22
23
  text = text.replace(/^> (.*$)/gm, '│ │ $1');
23
- // 链接渲染
24
+ // Link rendering
24
25
  text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '[$1]($2)');
25
26
  return text;
26
27
  }
27
- // 格式化消息内容
28
+ // Format message content
28
29
  function formatMessageContent(content) {
29
30
  if (typeof content === 'string') {
30
31
  return renderMarkdown(content);
@@ -52,7 +53,7 @@ function formatMessageContent(content) {
52
53
  }
53
54
  return parts.join('\n');
54
55
  }
55
- // 分类展示消息
56
+ // Display messages by category
56
57
  function displayMessages(messages, systemPrompt) {
57
58
  const roleColors = {
58
59
  system: '🟫 SYSTEM',
@@ -60,7 +61,7 @@ function displayMessages(messages, systemPrompt) {
60
61
  assistant: '🤖 ASSISTANT',
61
62
  tool: '🔧 TOOL'
62
63
  };
63
- // 先显示system消息(如果有单独的systemPrompt参数)
64
+ // Display system message first (if there's a separate systemPrompt parameter)
64
65
  if (systemPrompt) {
65
66
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
66
67
  console.log('│ 🟫 SYSTEM │');
@@ -68,7 +69,7 @@ function displayMessages(messages, systemPrompt) {
68
69
  console.log(renderMarkdown(systemPrompt).split('\n').map((l) => '│ ' + l).join('\n'));
69
70
  console.log('└─────────────────────────────────────────────────────────────┘');
70
71
  }
71
- // 遍历所有消息
72
+ // Iterate through all messages
72
73
  for (let i = 0; i < messages.length; i++) {
73
74
  const msg = messages[i];
74
75
  const role = msg.role;
@@ -76,7 +77,7 @@ function displayMessages(messages, systemPrompt) {
76
77
  console.log(`\n┌─────────────────────────────────────────────────────────────┐`);
77
78
  console.log(`│ ${roleLabel} (${i + 1}/${messages.length}) │`);
78
79
  console.log('├─────────────────────────────────────────────────────────────┤');
79
- // 显示reasoning_content(如果有)
80
+ // Display reasoning_content (if present)
80
81
  if (msg.reasoning_content) {
81
82
  console.log('│ 🧠 REASONING:');
82
83
  console.log('│ ───────────────────────────────────────────────────────────');
@@ -88,7 +89,7 @@ function displayMessages(messages, systemPrompt) {
88
89
  console.log('│ ... (truncated)');
89
90
  console.log('│ ───────────────────────────────────────────────────────────');
90
91
  }
91
- // 显示主要内容
92
+ // Display main content
92
93
  const content = formatMessageContent(msg.content);
93
94
  const lines = content.split('\n');
94
95
  for (const line of lines.slice(0, 50)) {
@@ -100,7 +101,7 @@ function displayMessages(messages, systemPrompt) {
100
101
  console.log('└─────────────────────────────────────────────────────────────┘');
101
102
  }
102
103
  }
103
- // 格式化响应内容
104
+ // Format response content
104
105
  function formatResponseContent(content) {
105
106
  if (typeof content === 'string') {
106
107
  return renderMarkdown(content);
@@ -113,7 +114,7 @@ function formatResponseContent(content) {
113
114
  }
114
115
  else if (block.type === 'tool_use') {
115
116
  hasToolUse = true;
116
- // 工具调用通过 tool_calls 字段处理,不在此显示
117
+ // Tool calls are handled via tool_calls field, not shown here
117
118
  }
118
119
  else if (block.type === 'tool_result') {
119
120
  const result = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
@@ -131,28 +132,28 @@ function formatResponseContent(content) {
131
132
  }
132
133
  return parts.join('\n');
133
134
  }
134
- // 检测是否为 Anthropic 兼容 API(使用 x-api-key 认证头)
135
+ // Detect if it's Anthropic compatible API(Use x-api-key authentication header)
135
136
  function isAnthropicCompatible(baseUrl) {
136
137
  return baseUrl.includes('anthropic') ||
137
138
  baseUrl.includes('minimaxi.com') ||
138
139
  baseUrl.includes('minimax.chat');
139
140
  }
140
- // MiniMax API 路径检测
141
+ // MiniMax API path detection
141
142
  function detectMiniMaxAPI(baseUrl) {
142
143
  return baseUrl.includes('minimax.chat') ||
143
144
  baseUrl.includes('minimaxi.com');
144
145
  }
145
- // 获取 MiniMax 的正确端点路径
146
+ // Get correct endpoint path for MiniMax
146
147
  function getMiniMaxEndpoint(baseUrl) {
147
- // MiniMax Anthropic 格式: https://api.minimax.chat/anthropic + /v1/messages
148
+ // MiniMax Anthropic format: https://api.minimax.chat/anthropic + /v1/messages
148
149
  if (baseUrl.includes('/anthropic')) {
149
150
  return { endpoint: '/v1/messages', format: 'anthropic' };
150
151
  }
151
- // MiniMax OpenAI 格式: https://api.minimaxi.com/v1 + /chat/completions
152
+ // MiniMax OpenAI format: https://api.minimaxi.com/v1 + /chat/completions
152
153
  if (baseUrl.includes('/v1') && !baseUrl.includes('/anthropic')) {
153
154
  return { endpoint: '/chat/completions', format: 'openai' };
154
155
  }
155
- // 默认使用 Anthropic 格式
156
+ // Default to Anthropic format
156
157
  return { endpoint: '/v1/messages', format: 'anthropic' };
157
158
  }
158
159
  export class AIClient {
@@ -166,27 +167,28 @@ export class AIClient {
166
167
  'Content-Type': 'application/json'
167
168
  };
168
169
  if (isMiniMax) {
169
- // MiniMax: 使用 x-api-key 认证头
170
+ // MiniMax: Use x-api-key authentication header
170
171
  headers['x-api-key'] = authConfig.apiKey || '';
171
172
  headers['anthropic-version'] = '2023-06-01';
172
173
  }
173
174
  else if (isAnthropicOfficial) {
174
- // Anthropic 官方: 使用 x-api-key 认证头
175
+ // Anthropic official: Use x-api-key authentication header
175
176
  headers['x-api-key'] = authConfig.apiKey || '';
176
177
  headers['anthropic-version'] = '2023-06-01';
177
178
  headers['anthropic-dangerous-direct-browser-access'] = 'true';
178
179
  }
179
180
  else {
180
- // 其他 OpenAI 兼容: 使用 Bearer token
181
+ // Other OpenAI compatible: 使用 Bearer token
181
182
  headers['Authorization'] = `Bearer ${authConfig.apiKey}`;
182
183
  }
183
184
  this.client = axios.create({
184
185
  baseURL: authConfig.baseUrl,
185
186
  headers,
186
- timeout: 240000
187
+ timeout: 240000,
188
+ httpsAgent: new https.Agent({ rejectUnauthorized: false })
187
189
  });
188
190
  }
189
- // OpenAI 格式消息转换为 Anthropic 格式
191
+ // Convert OpenAI format messages to Anthropic format
190
192
  convertToAnthropicFormat(messages, systemPrompt) {
191
193
  const systemMessages = messages.filter(m => m.role === 'system');
192
194
  const otherMessages = messages.filter(m => m.role !== 'system');
@@ -225,7 +227,7 @@ export class AIClient {
225
227
  }
226
228
  }
227
229
  }
228
- // 处理 tool_calls (OpenAI 格式)
230
+ // Handle tool_calls (OpenAI 格式)
229
231
  if (msg.tool_calls) {
230
232
  for (const tc of msg.tool_calls) {
231
233
  blocks.push({
@@ -255,7 +257,7 @@ export class AIClient {
255
257
  if (isAnthropic) {
256
258
  return this.anthropicNativeChatCompletion(messages, options);
257
259
  }
258
- // OpenAI 格式请求
260
+ // OpenAI format request
259
261
  const requestBody = {
260
262
  model,
261
263
  messages,
@@ -272,7 +274,7 @@ export class AIClient {
272
274
  if (options.thinkingTokens && options.thinkingTokens > 0) {
273
275
  requestBody.max_completion_tokens = options.thinkingTokens;
274
276
  }
275
- // 调试输出(受showAIDebugInfo配置控制)
277
+ // Debug output(受showAIDebugInfo配置控制)
276
278
  const showDebug = this.authConfig.showAIDebugInfo ?? false;
277
279
  if (showDebug) {
278
280
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -280,17 +282,17 @@ export class AIClient {
280
282
  console.log('╚══════════════════════════════════════════════════════════╝');
281
283
  console.log(`📦 Model: ${model}`);
282
284
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
283
- console.log(`💬 Total Messages: ${messages.length} 条`);
285
+ console.log(`💬 Total Messages: ${messages.length} items`);
284
286
  if (options.temperature !== undefined)
285
287
  console.log(`🌡️ Temperature: ${options.temperature}`);
286
288
  if (options.maxTokens)
287
289
  console.log(`📏 Max Tokens: ${options.maxTokens}`);
288
290
  if (options.tools?.length)
289
- console.log(`🔧 Tools: ${options.tools.length} 个`);
291
+ console.log(`🔧 Tools: ${options.tools.length} items`);
290
292
  if (options.thinkingTokens)
291
293
  console.log(`🧠 Thinking Tokens: ${options.thinkingTokens}`);
292
294
  console.log('─'.repeat(60));
293
- // 分离system消息
295
+ // Separate system messages
294
296
  const systemMsgs = messages.filter(m => m.role === 'system');
295
297
  const otherMsgs = messages.filter(m => m.role !== 'system');
296
298
  if (systemMsgs.length > 0) {
@@ -324,7 +326,7 @@ export class AIClient {
324
326
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
325
327
  console.log('│ 🤖 ASSISTANT │');
326
328
  console.log('├─────────────────────────────────────────────────────────────┤');
327
- // 显示reasoning_content(如果有)
329
+ // Display reasoning_content(如果有)
328
330
  if (choice.message.reasoning_content) {
329
331
  console.log('│ 🧠 REASONING:');
330
332
  console.log('│ ───────────────────────────────────────────────────────────');
@@ -336,7 +338,7 @@ export class AIClient {
336
338
  console.log('│ ... (truncated)');
337
339
  console.log('│ ───────────────────────────────────────────────────────────');
338
340
  }
339
- // 显示主要内容
341
+ // Display main content
340
342
  const content = formatResponseContent(choice.message.content);
341
343
  const lines = content.split('\n');
342
344
  console.log('│ 💬 CONTENT:');
@@ -367,7 +369,7 @@ export class AIClient {
367
369
  }
368
370
  }
369
371
  }
370
- // Anthropic 官方原生 API(使用 /v1/messages 端点)
372
+ // Anthropic official原生 API(使用 /v1/messages 端点)
371
373
  async anthropicNativeChatCompletion(messages, options = {}) {
372
374
  const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
373
375
  const requestBody = {
@@ -380,14 +382,14 @@ export class AIClient {
380
382
  if (system) {
381
383
  requestBody.system = system;
382
384
  }
383
- // Anthropic 原生工具格式
385
+ // Anthropic native tool format
384
386
  if (options.tools && options.tools.length > 0) {
385
387
  requestBody.tools = options.tools.map(tool => ({
386
388
  name: tool.function.name,
387
389
  description: tool.function.description,
388
390
  input_schema: tool.function.parameters || { type: 'object', properties: {} }
389
391
  }));
390
- // 转换 tool_choice 从 OpenAI 格式到 Anthropic 格式
392
+ // Convert tool_choice 从 OpenAI 格式到 Anthropic 格式
391
393
  const toolChoice = options.toolChoice;
392
394
  if (toolChoice === 'none') {
393
395
  requestBody.tool_choice = { type: 'auto' };
@@ -404,11 +406,11 @@ export class AIClient {
404
406
  requestBody.tool_choice = { type: 'auto' };
405
407
  }
406
408
  }
407
- // Anthropic thinking 模式
409
+ // Anthropic thinking mode
408
410
  if (options.thinkingTokens && options.thinkingTokens > 0) {
409
411
  requestBody.thinking = { type: 'enabled', budget_tokens: options.thinkingTokens };
410
412
  }
411
- // 调试输出(受showAIDebugInfo配置控制)
413
+ // Debug output(受showAIDebugInfo配置控制)
412
414
  const showDebug = this.authConfig.showAIDebugInfo ?? false;
413
415
  if (showDebug) {
414
416
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -416,17 +418,17 @@ export class AIClient {
416
418
  console.log('╚══════════════════════════════════════════════════════════╝');
417
419
  console.log(`📦 Model: ${requestBody.model}`);
418
420
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
419
- console.log(`💬 Total Messages: ${anthropicMessages.length} 条`);
421
+ console.log(`💬 Total Messages: ${anthropicMessages.length} items`);
420
422
  if (requestBody.temperature)
421
423
  console.log(`🌡️ Temperature: ${requestBody.temperature}`);
422
424
  if (requestBody.max_tokens)
423
425
  console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
424
426
  if (requestBody.tools)
425
- console.log(`🔧 Tools: ${requestBody.tools.length} 个`);
427
+ console.log(`🔧 Tools: ${requestBody.tools.length} items`);
426
428
  if (requestBody.thinking)
427
429
  console.log(`🧠 Thinking Budget: ${requestBody.thinking.budget_tokens}`);
428
430
  console.log('─'.repeat(60));
429
- // 显示system消息
431
+ // Display system messages
430
432
  if (system) {
431
433
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
432
434
  console.log('│ 🟫 SYSTEM │');
@@ -434,12 +436,12 @@ export class AIClient {
434
436
  console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
435
437
  console.log('└─────────────────────────────────────────────────────────────┘');
436
438
  }
437
- // 显示用户和助手消息
439
+ // Display user and assistant messages
438
440
  displayMessages(anthropicMessages);
439
441
  console.log('\n📤 Sending to Anthropic API (v1/messages)...\n');
440
442
  }
441
443
  try {
442
- // 使用 Anthropic 原生端点 /v1/messages
444
+ // Use Anthropic native endpoint /v1/messages
443
445
  const response = await this.client.post('/v1/messages', requestBody);
444
446
  if (showDebug) {
445
447
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -458,7 +460,7 @@ export class AIClient {
458
460
  const content = response.data.content || [];
459
461
  const reasoning = content.filter((c) => c.type === 'thinking').map((c) => c.thinking).join('');
460
462
  const textContent = content.filter((c) => c.type === 'text').map((c) => c.text).join('');
461
- // 显示thinking
463
+ // Display thinking
462
464
  if (reasoning) {
463
465
  console.log('│ 🧠 REASONING:');
464
466
  console.log('│ ───────────────────────────────────────────────────────────');
@@ -470,7 +472,7 @@ export class AIClient {
470
472
  console.log('│ ... (truncated)');
471
473
  console.log('│ ───────────────────────────────────────────────────────────');
472
474
  }
473
- // 显示内容
475
+ // Display content
474
476
  console.log('│ 💬 CONTENT:');
475
477
  console.log('│ ───────────────────────────────────────────────────────────');
476
478
  const lines = renderMarkdown(textContent).split('\n');
@@ -499,7 +501,7 @@ export class AIClient {
499
501
  }
500
502
  }
501
503
  }
502
- // MiniMax API(根据 baseUrl 自动选择 Anthropic 或 OpenAI 格式)
504
+ // MiniMax API(Automatically select based on baseUrl Anthropic 或 OpenAI 格式)
503
505
  async minimaxChatCompletion(messages, options = {}) {
504
506
  const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
505
507
  const { endpoint, format } = getMiniMaxEndpoint(this.authConfig.baseUrl || '');
@@ -539,13 +541,13 @@ export class AIClient {
539
541
  }
540
542
  }
541
543
  else {
542
- // OpenAI 格式的工具
544
+ // OpenAI format tools
543
545
  if (options.tools && options.tools.length > 0) {
544
546
  requestBody.tools = options.tools;
545
547
  requestBody.tool_choice = options.toolChoice || 'auto';
546
548
  }
547
549
  }
548
- // 调试输出(受showAIDebugInfo配置控制)
550
+ // Debug output(受showAIDebugInfo配置控制)
549
551
  const showDebug = this.authConfig.showAIDebugInfo ?? false;
550
552
  if (showDebug) {
551
553
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -554,15 +556,15 @@ export class AIClient {
554
556
  console.log(`📦 Model: ${requestBody.model}`);
555
557
  console.log(`🔗 Format: ${format.toUpperCase()} | Endpoint: ${endpoint}`);
556
558
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
557
- console.log(`💬 Total Messages: ${requestBody.messages.length} 条`);
559
+ console.log(`💬 Total Messages: ${requestBody.messages.length} items`);
558
560
  if (requestBody.temperature)
559
561
  console.log(`🌡️ Temperature: ${requestBody.temperature}`);
560
562
  if (requestBody.max_tokens)
561
563
  console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
562
564
  if (requestBody.tools)
563
- console.log(`🔧 Tools: ${requestBody.tools.length} 个`);
565
+ console.log(`🔧 Tools: ${requestBody.tools.length} items`);
564
566
  console.log('─'.repeat(60));
565
- // 显示system消息
567
+ // Display system messages
566
568
  if (system && format === 'anthropic') {
567
569
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
568
570
  console.log('│ 🟫 SYSTEM │');
@@ -570,12 +572,12 @@ export class AIClient {
570
572
  console.log(renderMarkdown(system).split('\n').map(l => '│ ' + l).join('\n'));
571
573
  console.log('└─────────────────────────────────────────────────────────────┘');
572
574
  }
573
- // 显示其他消息
575
+ // Display other messages
574
576
  displayMessages(requestBody.messages);
575
577
  console.log('\n📤 Sending to MiniMax API...\n');
576
578
  }
577
579
  try {
578
- // MiniMax 使用正确的端点
580
+ // MiniMax uses correct endpoint
579
581
  const response = await this.client.post(endpoint, requestBody);
580
582
  if (showDebug) {
581
583
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -626,7 +628,7 @@ export class AIClient {
626
628
  }
627
629
  }
628
630
  }
629
- // Anthropic 原生响应转换为统一格式
631
+ // Convert Anthropic native response to unified format
630
632
  convertFromAnthropicNativeResponse(anthropicResponse) {
631
633
  const content = anthropicResponse.content || [];
632
634
  let textContent = '';
@@ -673,7 +675,7 @@ export class AIClient {
673
675
  } : undefined
674
676
  };
675
677
  }
676
- // MiniMax 响应转换为统一格式
678
+ // Convert MiniMax response to unified format
677
679
  convertFromMiniMaxResponse(minimaxResponse) {
678
680
  const message = minimaxResponse.choices?.[0]?.message;
679
681
  const content = message?.content;
@@ -733,7 +735,7 @@ export class AIClient {
733
735
  yield* this.anthropicNativeStreamChatCompletion(messages, options);
734
736
  return;
735
737
  }
736
- // OpenAI 流式响应
738
+ // OpenAI streaming response
737
739
  const model = options.model || this.authConfig.modelName || 'gpt-4';
738
740
  const requestBody = {
739
741
  model,
@@ -751,7 +753,7 @@ export class AIClient {
751
753
  if (options.thinkingTokens && options.thinkingTokens > 0) {
752
754
  requestBody.max_completion_tokens = options.thinkingTokens;
753
755
  }
754
- // 调试输出(受showAIDebugInfo配置控制)
756
+ // Debug output(受showAIDebugInfo配置控制)
755
757
  const showDebug = this.authConfig.showAIDebugInfo ?? false;
756
758
  if (showDebug) {
757
759
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -759,15 +761,15 @@ export class AIClient {
759
761
  console.log('╚══════════════════════════════════════════════════════════╝');
760
762
  console.log(`📦 Model: ${model}`);
761
763
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
762
- console.log(`💬 Total Messages: ${messages.length} 条`);
764
+ console.log(`💬 Total Messages: ${messages.length} items`);
763
765
  if (options.temperature)
764
766
  console.log(`🌡️ Temperature: ${options.temperature}`);
765
767
  if (options.maxTokens)
766
768
  console.log(`📏 Max Tokens: ${options.maxTokens}`);
767
769
  if (options.tools?.length)
768
- console.log(`🔧 Tools: ${options.tools.length} 个`);
770
+ console.log(`🔧 Tools: ${options.tools.length} items`);
769
771
  console.log('─'.repeat(60));
770
- // 分离并显示消息
772
+ // Separate and display messages
771
773
  const systemMsgs = messages.filter(m => m.role === 'system');
772
774
  const otherMsgs = messages.filter(m => m.role !== 'system');
773
775
  if (systemMsgs.length > 0) {
@@ -882,7 +884,7 @@ export class AIClient {
882
884
  }
883
885
  }
884
886
  }
885
- // Anthropic 原生流式响应(/v1/messages 端点)
887
+ // Anthropic native streaming response(/v1/messages 端点)
886
888
  async *anthropicNativeStreamChatCompletion(messages, options = {}) {
887
889
  const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
888
890
  const requestBody = {
@@ -895,7 +897,7 @@ export class AIClient {
895
897
  if (system) {
896
898
  requestBody.system = system;
897
899
  }
898
- // Anthropic 原生工具格式
900
+ // Anthropic native tool format
899
901
  if (options.tools && options.tools.length > 0) {
900
902
  requestBody.tools = options.tools.map(tool => ({
901
903
  name: tool.function.name,
@@ -921,7 +923,7 @@ export class AIClient {
921
923
  if (options.thinkingTokens && options.thinkingTokens > 0) {
922
924
  requestBody.thinking = { type: 'enabled', budget_tokens: options.thinkingTokens };
923
925
  }
924
- // 调试输出(受showAIDebugInfo配置控制)
926
+ // Debug output(受showAIDebugInfo配置控制)
925
927
  const showDebug = this.authConfig.showAIDebugInfo ?? false;
926
928
  if (showDebug) {
927
929
  console.log('\n╔══════════════════════════════════════════════════════════╗');
@@ -929,7 +931,7 @@ export class AIClient {
929
931
  console.log('╚══════════════════════════════════════════════════════════╝');
930
932
  console.log(`📦 Model: ${requestBody.model}`);
931
933
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
932
- console.log(`💬 Total Messages: ${anthropicMessages.length} 条`);
934
+ console.log(`💬 Total Messages: ${anthropicMessages.length} items`);
933
935
  if (requestBody.temperature)
934
936
  console.log(`🌡️ Temperature: ${requestBody.temperature}`);
935
937
  if (requestBody.max_tokens)
@@ -937,7 +939,7 @@ export class AIClient {
937
939
  if (requestBody.thinking)
938
940
  console.log(`🧠 Thinking Budget: ${requestBody.thinking.budget_tokens}`);
939
941
  console.log('─'.repeat(60));
940
- // 显示system消息
942
+ // Display system messages
941
943
  if (system) {
942
944
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
943
945
  console.log('│ 🟫 SYSTEM │');
@@ -949,7 +951,7 @@ export class AIClient {
949
951
  console.log('\n📤 Starting Anthropic stream...\n');
950
952
  }
951
953
  try {
952
- // Anthropic 原生流式端点 /v1/messages
954
+ // Anthropic native streaming endpoint /v1/messages
953
955
  const response = await this.client.post('/v1/messages', requestBody, {
954
956
  responseType: 'stream'
955
957
  });
@@ -964,12 +966,12 @@ export class AIClient {
964
966
  const trimmedLine = line.trim();
965
967
  if (!trimmedLine)
966
968
  continue;
967
- // Anthropic 流式格式: data: {"type":"content_block_delta",...}
969
+ // Anthropic streaming format: data: {"type":"content_block_delta",...}
968
970
  if (trimmedLine.startsWith('data: ')) {
969
971
  const data = trimmedLine.slice(6);
970
972
  try {
971
973
  const parsed = JSON.parse(data);
972
- // Anthropic 事件类型
974
+ // Anthropic event types
973
975
  if (parsed.type === 'content_block_delta') {
974
976
  if (parsed.delta?.type === 'text_delta' && parsed.delta.text) {
975
977
  outputBuffer += parsed.delta.text;
@@ -982,7 +984,7 @@ export class AIClient {
982
984
  }
983
985
  else if (parsed.type === 'message_delta') {
984
986
  if (parsed.delta?.stop_reason) {
985
- // 消息结束
987
+ // Message end
986
988
  if (showDebug) {
987
989
  console.log('\n╔══════════════════════════════════════════════════════════╗');
988
990
  console.log('║ STREAM COMPLETED ║');
@@ -1008,7 +1010,7 @@ export class AIClient {
1008
1010
  }
1009
1011
  }
1010
1012
  catch (e) {
1011
- // 忽略解析错误
1013
+ // Ignore parsing errors
1012
1014
  }
1013
1015
  }
1014
1016
  }
@@ -1029,7 +1031,7 @@ export class AIClient {
1029
1031
  }
1030
1032
  }
1031
1033
  }
1032
- // MiniMax 流式响应(根据 baseUrl 自动选择格式)
1034
+ // MiniMax streaming response(Automatically select based on baseUrl格式)
1033
1035
  async *minimaxStreamChatCompletion(messages, options = {}) {
1034
1036
  const { system, messages: anthropicMessages } = this.convertToAnthropicFormat(messages);
1035
1037
  const { endpoint, format } = getMiniMaxEndpoint(this.authConfig.baseUrl || '');
@@ -1069,7 +1071,7 @@ export class AIClient {
1069
1071
  }
1070
1072
  }
1071
1073
  else {
1072
- // OpenAI 格式的工具
1074
+ // OpenAI format tools
1073
1075
  if (options.tools && options.tools.length > 0) {
1074
1076
  requestBody.tools = options.tools;
1075
1077
  requestBody.tool_choice = options.toolChoice || 'auto';
@@ -1081,13 +1083,13 @@ export class AIClient {
1081
1083
  console.log(`📦 Model: ${requestBody.model}`);
1082
1084
  console.log(`🔗 Format: ${format.toUpperCase()} | Endpoint: ${endpoint}`);
1083
1085
  console.log(`🌐 Base URL: ${this.authConfig.baseUrl}`);
1084
- console.log(`💬 Total Messages: ${requestBody.messages.length} 条`);
1086
+ console.log(`💬 Total Messages: ${requestBody.messages.length} items`);
1085
1087
  if (requestBody.temperature)
1086
1088
  console.log(`🌡️ Temperature: ${requestBody.temperature}`);
1087
1089
  if (requestBody.max_tokens)
1088
1090
  console.log(`📏 Max Tokens: ${requestBody.max_tokens}`);
1089
1091
  console.log('─'.repeat(60));
1090
- // 显示system消息
1092
+ // Display system messages
1091
1093
  if (system && format === 'anthropic') {
1092
1094
  console.log('\n┌─────────────────────────────────────────────────────────────┐');
1093
1095
  console.log('│ 🟫 SYSTEM │');
@@ -1113,9 +1115,9 @@ export class AIClient {
1113
1115
  const trimmedLine = line.trim();
1114
1116
  if (!trimmedLine)
1115
1117
  continue;
1116
- // 根据格式解析不同的流式响应
1118
+ // Parse different streaming responses based on format
1117
1119
  if (format === 'anthropic') {
1118
- // Anthropic SSE 格式: data: {"type":"content_block_delta",...}
1120
+ // Anthropic SSE format: data: {"type":"content_block_delta",...}
1119
1121
  if (trimmedLine.startsWith('data: ')) {
1120
1122
  const data = trimmedLine.slice(6);
1121
1123
  try {
@@ -1153,12 +1155,12 @@ export class AIClient {
1153
1155
  }
1154
1156
  }
1155
1157
  catch (e) {
1156
- // 忽略解析错误
1158
+ // Ignore parsing errors
1157
1159
  }
1158
1160
  }
1159
1161
  }
1160
1162
  else {
1161
- // OpenAI SSE 格式: data: {...}
1163
+ // OpenAI SSE format: data: {...}
1162
1164
  if (trimmedLine.startsWith('data: ')) {
1163
1165
  const data = trimmedLine.slice(6);
1164
1166
  if (data === '[DONE]')
@@ -1176,7 +1178,7 @@ export class AIClient {
1176
1178
  }
1177
1179
  }
1178
1180
  catch (e) {
1179
- // 忽略解析错误
1181
+ // Ignore parsing errors
1180
1182
  }
1181
1183
  }
1182
1184
  }