v1.4.2: Add QwenBot Integration Tool
This commit is contained in:
222
src/tools/qwenbot.ts
Normal file
222
src/tools/qwenbot.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* QwenBot Tool for Qwen Code
|
||||
*
|
||||
* Provides AI assistant capabilities through Qwen API
|
||||
*/
|
||||
|
||||
import { writeFile, mkdir } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
const QWENBOT_CONFIG_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen", "qwenbot");
|
||||
const QWENBOT_CONFIG_FILE = join(QWENBOT_CONFIG_DIR, "config.json");
|
||||
|
||||
export interface QwenBotConfig {
|
||||
apiKey: string;
|
||||
model: string;
|
||||
temperature: number;
|
||||
maxTokens: number;
|
||||
baseUrl: string;
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: QwenBotConfig = {
|
||||
apiKey: "",
|
||||
model: "qwen-plus",
|
||||
temperature: 0.7,
|
||||
maxTokens: 2048,
|
||||
baseUrl: "https://api.qwen.ai/v1",
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize QwenBot configuration
|
||||
*/
|
||||
export async function initQwenBot(): Promise<QwenBotConfig> {
|
||||
// Create config directory if it doesn't exist
|
||||
if (!existsSync(QWENBOT_CONFIG_DIR)) {
|
||||
await mkdir(QWENBOT_CONFIG_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
// Load or create config
|
||||
let config: QwenBotConfig;
|
||||
|
||||
if (existsSync(QWENBOT_CONFIG_FILE)) {
|
||||
try {
|
||||
const content = await Bun.file(QWENBOT_CONFIG_FILE).text();
|
||||
config = { ...DEFAULT_CONFIG, ...JSON.parse(content) };
|
||||
} catch {
|
||||
config = DEFAULT_CONFIG;
|
||||
}
|
||||
} else {
|
||||
config = DEFAULT_CONFIG;
|
||||
await saveConfig(config);
|
||||
}
|
||||
|
||||
// Override with environment variables if set
|
||||
if (process.env.QWENBOT_API_KEY) {
|
||||
config.apiKey = process.env.QWENBOT_API_KEY;
|
||||
}
|
||||
if (process.env.QWENBOT_MODEL) {
|
||||
config.model = process.env.QWENBOT_MODEL;
|
||||
}
|
||||
if (process.env.QWENBOT_BASE_URL) {
|
||||
config.baseUrl = process.env.QWENBOT_BASE_URL;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save QwenBot configuration
|
||||
*/
|
||||
async function saveConfig(config: QwenBotConfig): Promise<void> {
|
||||
await writeFile(QWENBOT_CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Chat with QwenBot
|
||||
*/
|
||||
export async function chatWithQwenBot(
|
||||
message: string,
|
||||
config?: Partial<QwenBotConfig>
|
||||
): Promise<string> {
|
||||
const fullConfig = await initQwenBot();
|
||||
const mergedConfig = { ...fullConfig, ...config };
|
||||
|
||||
if (!mergedConfig.apiKey) {
|
||||
return "[ERROR] QwenBot API key not configured. Please set QWENBOT_API_KEY or configure config.json";
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${mergedConfig.baseUrl}/chat/completions`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${mergedConfig.apiKey}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: mergedConfig.model,
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You are QwenBot, a helpful AI assistant integrated with Qwen Code.",
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: message,
|
||||
},
|
||||
],
|
||||
temperature: mergedConfig.temperature,
|
||||
max_tokens: mergedConfig.maxTokens,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
return `[ERROR] QwenBot API error: ${response.status} - ${error}`;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.choices?.[0]?.message?.content || "[ERROR] No response from QwenBot";
|
||||
} catch (err) {
|
||||
return `[ERROR] QwenBot request failed: ${err instanceof Error ? err.message : String(err)}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyze code with QwenBot
|
||||
*/
|
||||
export async function analyzeCodeWithQwenBot(
|
||||
code: string,
|
||||
language?: string
|
||||
): Promise<string> {
|
||||
const message = language
|
||||
? `Analyze this ${language} code and provide feedback:\n\n\`\`\`${language}\n${code}\n\`\`\``
|
||||
: `Analyze this code and provide feedback:\n\n\`\`\`\n${code}\n\`\`\``;
|
||||
|
||||
return await chatWithQwenBot(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate documentation with QwenBot
|
||||
*/
|
||||
export async function generateDocsWithQwenBot(
|
||||
code: string,
|
||||
style?: string
|
||||
): Promise<string> {
|
||||
const message = style
|
||||
? `Generate ${style} style documentation for this code:\n\n\`\`\`\n${code}\n\`\`\``
|
||||
: `Generate documentation for this code:\n\n\`\`\`\n${code}\n\`\`\``;
|
||||
|
||||
return await chatWithQwenBot(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tests with QwenBot
|
||||
*/
|
||||
export async function generateTestsWithQwenBot(
|
||||
code: string,
|
||||
framework?: string
|
||||
): Promise<string> {
|
||||
const message = framework
|
||||
? `Generate ${framework} tests for this code:\n\n\`\`\`\n${code}\n\`\`\``
|
||||
: `Generate unit tests for this code:\n\n\`\`\`\n${code}\n\`\`\``;
|
||||
|
||||
return await chatWithQwenBot(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explain code with QwenBot
|
||||
*/
|
||||
export async function explainCodeWithQwenBot(
|
||||
code: string
|
||||
): Promise<string> {
|
||||
const message = `Explain what this code does in simple terms:\n\n\`\`\`\n${code}\n\`\`\``;
|
||||
|
||||
return await chatWithQwenBot(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick command for Qwen Code integration
|
||||
*/
|
||||
export async function qwenbotCommand(args: string[]): Promise<void> {
|
||||
const message = args.join(" ");
|
||||
|
||||
if (!message) {
|
||||
console.log("Usage: qwenbot <message>");
|
||||
console.log("");
|
||||
console.log("Examples:");
|
||||
console.log(" qwenbot Explain async/await in JavaScript");
|
||||
console.log(" qwenbot Review this code for bugs");
|
||||
console.log(" qwenbot Generate tests for this function");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("🤖 QwenBot: Thinking...");
|
||||
|
||||
const response = await chatWithQwenBot(message);
|
||||
|
||||
console.log("\n🤖 QwenBot: " + response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup QwenBot configuration interactively
|
||||
*/
|
||||
export async function setupQwenBot(): Promise<void> {
|
||||
console.log("🤖 QwenBot Setup");
|
||||
console.log("================");
|
||||
console.log("");
|
||||
console.log("To get your API key, visit: https://platform.qwen.ai/api-keys");
|
||||
console.log("");
|
||||
|
||||
const config = await initQwenBot();
|
||||
|
||||
console.log("Current configuration:");
|
||||
console.log(` Model: ${config.model}`);
|
||||
console.log(` Base URL: ${config.baseUrl}`);
|
||||
console.log(` Temperature: ${config.temperature}`);
|
||||
console.log(` Max Tokens: ${config.maxTokens}`);
|
||||
console.log(` API Key: ${config.apiKey ? "****" + config.apiKey.slice(-4) : "Not set"}`);
|
||||
console.log("");
|
||||
console.log("To configure, edit: " + QWENBOT_CONFIG_FILE);
|
||||
console.log("Or set environment variable: QWENBOT_API_KEY");
|
||||
}
|
||||
Reference in New Issue
Block a user