225 lines
5.7 KiB
JavaScript
225 lines
5.7 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* SiliconFlow API Client
|
||
* 支持 GLM-4 等模型
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const https = require('https');
|
||
|
||
// 配置
|
||
const CONFIG_PATH = process.env.SILICONFLOW_CONFIG_PATH ||
|
||
path.join(process.env.HOME || process.env.USERPROFILE, '.config', 'siliconflow', 'api_key');
|
||
|
||
const API_KEY = fs.readFileSync(CONFIG_PATH, 'utf8').trim();
|
||
const API_URL = 'https://api.siliconflow.cn/v1/chat/completions';
|
||
const MODEL = 'Pro/moonshotai/Kimi-K2.5';
|
||
|
||
class SiliconFlow {
|
||
constructor() {
|
||
this.apiKey = API_KEY;
|
||
this.model = MODEL;
|
||
}
|
||
|
||
async chat(messages, options = {}) {
|
||
const maxTokens = options.maxTokens || 4096;
|
||
const temperature = options.temperature || 0.7;
|
||
|
||
const data = JSON.stringify({
|
||
model: this.model,
|
||
messages: messages,
|
||
max_tokens: maxTokens,
|
||
temperature: temperature
|
||
});
|
||
|
||
return new Promise((resolve, reject) => {
|
||
const url = new URL(API_URL);
|
||
|
||
const options = {
|
||
hostname: url.hostname,
|
||
port: url.port || 443,
|
||
path: url.pathname,
|
||
method: 'POST',
|
||
headers: {
|
||
'Authorization': `Bearer ${this.apiKey}`,
|
||
'Content-Type': 'application/json',
|
||
'Content-Length': Buffer.byteLength(data)
|
||
},
|
||
timeout: 60000
|
||
};
|
||
|
||
const req = https.request(options, (res) => {
|
||
let body = '';
|
||
res.on('data', chunk => body += chunk);
|
||
res.on('end', () => {
|
||
try {
|
||
const json = JSON.parse(body);
|
||
if (json.choices && json.choices[0]) {
|
||
resolve(json.choices[0].message.content);
|
||
} else {
|
||
reject(new Error(`API 错误: ${body}`));
|
||
}
|
||
} catch (e) {
|
||
reject(e);
|
||
}
|
||
});
|
||
});
|
||
|
||
req.on('error', reject);
|
||
req.write(data);
|
||
req.end();
|
||
});
|
||
}
|
||
|
||
async complete(prompt, language = 'javascript') {
|
||
const messages = [
|
||
{
|
||
role: 'system',
|
||
content: `你是专业程序员,擅长写高质量 ${language} 代码。只输出代码,不要解释。`
|
||
},
|
||
{
|
||
role: 'user',
|
||
content: `用 ${language} 写代码:\n\n${prompt}`
|
||
}
|
||
];
|
||
|
||
return await this.chat(messages);
|
||
}
|
||
|
||
async fixBug(code, error) {
|
||
const messages = [
|
||
{
|
||
role: 'system',
|
||
content: `你是资深程序员,擅长调试和修复 bug。只输出修复后的完整代码。`
|
||
},
|
||
{
|
||
role: 'user',
|
||
content: `修复以下代码的 bug:\n\n错误: ${error}\n\n代码:\n${code}`
|
||
}
|
||
];
|
||
|
||
return await this.chat(messages);
|
||
}
|
||
|
||
async explain(code) {
|
||
const messages = [
|
||
{
|
||
role: 'system',
|
||
content: `你是专业程序员,善于解释代码。`
|
||
},
|
||
{
|
||
role: 'user',
|
||
content: `解释以下代码:\n\n${code}`
|
||
}
|
||
];
|
||
|
||
return await this.chat(messages);
|
||
}
|
||
|
||
async rewrite(code, instructions) {
|
||
const messages = [
|
||
{
|
||
role: 'system',
|
||
content: `你是专业程序员,擅长重构和优化代码。只输出优化后的完整代码。`
|
||
},
|
||
{
|
||
role: 'user',
|
||
content: `重写以下代码:\n\n要求: ${instructions}\n\n原代码:\n${code}`
|
||
}
|
||
];
|
||
|
||
return await this.chat(messages);
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
const args = process.argv.slice(2);
|
||
const command = args[0] || 'help';
|
||
|
||
const sf = new SiliconFlow();
|
||
|
||
try {
|
||
switch (command) {
|
||
case 'chat':
|
||
const msg = args.slice(1).join(' ');
|
||
console.log('\n🤖 SiliconFlow:\n');
|
||
const response = await sf.chat([{ role: 'user', content: msg }]);
|
||
console.log(response);
|
||
break;
|
||
|
||
case 'code':
|
||
const prompt = args.slice(1).join(' ');
|
||
console.log('\n💻 生成代码:\n');
|
||
const code = await sf.complete(prompt);
|
||
console.log(code);
|
||
break;
|
||
|
||
case 'fix':
|
||
const error = args[1] || '未知错误';
|
||
const buggyCode = args.slice(2).join(' ');
|
||
console.log('\n🔧 修复 bug:\n');
|
||
const fixed = await sf.fixBug(buggyCode, error);
|
||
console.log(fixed);
|
||
break;
|
||
|
||
case 'explain':
|
||
const codeToExplain = args.slice(1).join(' ');
|
||
console.log('\n📖 解释代码:\n');
|
||
const explained = await sf.explain(codeToExplain);
|
||
console.log(explained);
|
||
break;
|
||
|
||
case 'rewrite':
|
||
const instructions = args[1] || '优化代码';
|
||
const oldCode = args.slice(2).join(' ');
|
||
console.log('\n♻️ 重写代码:\n');
|
||
const rewritten = await sf.rewrite(oldCode, instructions);
|
||
console.log(rewritten);
|
||
break;
|
||
|
||
case 'version':
|
||
console.log(`\n🤖 SiliconFlow API Client`);
|
||
console.log(`Model: ${sf.model}\n`);
|
||
break;
|
||
|
||
case 'help':
|
||
default:
|
||
console.log(`
|
||
🤖 SiliconFlow AI 编程助手
|
||
|
||
用法:
|
||
silicon chat "你好" # 对话
|
||
silicon code "写一个HTTP服务器" # 生成代码
|
||
silicon fix "错误信息" " buggy code" # 修复 bug
|
||
silicon explain "code" # 解释代码
|
||
silicon rewrite "优化" "code" # 重写代码
|
||
silicon version # 版本
|
||
silicon help # 帮助
|
||
|
||
示例:
|
||
silicon code "用 Node.js 写一个计算器"
|
||
silicon fix "Cannot read property" "const a = b.c"
|
||
|
||
配置:
|
||
API Key: ~/.config/siliconflow/api_key
|
||
模型: ${sf.model}
|
||
|
||
支持的模型:
|
||
- Pro/zai-org/GLM-4.7
|
||
- deepseek-ai/DeepSeek-V2
|
||
- Qwen/Qwen2.5-Coder-32B-Instruct
|
||
`);
|
||
break;
|
||
}
|
||
} catch (error) {
|
||
console.error('\n❌ 错误:', error.message);
|
||
}
|
||
}
|
||
|
||
module.exports = { SiliconFlow };
|
||
|
||
if (require.main === module) {
|
||
main();
|
||
}
|