yuangs 1.3.10 → 1.3.13
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/cli.js +78 -16
- package/index.js +50 -4
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -20,6 +20,9 @@ function printHelp() {
|
|
|
20
20
|
console.log(` ${chalk.green('ai')} "<问题>" 向 AI 提问(不写问题进入交互模式)`);
|
|
21
21
|
console.log(` ${chalk.gray('--model, -m <模型名称>')} 指定 AI 模型 (可选)`);
|
|
22
22
|
console.log(` ${chalk.green('help')} 显示帮助信息\n`);
|
|
23
|
+
console.log(chalk.bold('AI 交互模式命令:'));
|
|
24
|
+
console.log(` ${chalk.gray('/clear')} 清空对话历史`);
|
|
25
|
+
console.log(` ${chalk.gray('/history')} 查看对话历史\n`);
|
|
23
26
|
console.log(chalk.gray('AI 示例: yuangs ai "你好" --model gemini-pro-latest'));
|
|
24
27
|
console.log(chalk.gray('普通示例: yuangs shici\n'));
|
|
25
28
|
}
|
|
@@ -35,14 +38,23 @@ async function askOnce(question, model) {
|
|
|
35
38
|
const spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
36
39
|
const interval = setInterval(() => {
|
|
37
40
|
const elapsedTime = Math.floor((Date.now() - startTime) / 1000); // Calculate elapsed time in seconds
|
|
38
|
-
process.stdout.write(chalk.cyan(`\r${spinner[i++ % spinner.length]} 正在请求 AI,请稍候... (${elapsedTime}s
|
|
41
|
+
process.stdout.write(chalk.cyan(`\r${spinner[i++ % spinner.length]} 正在请求 AI,请稍候... (${elapsedTime}s}`));
|
|
39
42
|
}, 100);
|
|
40
43
|
|
|
41
44
|
try {
|
|
42
|
-
|
|
45
|
+
// For single requests (non-interactive mode), we may want to include history
|
|
46
|
+
// For now, use history for all requests, but we could make this configurable
|
|
47
|
+
const answer = await yuangs.getAIAnswer(question, model, true);
|
|
43
48
|
clearInterval(interval);
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
|
|
50
|
+
// Clear the spinner line if possible
|
|
51
|
+
if (process.stdout.clearLine) {
|
|
52
|
+
process.stdout.clearLine(0);
|
|
53
|
+
process.stdout.cursorTo(0);
|
|
54
|
+
} else {
|
|
55
|
+
process.stdout.write('\r'); // Fallback to just carriage return
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
const totalElapsedTime = (Date.now() - startTime) / 1000; // Calculate total elapsed time
|
|
47
59
|
if (answer && answer.explanation) {
|
|
48
60
|
console.log(chalk.bold.green('🤖 AI 回答:\n'));
|
|
@@ -53,8 +65,15 @@ async function askOnce(question, model) {
|
|
|
53
65
|
console.log(chalk.gray(`\n请求耗时: ${totalElapsedTime.toFixed(2)}s\n`)); // Display total elapsed time
|
|
54
66
|
} catch (error) {
|
|
55
67
|
clearInterval(interval);
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
|
|
69
|
+
// Clear the spinner line if possible
|
|
70
|
+
if (process.stdout.clearLine) {
|
|
71
|
+
process.stdout.clearLine(0);
|
|
72
|
+
process.stdout.cursorTo(0);
|
|
73
|
+
} else {
|
|
74
|
+
process.stdout.write('\r'); // Fallback to just carriage return
|
|
75
|
+
}
|
|
76
|
+
|
|
58
77
|
const totalElapsedTime = (Date.now() - startTime) / 1000; // Calculate total elapsed time on error
|
|
59
78
|
console.error(chalk.red('处理 AI 请求时出错:'), error.message || error);
|
|
60
79
|
console.log(chalk.gray(`\n请求耗时: ${totalElapsedTime.toFixed(2)}s\n`)); // Display total elapsed time on error
|
|
@@ -64,18 +83,36 @@ async function askOnce(question, model) {
|
|
|
64
83
|
async function handleAICommand() {
|
|
65
84
|
const commandArgs = args.slice(1);
|
|
66
85
|
|
|
67
|
-
// 支持 --model 和 -m 两种写法
|
|
68
|
-
const longIndex = commandArgs.indexOf('--model');
|
|
69
|
-
const shortIndex = commandArgs.indexOf('-m');
|
|
70
|
-
const modelIndex = longIndex !== -1 ? longIndex : shortIndex;
|
|
71
|
-
|
|
72
86
|
let model = null; // Default model will be handled in index.js
|
|
73
87
|
let questionParts = commandArgs;
|
|
74
88
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
89
|
+
// Check for shorthand model flags first
|
|
90
|
+
const proIndex = commandArgs.indexOf('-p');
|
|
91
|
+
const flashIndex = commandArgs.indexOf('-f');
|
|
92
|
+
const liteIndex = commandArgs.indexOf('-l');
|
|
93
|
+
|
|
94
|
+
if (proIndex !== -1) {
|
|
95
|
+
model = 'gemini-pro';
|
|
96
|
+
questionParts = commandArgs.filter((_, index) => index !== proIndex);
|
|
97
|
+
} else if (flashIndex !== -1) {
|
|
98
|
+
model = 'gemini-flash-latest';
|
|
99
|
+
questionParts = commandArgs.filter((_, index) => index !== flashIndex);
|
|
100
|
+
} else if (liteIndex !== -1) {
|
|
101
|
+
model = 'gemini-flash-lite-latest';
|
|
102
|
+
questionParts = commandArgs.filter((_, index) => index !== liteIndex);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// If shorthand flags are not used, check for --model or -m
|
|
106
|
+
if (!model) {
|
|
107
|
+
const longIndex = questionParts.indexOf('--model');
|
|
108
|
+
const shortIndex = questionParts.indexOf('-m');
|
|
109
|
+
const modelIndex = longIndex !== -1 ? longIndex : shortIndex;
|
|
110
|
+
|
|
111
|
+
if (modelIndex !== -1 && questionParts.length > modelIndex + 1) {
|
|
112
|
+
model = questionParts[modelIndex + 1];
|
|
113
|
+
// Filter out --model/-m and its value
|
|
114
|
+
questionParts = questionParts.filter((_, index) => index !== modelIndex && index !== modelIndex + 1);
|
|
115
|
+
}
|
|
79
116
|
}
|
|
80
117
|
|
|
81
118
|
const question = questionParts.join(' ').trim();
|
|
@@ -84,6 +121,9 @@ async function handleAICommand() {
|
|
|
84
121
|
if (!question) {
|
|
85
122
|
console.log(chalk.bold.cyan('\n🤖 进入 AI 交互模式 (输入 exit 退出)\n'));
|
|
86
123
|
console.log(chalk.gray('直接输入你的问题,每回车一次提一个问题。\n'));
|
|
124
|
+
console.log(chalk.gray('支持的命令:'));
|
|
125
|
+
console.log(chalk.gray(' /clear - 清空对话历史'));
|
|
126
|
+
console.log(chalk.gray(' /history - 查看对话历史\n'));
|
|
87
127
|
|
|
88
128
|
const readline = require('readline');
|
|
89
129
|
const rl = readline.createInterface({
|
|
@@ -103,10 +143,32 @@ async function handleAICommand() {
|
|
|
103
143
|
process.exit(0);
|
|
104
144
|
}
|
|
105
145
|
|
|
146
|
+
// Handle special commands
|
|
147
|
+
if (trimmed === '/clear') {
|
|
148
|
+
yuangs.clearConversationHistory();
|
|
149
|
+
console.log(chalk.yellow('✓ 对话历史已清空\n'));
|
|
150
|
+
return askLoop();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (trimmed === '/history') {
|
|
154
|
+
const history = yuangs.getConversationHistory();
|
|
155
|
+
if (history.length === 0) {
|
|
156
|
+
console.log(chalk.gray('暂无对话历史\n'));
|
|
157
|
+
} else {
|
|
158
|
+
console.log(chalk.bold('📋 对话历史:\n'));
|
|
159
|
+
history.forEach((msg, index) => {
|
|
160
|
+
const prefix = msg.role === 'user' ? chalk.green('你: ') : chalk.blue('AI: ');
|
|
161
|
+
console.log(prefix + msg.content);
|
|
162
|
+
});
|
|
163
|
+
console.log('');
|
|
164
|
+
}
|
|
165
|
+
return askLoop();
|
|
166
|
+
}
|
|
167
|
+
|
|
106
168
|
if (!trimmed) {
|
|
107
169
|
return askLoop(); // 空输入则重新询问
|
|
108
170
|
}
|
|
109
|
-
|
|
171
|
+
|
|
110
172
|
// 等待回答完成后,再开启下一轮询问
|
|
111
173
|
await askOnce(trimmed, model);
|
|
112
174
|
askLoop();
|
package/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const { exec } = require('child_process');
|
|
2
2
|
const axios = require('axios');
|
|
3
3
|
|
|
4
|
+
// Store conversation history
|
|
5
|
+
let conversationHistory = [];
|
|
6
|
+
|
|
4
7
|
const APPS = {
|
|
5
8
|
shici: 'https://wealth.want.biz/shici/index.html',
|
|
6
9
|
dict: 'https://wealth.want.biz/pages/dict.html',
|
|
@@ -17,9 +20,39 @@ function openUrl(url) {
|
|
|
17
20
|
exec(command);
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
// Function to add a message to the conversation history
|
|
24
|
+
function addToConversationHistory(role, content) {
|
|
25
|
+
conversationHistory.push({ role, content });
|
|
26
|
+
|
|
27
|
+
// Keep only the last 20 messages to prevent history from growing too large
|
|
28
|
+
if (conversationHistory.length > 20) {
|
|
29
|
+
conversationHistory = conversationHistory.slice(-20);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Function to clear conversation history
|
|
34
|
+
function clearConversationHistory() {
|
|
35
|
+
conversationHistory = [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Function to get conversation history
|
|
39
|
+
function getConversationHistory() {
|
|
40
|
+
return conversationHistory;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function getAIAnswer(question, model, includeHistory = true) {
|
|
21
44
|
const url = 'https://aiproxy.want.biz/ai/explain';
|
|
22
|
-
|
|
45
|
+
|
|
46
|
+
// Prepare the prompt with conversation history if enabled
|
|
47
|
+
let prompt = question;
|
|
48
|
+
if (includeHistory && conversationHistory.length > 0) {
|
|
49
|
+
// Create a context with the current question added to history
|
|
50
|
+
const contextWithHistory = [...conversationHistory, { role: 'user', content: question }];
|
|
51
|
+
prompt = contextWithHistory.map(msg => `${msg.role}: ${msg.content}`).join('\n\n');
|
|
52
|
+
} else {
|
|
53
|
+
// If not including history, just use the question directly
|
|
54
|
+
prompt = question;
|
|
55
|
+
}
|
|
23
56
|
|
|
24
57
|
const headers = {
|
|
25
58
|
'Referer': 'https://wealth.want.biz/',
|
|
@@ -35,7 +68,17 @@ async function getAIAnswer(question, model) {
|
|
|
35
68
|
|
|
36
69
|
try {
|
|
37
70
|
const response = await axios.post(url, data, { headers });
|
|
38
|
-
|
|
71
|
+
const answer = response.data;
|
|
72
|
+
|
|
73
|
+
// Add the user's question to the conversation history
|
|
74
|
+
addToConversationHistory('user', question);
|
|
75
|
+
|
|
76
|
+
// Add the AI response to the conversation history
|
|
77
|
+
if (answer && answer.explanation) {
|
|
78
|
+
addToConversationHistory('assistant', answer.explanation);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return answer;
|
|
39
82
|
} catch (error) {
|
|
40
83
|
console.error('AI 请求失败:', error.response?.data?.message || error.message || '未知错误');
|
|
41
84
|
return null;
|
|
@@ -51,5 +94,8 @@ module.exports = {
|
|
|
51
94
|
console.log('--- YGS Apps ---');
|
|
52
95
|
Object.entries(APPS).forEach(([key, url]) => console.log(`${key}: ${url}`));
|
|
53
96
|
},
|
|
54
|
-
getAIAnswer
|
|
97
|
+
getAIAnswer,
|
|
98
|
+
addToConversationHistory,
|
|
99
|
+
clearConversationHistory,
|
|
100
|
+
getConversationHistory
|
|
55
101
|
};
|