@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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/README.md +280 -280
- package/README_CN.md +3 -3
- package/dist/ai-client.d.ts.map +1 -1
- package/dist/ai-client.js +84 -82
- package/dist/ai-client.js.map +1 -1
- package/dist/auth.d.ts +0 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +75 -105
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +166 -13
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +48 -7
- package/dist/config.js.map +1 -1
- package/dist/context-compressor.d.ts +5 -5
- package/dist/context-compressor.js +8 -8
- package/dist/context-compressor.js.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.d.ts +7 -0
- package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/actionParser.js +6 -3
- package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
- package/dist/gui-subagent/action-parser/constants.d.ts +6 -0
- package/dist/gui-subagent/action-parser/constants.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/constants.js +5 -3
- package/dist/gui-subagent/action-parser/constants.js.map +1 -1
- package/dist/gui-subagent/action-parser/index.d.ts +6 -0
- package/dist/gui-subagent/action-parser/index.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/index.js +5 -3
- package/dist/gui-subagent/action-parser/index.js.map +1 -1
- package/dist/gui-subagent/action-parser/types.d.ts +4 -0
- package/dist/gui-subagent/action-parser/types.d.ts.map +1 -1
- package/dist/gui-subagent/action-parser/types.js +3 -3
- package/dist/gui-subagent/agent/gui-agent.d.ts +39 -0
- package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
- package/dist/gui-subagent/agent/gui-agent.js +164 -89
- package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
- package/dist/gui-subagent/agent/index.d.ts +1 -1
- package/dist/gui-subagent/agent/index.d.ts.map +1 -1
- package/dist/gui-subagent/agent/index.js.map +1 -1
- package/dist/gui-subagent/index.d.ts +27 -1
- package/dist/gui-subagent/index.d.ts.map +1 -1
- package/dist/gui-subagent/index.js +6 -0
- package/dist/gui-subagent/index.js.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/mcp.d.ts +1 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +140 -29
- package/dist/mcp.js.map +1 -1
- package/dist/remote-ai-client.d.ts +111 -0
- package/dist/remote-ai-client.d.ts.map +1 -0
- package/dist/remote-ai-client.js +558 -0
- package/dist/remote-ai-client.js.map +1 -0
- package/dist/sdk-output-adapter.d.ts +232 -0
- package/dist/sdk-output-adapter.d.ts.map +1 -0
- package/dist/sdk-output-adapter.js +636 -0
- package/dist/sdk-output-adapter.js.map +1 -0
- package/dist/sdk-session-v2.d.ts +13 -0
- package/dist/sdk-session-v2.d.ts.map +1 -0
- package/dist/sdk-session-v2.js +46 -0
- package/dist/sdk-session-v2.js.map +1 -0
- package/dist/sdk-session.d.ts +13 -0
- package/dist/sdk-session.d.ts.map +1 -0
- package/dist/sdk-session.js +48 -0
- package/dist/sdk-session.js.map +1 -0
- package/dist/session-manager.js +3 -3
- package/dist/session-manager.js.map +1 -1
- package/dist/session.d.ts +46 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +564 -117
- package/dist/session.js.map +1 -1
- package/dist/skill-invoker.d.ts +40 -4
- package/dist/skill-invoker.d.ts.map +1 -1
- package/dist/skill-invoker.js +310 -1184
- package/dist/skill-invoker.js.map +1 -1
- package/dist/skill-loader.d.ts +15 -1
- package/dist/skill-loader.d.ts.map +1 -1
- package/dist/skill-loader.js +49 -32
- package/dist/skill-loader.js.map +1 -1
- package/dist/slash-commands.d.ts +4 -2
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +149 -15
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts +2 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +29 -3
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.d.ts +4 -5
- package/dist/system-prompt-generator.d.ts.map +1 -1
- package/dist/system-prompt-generator.js +131 -81
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/tools.d.ts +17 -6
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +264 -211
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/docs/architecture/mcp-integration-guide.md +194 -131
- package/docs/architecture/overview.md +169 -93
- package/docs/architecture/tool-system-design.md +56 -11
- package/docs/cli/commands.md +238 -189
- package/docs/smart-mode.md +281 -257
- package/docs/third-party-models.md +247 -256
- package/package.json +6 -2
- package/src/ai-client.ts +107 -105
- package/src/auth.ts +82 -116
- package/src/cancellation.ts +1 -1
- package/src/cli.ts +178 -13
- package/src/config.ts +57 -8
- package/src/context-compressor.ts +8 -8
- package/src/gui-subagent/action-parser/actionParser.ts +6 -3
- package/src/gui-subagent/action-parser/constants.ts +5 -3
- package/src/gui-subagent/action-parser/index.ts +5 -3
- package/src/gui-subagent/action-parser/types.ts +3 -3
- package/src/gui-subagent/agent/gui-agent.ts +210 -103
- package/src/gui-subagent/agent/index.ts +1 -1
- package/src/gui-subagent/index.ts +26 -2
- package/src/index.ts +18 -18
- package/src/logger.ts +1 -1
- package/src/mcp.ts +149 -30
- package/src/remote-ai-client.ts +671 -0
- package/src/session-manager.ts +3 -3
- package/src/session.ts +742 -178
- package/src/skill-invoker.ts +340 -1293
- package/src/skill-loader.ts +55 -34
- package/src/slash-commands.ts +165 -15
- package/src/smart-approval.ts +34 -3
- package/src/system-prompt-generator.ts +145 -88
- package/src/tools.ts +309 -224
- package/src/types.ts +0 -1
- 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
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
146
|
+
// Get correct endpoint path for MiniMax
|
|
146
147
|
function getMiniMaxEndpoint(baseUrl) {
|
|
147
|
-
// MiniMax Anthropic
|
|
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
|
|
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
|
-
//
|
|
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:
|
|
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
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
}
|