mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-07 13:34:08 +08:00
新增AI操作分类,支持AI对话(预设翻译、总结、shell生成)
This commit is contained in:
parent
89a2e07b13
commit
d7508c36a7
@ -26,8 +26,8 @@ quasar build
|
||||
|
||||
## ② 可视化编排
|
||||
|
||||
- 自动化:支持文件、网络、音视频、图片、文本、浏览器、键鼠等超过 20 种类型的自动化处理
|
||||
- 工具集:所有功能既可以组合使用,也可以单独运行,具备视频压缩、格式转换,图片裁剪、旋转,文本朗读,音频播放,编解码,模拟按键,鼠标连点等超过 100 种实用功能
|
||||
- 自动化:文件操作、网络操作、系统操作、音频操作、图片操作、视频操作、uTools功能、Mac自动化、Window自动化、浏览器控制、数据处理、编码加密、流程控制、编程相关、用户交互、AI对话、模拟操作、获取状态、数学计算、用户数据、显示器、输出消息等20种以上不同类型命令。
|
||||
- 工具集:所有功能既可以组合使用,也可以单独运行,具备视频压缩、格式转换,图片裁剪、旋转,文本朗读,音频播放,编解码,模拟按键,鼠标连点等超过 100 种实用功能。
|
||||
|
||||
# 二、其他特色
|
||||
|
||||
@ -156,6 +156,11 @@ JS代码注入、脚本执行(支持多种语言)、函数返回、变量管
|
||||
匹配数据获取、插件跳转、窗口控制、版本信息获取、主题切换、快捷键管理...
|
||||
Windows特定功能
|
||||
窗口控制(置顶、透明度、位置)、消息发送、文件系统监控、进程管理、注册表操作、服务管理、快捷方式管理、系统设置修改...
|
||||
|
||||
## AI对话
|
||||
|
||||
获取API支持的模型列表、AI对话...
|
||||
|
||||
## 视频处理
|
||||
|
||||
格式转换、视频压缩、视频剪辑、视频合并、速度调整、视频截图、GIF转换、音频提取、水印添加、分辨率调整、帧率设置、码率控制...
|
||||
|
@ -13,6 +13,7 @@ const quickcomposer = {
|
||||
status: require("./quickcomposer/status"),
|
||||
browser: require("./quickcomposer/browser"),
|
||||
video: require("./quickcomposer/video"),
|
||||
ai: require("./quickcomposer/ai"),
|
||||
};
|
||||
|
||||
module.exports = quickcomposer;
|
||||
|
214
plugin/lib/quickcomposer/ai/chat.js
Normal file
214
plugin/lib/quickcomposer/ai/chat.js
Normal file
@ -0,0 +1,214 @@
|
||||
const axios = require("axios");
|
||||
|
||||
// 支持的模型类型
|
||||
const MODEL_TYPES = {
|
||||
OPENAI: "openai",
|
||||
OLLAMA: "ollama",
|
||||
};
|
||||
|
||||
// 预设提示词
|
||||
const PRESET_PROMPTS = {
|
||||
// 翻译
|
||||
translate: `请将以下内容翻译成地道的中文,要求:
|
||||
1. 保持原文的专业性和准确性
|
||||
2. 符合中文的表达习惯
|
||||
3. 对于专业术语保留英文原文,并在括号中给出中文翻译
|
||||
4. 保持原文的段落格式
|
||||
|
||||
原文:`,
|
||||
|
||||
// 生成SHELL命令
|
||||
shell: `请根据以下描述生成一个 shell 命令,要求:
|
||||
1. 命令应当简洁高效
|
||||
2. 优先使用常见的命令行工具
|
||||
3. 确保命令的安全性和可靠性
|
||||
4. 对于复杂操作,添加注释说明
|
||||
5. 如果需要多个命令,使用 && 连接或使用脚本格式
|
||||
6. 直接输出命令,不要输出任何解释,不要使用markdown格式
|
||||
|
||||
需求描述:`,
|
||||
|
||||
// 总结
|
||||
summarize: `请总结以下内容的要点,要求:
|
||||
1. 提取最重要和最有价值的信息
|
||||
2. 使用简洁的语言
|
||||
3. 按重要性排序
|
||||
4. 保持逻辑性和连贯性
|
||||
5. 如果有专业术语,保留并解释
|
||||
|
||||
原文:`,
|
||||
};
|
||||
|
||||
/**
|
||||
* AI对话功能
|
||||
* @param {Object} apiConfig - API配置参数
|
||||
* @param {string} apiConfig.modelType - 模型类型(openai/ollama)
|
||||
* @param {string} apiConfig.apiUrl - API地址
|
||||
* @param {string} apiConfig.apiToken - API令牌
|
||||
* @param {string} apiConfig.model - 模型名称
|
||||
* @param {Object} content - 对话内容参数
|
||||
* @param {string} content.prompt - 用户输入的提示词
|
||||
* @param {string} content.presetPrompt - 预设提示词类型
|
||||
* @returns {Promise<Object>} 对话响应
|
||||
*/
|
||||
async function chat(apiConfig, content) {
|
||||
try {
|
||||
const { modelType, apiUrl, apiToken, model } = apiConfig;
|
||||
const { prompt, presetPrompt } = content;
|
||||
|
||||
// 验证必要参数
|
||||
if (!apiUrl || !prompt || !model) {
|
||||
throw new Error("API地址、模型名称和提示词不能为空");
|
||||
}
|
||||
|
||||
// 构建完整提示词
|
||||
const fullPrompt = presetPrompt
|
||||
? `${PRESET_PROMPTS[presetPrompt]}\n${prompt}`
|
||||
: prompt;
|
||||
|
||||
// 准备请求配置
|
||||
const config = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
let requestData;
|
||||
let url = apiUrl;
|
||||
|
||||
// 根据不同的模型类型构建请求数据
|
||||
if (modelType === MODEL_TYPES.OPENAI) {
|
||||
// OpenAI API
|
||||
config.headers["Authorization"] = `Bearer ${apiToken}`;
|
||||
requestData = {
|
||||
model: model,
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: fullPrompt,
|
||||
},
|
||||
],
|
||||
};
|
||||
} else if (modelType === MODEL_TYPES.OLLAMA) {
|
||||
// Ollama API
|
||||
// 如果用户没有指定完整的 API 路径,添加 /api/generate
|
||||
if (!url.endsWith("/api/generate")) {
|
||||
url = url.replace(/\/?$/, "/api/generate");
|
||||
}
|
||||
|
||||
requestData = {
|
||||
model: model,
|
||||
prompt: fullPrompt,
|
||||
stream: false,
|
||||
};
|
||||
} else {
|
||||
throw new Error("不支持的模型类型");
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
const response = await axios.post(url, requestData, config);
|
||||
|
||||
// 解析不同模型的响应
|
||||
let result;
|
||||
if (modelType === MODEL_TYPES.OPENAI) {
|
||||
// OpenAI 响应格式
|
||||
if (!response.data.choices || !response.data.choices[0]) {
|
||||
throw new Error("OpenAI 响应格式错误");
|
||||
}
|
||||
result = response.data.choices[0].message.content;
|
||||
} else {
|
||||
// Ollama 响应格式
|
||||
if (!response.data.response) {
|
||||
throw new Error("Ollama 响应格式错误");
|
||||
}
|
||||
result = response.data.response;
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
result,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.response?.data?.error?.message || error.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取API支持的模型列表
|
||||
* @param {Object} apiConfig - API配置参数
|
||||
* @param {string} apiConfig.modelType - 模型类型(openai/ollama)
|
||||
* @param {string} apiConfig.apiUrl - API地址
|
||||
* @param {string} apiConfig.apiToken - API令牌
|
||||
* @returns {Promise<Object>} 模型列表响应
|
||||
*/
|
||||
async function getModels(apiConfig) {
|
||||
try {
|
||||
const { modelType, apiUrl, apiToken } = apiConfig;
|
||||
|
||||
// 验证必要参数
|
||||
if (!apiUrl) {
|
||||
throw new Error("API地址不能为空");
|
||||
}
|
||||
|
||||
// 准备请求配置
|
||||
const config = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
};
|
||||
|
||||
let url = apiUrl;
|
||||
|
||||
// 根据不同的模型类型构建请求
|
||||
if (modelType === MODEL_TYPES.OPENAI) {
|
||||
// OpenAI API
|
||||
config.headers["Authorization"] = `Bearer ${apiToken}`;
|
||||
// OpenAI的模型列表接口是 /v1/models
|
||||
if (!url.endsWith("/models")) {
|
||||
url = "https://api.openai.com/v1/models";
|
||||
}
|
||||
} else if (modelType === MODEL_TYPES.OLLAMA) {
|
||||
// Ollama API
|
||||
// Ollama的模型列表接口是 /api/tags
|
||||
if (!url.endsWith("/api/tags")) {
|
||||
url = url.replace(/\/?$/, "/api/tags");
|
||||
}
|
||||
} else {
|
||||
throw new Error("不支持的模型类型");
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
const response = await axios.get(url, config);
|
||||
|
||||
// 解析不同模型的响应
|
||||
let models;
|
||||
if (modelType === MODEL_TYPES.OPENAI) {
|
||||
// OpenAI 响应格式
|
||||
if (!response.data.data) {
|
||||
throw new Error("OpenAI 响应格式错误");
|
||||
}
|
||||
models = response.data.data.map((model) => model.id);
|
||||
} else {
|
||||
// Ollama 响应格式
|
||||
if (!response.data.models) {
|
||||
throw new Error("Ollama 响应格式错误");
|
||||
}
|
||||
models = response.data.models.map((model) => model.name);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
result: models,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.response?.data?.error?.message || error.message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { chat, getModels };
|
6
plugin/lib/quickcomposer/ai/index.js
Normal file
6
plugin/lib/quickcomposer/ai/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
const { chat, getModels } = require("./chat");
|
||||
|
||||
module.exports = {
|
||||
chat,
|
||||
getModels,
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"pluginName": "快捷命令",
|
||||
"description": "实现具备UI交互的自动化操作,支持可视化拖拽及直接编写脚本两种形式。1.可视化拖拽:支持文件、网络、音视频、图片、文本、浏览器、键鼠等超过20种类型的自动化处理,2.编写脚本:支持utools的api,python、js、shell、cmd等多种脚本语言。关联关键词:自动化、可视化、RPA",
|
||||
"description": "实现具备UI交互的自动化操作,支持可视化拖拽及直接编写脚本两种形式。1.可视化拖拽:支持文件、网络、音视频、图片、文本、浏览器、键鼠、AI对话等超过20种类型的自动化处理,2.编写脚本:支持utools的api,python、js、shell、cmd等多种脚本语言。关联关键词:自动化、可视化、RPA",
|
||||
"main": "index.html",
|
||||
"homepage": "https://github.com/fofolee/uTools-quickcommand",
|
||||
"publishPage": "https://yuanliao.info/d/424",
|
||||
|
175
src/js/composer/commands/aiCommands.js
Normal file
175
src/js/composer/commands/aiCommands.js
Normal file
@ -0,0 +1,175 @@
|
||||
import { newVarInputVal } from "js/composer/varInputValManager";
|
||||
|
||||
export const aiCommands = {
|
||||
label: "AI操作",
|
||||
icon: "smart_toy",
|
||||
defaultOpened: false,
|
||||
commands: [
|
||||
{
|
||||
value: "quickcomposer.ai.getModels",
|
||||
label: "获取可用模型",
|
||||
desc: "获取API支持的模型列表",
|
||||
asyncMode: "await",
|
||||
icon: "list",
|
||||
showLoading: true,
|
||||
config: [
|
||||
{
|
||||
label: "API配置",
|
||||
component: "OptionEditor",
|
||||
icon: "settings",
|
||||
width: 12,
|
||||
options: {
|
||||
modelType: {
|
||||
component: "ButtonGroup",
|
||||
width: 12,
|
||||
height: "26px",
|
||||
options: [
|
||||
{ label: "OpenAI", value: "openai" },
|
||||
{ label: "Ollama", value: "ollama" },
|
||||
],
|
||||
},
|
||||
apiUrl: {
|
||||
label: "API地址",
|
||||
component: "VariableInput",
|
||||
icon: "link",
|
||||
width: 12,
|
||||
placeholder: "输入API地址",
|
||||
},
|
||||
apiToken: {
|
||||
label: "API令牌",
|
||||
component: "VariableInput",
|
||||
icon: "key",
|
||||
width: 12,
|
||||
placeholder: "ollama 则留空",
|
||||
},
|
||||
},
|
||||
defaultValue: {
|
||||
modelType: "openai",
|
||||
apiUrl: newVarInputVal("str", "https://api.openai.com/v1/models"),
|
||||
},
|
||||
},
|
||||
],
|
||||
outputs: {
|
||||
label: "获取模型列表结果",
|
||||
suggestName: "modelListResult",
|
||||
structure: {
|
||||
success: {
|
||||
label: "是否成功",
|
||||
suggestName: "isSuccess",
|
||||
},
|
||||
result: {
|
||||
label: "模型列表",
|
||||
suggestName: "modelList",
|
||||
},
|
||||
error: {
|
||||
label: "错误信息",
|
||||
suggestName: "resultErrorInfo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
value: "quickcomposer.ai.chat",
|
||||
label: "AI对话",
|
||||
desc: "与AI助手进行对话",
|
||||
asyncMode: "await",
|
||||
icon: "chat",
|
||||
showLoading: true,
|
||||
config: [
|
||||
{
|
||||
label: "API配置",
|
||||
component: "OptionEditor",
|
||||
icon: "settings",
|
||||
width: 12,
|
||||
options: {
|
||||
modelType: {
|
||||
component: "ButtonGroup",
|
||||
width: 12,
|
||||
height: "26px",
|
||||
options: [
|
||||
{ label: "OpenAI", value: "openai" },
|
||||
{ label: "Ollama", value: "ollama" },
|
||||
],
|
||||
},
|
||||
apiUrl: {
|
||||
label: "API地址",
|
||||
component: "VariableInput",
|
||||
icon: "link",
|
||||
width: 12,
|
||||
placeholder: "输入API地址",
|
||||
},
|
||||
apiToken: {
|
||||
label: "API令牌",
|
||||
component: "VariableInput",
|
||||
icon: "key",
|
||||
width: 6,
|
||||
placeholder: "ollama 则留空",
|
||||
},
|
||||
model: {
|
||||
label: "模型名称",
|
||||
component: "VariableInput",
|
||||
icon: "smart_toy",
|
||||
width: 6,
|
||||
placeholder: "如 gpt-3.5-turbo",
|
||||
},
|
||||
},
|
||||
defaultValue: {
|
||||
modelType: "openai",
|
||||
apiUrl: newVarInputVal(
|
||||
"str",
|
||||
"https://api.openai.com/v1/chat/completions"
|
||||
),
|
||||
model: newVarInputVal("str", "gpt-3.5-turbo"),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "对话内容",
|
||||
component: "OptionEditor",
|
||||
icon: "chat",
|
||||
width: 12,
|
||||
options: {
|
||||
presetPrompt: {
|
||||
component: "ButtonGroup",
|
||||
width: 12,
|
||||
height: "26px",
|
||||
options: [
|
||||
{ label: "自由对话", value: "" },
|
||||
{ label: "翻译", value: "translate" },
|
||||
{ label: "总结", value: "summarize" },
|
||||
{ label: "生成SHELL命令", value: "shell" },
|
||||
],
|
||||
},
|
||||
prompt: {
|
||||
label: "提示词",
|
||||
component: "VariableInput",
|
||||
icon: "edit",
|
||||
width: 12,
|
||||
placeholder: "输入要询问AI的内容",
|
||||
},
|
||||
},
|
||||
defaultValue: {
|
||||
presetPrompt: "",
|
||||
},
|
||||
},
|
||||
],
|
||||
outputs: {
|
||||
label: "AI响应",
|
||||
suggestName: "aiResponse",
|
||||
structure: {
|
||||
success: {
|
||||
label: "是否成功",
|
||||
suggestName: "isAiResponseSuccess",
|
||||
},
|
||||
result: {
|
||||
label: "响应内容",
|
||||
suggestName: "aiResponseContent",
|
||||
},
|
||||
error: {
|
||||
label: "错误信息",
|
||||
suggestName: "aiResponseError",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@ -1,5 +1,3 @@
|
||||
import { newVarInputVal } from "js/composer/varInputValManager";
|
||||
|
||||
// 系统音效选项
|
||||
const SYSTEM_SOUNDS = [
|
||||
{ label: "提示音", value: "beep" },
|
||||
|
@ -20,6 +20,7 @@ import { macosCommands } from "./macosCommands";
|
||||
import { scriptCommands } from "./scriptCommands";
|
||||
import { browserCommands } from "./browserCommands";
|
||||
import { videoCommands } from "./videoCommands";
|
||||
import { aiCommands } from "./aiCommands";
|
||||
|
||||
export const commandCategories = [
|
||||
fileCommands,
|
||||
@ -38,6 +39,7 @@ export const commandCategories = [
|
||||
scriptCommands,
|
||||
uiCommands,
|
||||
simulateCommands,
|
||||
aiCommands,
|
||||
statusCommands,
|
||||
mathCommands,
|
||||
userdataCommands,
|
||||
|
96
src/plugins/monaco/types/quickcomposer.d.ts
vendored
96
src/plugins/monaco/types/quickcomposer.d.ts
vendored
@ -2512,4 +2512,100 @@ interface quickcomposerApi {
|
||||
*/
|
||||
waitForElement(selector: string, timeout?: number): Promise<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* AI 相关功能
|
||||
*/
|
||||
ai: {
|
||||
/**
|
||||
* 与 AI 进行对话
|
||||
* @param apiConfig API配置
|
||||
* @param content 对话内容
|
||||
* @example
|
||||
* // OpenAI 示例
|
||||
* const response = await quickcomposer.ai.chat(
|
||||
* {
|
||||
* modelType: "openai",
|
||||
* apiUrl: "https://api.openai.com/v1/chat/completions",
|
||||
* apiToken: "your-api-token",
|
||||
* model: "gpt-3.5-turbo"
|
||||
* },
|
||||
* {
|
||||
* prompt: "你好",
|
||||
* presetPrompt: "" // 使用预设提示词:translate/shell/summarize
|
||||
* }
|
||||
* );
|
||||
*
|
||||
* // Ollama 示例
|
||||
* const response = await quickcomposer.ai.chat(
|
||||
* {
|
||||
* modelType: "ollama",
|
||||
* apiUrl: "http://localhost:11434/api/generate",
|
||||
* model: "qwen2.5:32b"
|
||||
* },
|
||||
* {
|
||||
* prompt: "查找进程名为chrome的进程并关闭",
|
||||
* presetPrompt: "shell"
|
||||
* }
|
||||
* );
|
||||
*/
|
||||
chat(
|
||||
apiConfig: {
|
||||
/** 模型类型:openai/ollama */
|
||||
modelType: "openai" | "ollama";
|
||||
/** API地址 */
|
||||
apiUrl: string;
|
||||
/** API令牌(仅 OpenAI 需要) */
|
||||
apiToken?: string;
|
||||
/** 模型名称 */
|
||||
model: string;
|
||||
},
|
||||
content: {
|
||||
/** 提示词 */
|
||||
prompt: string;
|
||||
/** 预设提示词类型 */
|
||||
presetPrompt?: "" | "translate" | "shell" | "summarize";
|
||||
}
|
||||
): Promise<{
|
||||
/** 是否成功 */
|
||||
success: boolean;
|
||||
/** AI 响应内容 */
|
||||
result?: string;
|
||||
/** 错误信息 */
|
||||
error?: string;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* 获取 API 支持的模型列表
|
||||
* @param apiConfig API配置
|
||||
* @example
|
||||
* // OpenAI 示例
|
||||
* const models = await quickcomposer.ai.getModels({
|
||||
* modelType: "openai",
|
||||
* apiUrl: "https://api.openai.com/v1/models",
|
||||
* apiToken: "your-api-token"
|
||||
* });
|
||||
*
|
||||
* // Ollama 示例
|
||||
* const models = await quickcomposer.ai.getModels({
|
||||
* modelType: "ollama",
|
||||
* apiUrl: "http://localhost:11434"
|
||||
* });
|
||||
*/
|
||||
getModels(apiConfig: {
|
||||
/** 模型类型:openai/ollama */
|
||||
modelType: "openai" | "ollama";
|
||||
/** API地址 */
|
||||
apiUrl: string;
|
||||
/** API令牌(仅 OpenAI 需要) */
|
||||
apiToken?: string;
|
||||
}): Promise<{
|
||||
/** 是否成功 */
|
||||
success: boolean;
|
||||
/** 模型名称列表 */
|
||||
result?: string[];
|
||||
/** 错误信息 */
|
||||
error?: string;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user