mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 22:07:10 +00:00
喵喵喵
This commit is contained in:
parent
d1ca268f36
commit
267c24dda5
1 changed files with 66 additions and 46 deletions
|
|
@ -4,13 +4,15 @@ import { Config } from '../config.js';
|
||||||
import common from '../../../../lib/common/common.js';
|
import common from '../../../../lib/common/common.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代码执行工具类 - 使用 Gemini API
|
* CodeExecutionTool - Gemini API代码执行工具类
|
||||||
* @class CodeExecutionTool
|
* 支持多种编程语言的代码执行,并提供详细的执行结果和分析
|
||||||
* @extends {AbstractTool}
|
* @extends {AbstractTool}
|
||||||
*/
|
*/
|
||||||
export class CodeExecutionTool extends AbstractTool {
|
export class CodeExecutionTool extends AbstractTool {
|
||||||
|
// 工具标识名称
|
||||||
name = 'CodeExecutionTool';
|
name = 'CodeExecutionTool';
|
||||||
|
|
||||||
|
// 工具参数定义
|
||||||
parameters = {
|
parameters = {
|
||||||
properties: {
|
properties: {
|
||||||
code: {
|
code: {
|
||||||
|
|
@ -29,54 +31,54 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
required: ['code', 'language'],
|
required: ['code', 'language'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 工具功能描述
|
||||||
description = '使用 Gemini API 执行代码,支持多种编程语言,并返回执行结果和相关解释。';
|
description = '使用 Gemini API 执行代码,支持多种编程语言,并返回执行结果和相关解释。';
|
||||||
|
|
||||||
// 配置常量
|
// API请求超时设置(30秒)
|
||||||
static TIMEOUT = 30000; // 请求超时时间:30秒
|
static TIMEOUT = 30000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工具执行函数
|
* 工具主执行函数
|
||||||
* @param {Object} opt - 工具参数
|
* @param {Object} opt - 执行参数对象
|
||||||
* @param {string} opt.code - 代码内容
|
* @param {string} opt.code - 需要执行的代码
|
||||||
* @param {string} opt.language - 编程语言
|
* @param {string} opt.language - 代码语言
|
||||||
* @param {string} [opt.description] - 代码功能描述
|
* @param {string} [opt.description] - 代码功能描述
|
||||||
* @param {Object} e - 事件对象
|
* @param {Object} e - 事件对象
|
||||||
* @returns {Promise<Object>} - 包含执行结果的对象
|
* @returns {Promise<Object>} 执行结果对象
|
||||||
*/
|
*/
|
||||||
func = async function (opt, e) {
|
func = async function (opt, e) {
|
||||||
const { code, language, description } = opt;
|
const { code, language, description } = opt;
|
||||||
|
|
||||||
|
// 代码内容验证
|
||||||
if (!code?.trim()) {
|
if (!code?.trim()) {
|
||||||
throw new Error('代码内容不能为空');
|
throw new Error('代码内容不能为空');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 执行代码并获取结果
|
||||||
const result = await this.executeCode(code, language, description);
|
const result = await this.executeCode(code, language, description);
|
||||||
console.debug(`[CodeExecutionTool] 执行结果:`, result);
|
console.debug(`[CodeExecutionTool] 执行结果:`, result);
|
||||||
|
|
||||||
// 优化消息构建逻辑
|
// 解构结果对象
|
||||||
const messages = [];
|
const { output, executionOutput, explanation, error } = result;
|
||||||
|
const forwardMsg = [];
|
||||||
|
|
||||||
// 添加代码信息
|
// 根据执行结果构建消息
|
||||||
messages.push(`执行代码:\n\`\`\`${language}\n${code}\n\`\`\``);
|
if (error) {
|
||||||
|
forwardMsg.push(`执行出错:\n${error}`);
|
||||||
// 添加执行结果
|
|
||||||
if (result.error) {
|
|
||||||
messages.push(`执行错误:\n\`\`\`\n${result.error}\n\`\`\``);
|
|
||||||
} else {
|
} else {
|
||||||
messages.push(`执行结果:\n\`\`\`\n${result.output}\n\`\`\``);
|
// 添加程序实际输出(如果有)
|
||||||
|
if (executionOutput) {
|
||||||
|
forwardMsg.push(`程序输出:\n${executionOutput}`);
|
||||||
|
}
|
||||||
|
forwardMsg.push(`执行结果:\n${output}`);
|
||||||
|
if (explanation) {
|
||||||
|
forwardMsg.push(`\n代码分析:\n${explanation}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加代码分析
|
|
||||||
if (result.explanation) {
|
|
||||||
messages.push(`代码分析:\n${result.explanation}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加执行时间
|
|
||||||
messages.push(`执行时间:${new Date(result.executionTime).toLocaleString()}`);
|
|
||||||
|
|
||||||
// 发送转发消息
|
// 发送转发消息
|
||||||
e.reply(await common.makeForwardMsg(e, messages, `${e.sender.card || e.sender.nickname || e.user_id}的代码执行结果`));
|
e.reply(await common.makeForwardMsg(e, forwardMsg, `${e.sender.card || e.sender.nickname || e.user_id}的代码执行结果`));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -86,22 +88,25 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 Gemini API 执行代码
|
* 通过Gemini API执行代码
|
||||||
* @param {string} code - 代码内容
|
* @param {string} code - 代码内容
|
||||||
* @param {string} language - 编程语言
|
* @param {string} language - 编程语言
|
||||||
* @param {string} [description] - 代码功能描述
|
* @param {string} [description] - 代码描述
|
||||||
* @returns {Promise<Object>} - 包含执行结果的对象
|
* @returns {Promise<Object>} API执行结果
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async executeCode(code, language, description) {
|
async executeCode(code, language, description) {
|
||||||
|
// 获取API配置信息
|
||||||
const apiKey = Config.geminiKey;
|
const apiKey = Config.geminiKey;
|
||||||
const apiBaseUrl = Config.geminiBaseUrl;
|
const apiBaseUrl = Config.geminiBaseUrl;
|
||||||
const apiUrl = `${apiBaseUrl}/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${apiKey}`;
|
const apiUrl = `${apiBaseUrl}/v1beta/models/gemini-2.0-flash-exp:generateContent?key=${apiKey}`;
|
||||||
|
|
||||||
|
// API配置验证
|
||||||
if (!apiKey || !apiBaseUrl) {
|
if (!apiKey || !apiBaseUrl) {
|
||||||
throw new Error('Gemini API 配置缺失');
|
throw new Error('Gemini API 配置缺失');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建API请求体
|
||||||
const requestBody = {
|
const requestBody = {
|
||||||
"systemInstruction": {
|
"systemInstruction": {
|
||||||
"parts": [{
|
"parts": [{
|
||||||
|
|
@ -126,9 +131,11 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 设置请求超时控制
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), CodeExecutionTool.TIMEOUT);
|
const timeoutId = setTimeout(() => controller.abort(), CodeExecutionTool.TIMEOUT);
|
||||||
|
|
||||||
|
// 发送API请求
|
||||||
const response = await fetch(apiUrl, {
|
const response = await fetch(apiUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -142,6 +149,7 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
// 响应状态检查
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`API 请求失败: ${data.error?.message || '未知错误'}`);
|
throw new Error(`API 请求失败: ${data.error?.message || '未知错误'}`);
|
||||||
}
|
}
|
||||||
|
|
@ -156,11 +164,11 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建提示词
|
* 构建API提示词
|
||||||
* @param {string} code - 代码内容
|
* @param {string} code - 代码内容
|
||||||
* @param {string} language - 编程语言
|
* @param {string} language - 编程语言
|
||||||
* @param {string} [description] - 代码功能描述
|
* @param {string} [description] - 代码描述
|
||||||
* @returns {string} - 格式化的提示词
|
* @returns {string} 格式化的提示词
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
constructPrompt(code, language, description) {
|
constructPrompt(code, language, description) {
|
||||||
|
|
@ -170,24 +178,27 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
}
|
}
|
||||||
prompt += `\n执行代码:\n\`\`\`${language}\n${code}\n\`\`\`\n`;
|
prompt += `\n执行代码:\n\`\`\`${language}\n${code}\n\`\`\`\n`;
|
||||||
prompt += '请按照以下格式返回结果:\n';
|
prompt += '请按照以下格式返回结果:\n';
|
||||||
prompt += '执行结果(OUTCOME_OK):\n```\n<执行输出>\n```\n';
|
prompt += '执行输出:\n```\n<程序实际输出内容>\n```\n';
|
||||||
|
prompt += '执行结果(OUTCOME_OK):\n```\n<执行状态和结果说明>\n```\n';
|
||||||
prompt += '如果执行出错,请使用:\n';
|
prompt += '如果执行出错,请使用:\n';
|
||||||
prompt += '执行结果(OUTCOME_ERROR):\n```\n<错误信息>\n```\n';
|
prompt += '执行结果(OUTCOME_ERROR):\n```\n<错误信息>\n```\n';
|
||||||
prompt += '如果需要,可以在最后添加代码分析。';
|
prompt += '代码分析:\n<分析和建议>';
|
||||||
return prompt;
|
return prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理 Gemini API 响应
|
* 处理Gemini API响应数据
|
||||||
* @param {Object} data - API 响应数据
|
* @param {Object} data - API响应数据
|
||||||
* @returns {Object} - 处理后的结果对象
|
* @returns {Object} 处理后的结果对象,包含输出、执行输出、解释和错误信息
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
processGeminiResponse(data) {
|
processGeminiResponse(data) {
|
||||||
|
// 响应数据结构验证
|
||||||
if (!data?.candidates?.[0]?.content?.parts) {
|
if (!data?.candidates?.[0]?.content?.parts) {
|
||||||
throw new Error('无效的 API 响应');
|
throw new Error('无效的 API 响应');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 合并响应文本
|
||||||
const response = data.candidates[0].content.parts
|
const response = data.candidates[0].content.parts
|
||||||
.map(part => part.text)
|
.map(part => part.text)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
|
|
@ -196,23 +207,30 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
let output = '';
|
let output = '';
|
||||||
let explanation = '';
|
let explanation = '';
|
||||||
let error = null;
|
let error = null;
|
||||||
|
let executionOutput = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 查找执行结果部分
|
// 提取执行输出
|
||||||
|
const outputMatch = response.match(/执行输出:\s*```(?:\w*\n)?([\s\S]*?)```/);
|
||||||
|
if (outputMatch) {
|
||||||
|
executionOutput = outputMatch[1].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取执行结果
|
||||||
const outcomeMatch = response.match(/执行结果\(OUTCOME_OK\):\s*```(?:\w*\n)?([\s\S]*?)```/);
|
const outcomeMatch = response.match(/执行结果\(OUTCOME_OK\):\s*```(?:\w*\n)?([\s\S]*?)```/);
|
||||||
if (outcomeMatch) {
|
if (outcomeMatch) {
|
||||||
output = outcomeMatch[1].trim();
|
output = outcomeMatch[1].trim();
|
||||||
} else {
|
} else {
|
||||||
// 检查是否有错误结果
|
// 提取错误信息
|
||||||
const errorMatch = response.match(/执行结果\(OUTCOME_ERROR\):\s*```(?:\w*\n)?([\s\S]*?)```/);
|
const errorMatch = response.match(/执行结果\(OUTCOME_ERROR\):\s*```(?:\w*\n)?([\s\S]*?)```/);
|
||||||
if (errorMatch) {
|
if (errorMatch) {
|
||||||
error = errorMatch[1].trim();
|
error = errorMatch[1].trim();
|
||||||
} else {
|
} else {
|
||||||
output = response; // 如果没有匹配到预期格式,返回原始响应
|
output = response; // 使用原始响应作为输出
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提取代码分析部分(如果有)
|
// 提取代码分析
|
||||||
const analysisMatch = response.match(/代码分析:([\s\S]*?)(?=\n\n|$)/);
|
const analysisMatch = response.match(/代码分析:([\s\S]*?)(?=\n\n|$)/);
|
||||||
if (analysisMatch) {
|
if (analysisMatch) {
|
||||||
explanation = analysisMatch[1].trim();
|
explanation = analysisMatch[1].trim();
|
||||||
|
|
@ -222,11 +240,13 @@ export class CodeExecutionTool extends AbstractTool {
|
||||||
output = response; // 解析失败时返回原始响应
|
output = response; // 解析失败时返回原始响应
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回完整的结果对象
|
||||||
return {
|
return {
|
||||||
output,
|
output, // 执行结果说明
|
||||||
explanation,
|
executionOutput, // 程序实际输出
|
||||||
error,
|
explanation, // 代码分析
|
||||||
executionTime: Date.now()
|
error, // 错误信息
|
||||||
|
executionTime: Date.now() // 执行时间戳
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue