diff --git a/README.md b/README.md index 151251f..df39f05 100644 --- a/README.md +++ b/README.md @@ -157,9 +157,9 @@ JS代码注入、脚本执行(支持多种语言)、函数返回、变量管 Windows特定功能 窗口控制(置顶、透明度、位置)、消息发送、文件系统监控、进程管理、注册表操作、服务管理、快捷方式管理、系统设置修改... -## AI对话 +## AI问答 -获取API支持的模型列表、AI对话... +AI问答(自由问答、翻译、总结、生成shell代码)... ## 视频处理 diff --git a/plugin/lib/quickcomposer/ai/chat.js b/plugin/lib/ai.js similarity index 99% rename from plugin/lib/quickcomposer/ai/chat.js rename to plugin/lib/ai.js index f2d18cc..17c1eb7 100644 --- a/plugin/lib/quickcomposer/ai/chat.js +++ b/plugin/lib/ai.js @@ -51,7 +51,7 @@ const PRESET_PROMPTS = { * @param {string} content.presetPrompt - 预设提示词类型 * @returns {Promise} 对话响应 */ -async function chat(apiConfig, content) { +async function chat(content, apiConfig) { try { const { modelType, apiUrl, apiToken, model } = apiConfig; const { prompt, presetPrompt } = content; diff --git a/plugin/lib/quickcommand.js b/plugin/lib/quickcommand.js index f0e1cae..183e6f2 100644 --- a/plugin/lib/quickcommand.js +++ b/plugin/lib/quickcommand.js @@ -5,6 +5,9 @@ const kill = require("tree-kill"); const iconv = require("iconv-lite"); const path = require("path"); const axios = require("axios"); +const { chat, getModels } = require("./ai"); + +window.getModelsFromAiApi = getModels; const systemDialog = require("./dialog/service"); @@ -184,6 +187,11 @@ const quickcommand = { } return null; }, + + askAI: async function (content, apiConfig) { + return await chat(content, apiConfig); + }, + ...systemDialog, }; diff --git a/plugin/lib/quickcomposer.js b/plugin/lib/quickcomposer.js index 1dbccbc..8c05e61 100644 --- a/plugin/lib/quickcomposer.js +++ b/plugin/lib/quickcomposer.js @@ -13,7 +13,6 @@ const quickcomposer = { status: require("./quickcomposer/status"), browser: require("./quickcomposer/browser"), video: require("./quickcomposer/video"), - ai: require("./quickcomposer/ai"), }; module.exports = quickcomposer; diff --git a/plugin/lib/quickcomposer/ai/index.js b/plugin/lib/quickcomposer/ai/index.js deleted file mode 100644 index d4af17c..0000000 --- a/plugin/lib/quickcomposer/ai/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const { chat, getModels } = require("./chat"); - -module.exports = { - chat, - getModels, -}; diff --git a/src/App.vue b/src/App.vue index 35272e2..ff00477 100644 --- a/src/App.vue +++ b/src/App.vue @@ -129,19 +129,19 @@ export default defineComponent({ }, outPlugin() { // 退出时保存RunCode和RunComposer的命令 - if (!["code", "composer"].includes(this.$route.name)) return; + if (["code", "composer"].includes(this.$route.name)) { + let currentCommand = window.lodashM.cloneDeep( + this.commandManager.state.currentCommand + ); - let currentCommand = window.lodashM.cloneDeep( - this.commandManager.state.currentCommand - ); + if (this.$route.name === "composer") { + currentCommand = + this.commandManager.getLitedComposerCommand(currentCommand); + } - if (this.$route.name === "composer") { - currentCommand = - this.commandManager.getLitedComposerCommand(currentCommand); + dbManager.putDB(currentCommand, `cfg_${this.$route.name}History`); } - dbManager.putDB(currentCommand, `cfg_${this.$route.name}History`); - this.$router.push("/"); this.saveProfile(); }, diff --git a/src/components/composer/ai/AskAIEditor.vue b/src/components/composer/ai/AskAIEditor.vue new file mode 100644 index 0000000..2436ec6 --- /dev/null +++ b/src/components/composer/ai/AskAIEditor.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/src/components/menu/index.vue b/src/components/menu/index.vue index fdad1e5..6ac56e5 100644 --- a/src/components/menu/index.vue +++ b/src/components/menu/index.vue @@ -51,6 +51,14 @@ + + + + + + AI配置 + + + + + + @@ -110,6 +122,7 @@ import CommandManageMenu from "components/menu/CommandManageMenu.vue"; import UtilityFeaturesMenu from "components/menu/UtilityFeaturesMenu.vue"; import EnvConfigMenu from "components/menu/EnvConfigMenu.vue"; import PersonalizeMenu from "components/menu/PersonalizeMenu.vue"; +import AIConfig from "components/popup/AIConfig.vue"; import UserData from "components/popup/UserData.vue"; import { utoolsFull } from "js/utools.js"; import { useCommandManager } from "js/commandManager"; @@ -125,6 +138,7 @@ export default { EnvConfigMenu, PersonalizeMenu, UserData, + AIConfig, }, data() { return { @@ -132,6 +146,7 @@ export default { showAbout: false, showPanelConf: false, showUserData: false, + showAIConfig: false, utools: utoolsFull, }; }, diff --git a/src/components/popup/AIConfig.vue b/src/components/popup/AIConfig.vue new file mode 100644 index 0000000..522957b --- /dev/null +++ b/src/components/popup/AIConfig.vue @@ -0,0 +1,113 @@ + + + diff --git a/src/js/composer/cardComponents.js b/src/js/composer/cardComponents.js index 6d6fd87..e94af63 100644 --- a/src/js/composer/cardComponents.js +++ b/src/js/composer/cardComponents.js @@ -59,3 +59,8 @@ export const ReturnEditor = defineAsyncComponent(() => export const ScriptEditor = defineAsyncComponent(() => import("components/composer/script/ScriptEditor.vue") ); + +// AI组件 +export const AskAIEditor = defineAsyncComponent(() => + import("src/components/composer/ai/AskAIEditor.vue") +); diff --git a/src/js/composer/commands/aiCommands.js b/src/js/composer/commands/aiCommands.js index ca2b452..ead4cb0 100644 --- a/src/js/composer/commands/aiCommands.js +++ b/src/js/composer/commands/aiCommands.js @@ -6,150 +6,11 @@ export const aiCommands = { defaultOpened: false, commands: [ { - value: "quickcomposer.ai.getModels", - label: "获取可用模型", - desc: "获取API支持的模型列表", - asyncMode: "await", - icon: "list", - 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助手进行对话", + value: "quickcommand.askAI", + label: "AI问答", asyncMode: "await", icon: "chat", - 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: "", - }, - }, - ], + component: "AskAIEditor", outputs: { label: "AI响应", suggestName: "aiResponse", diff --git a/src/plugins/monaco/types/quickcommand.api.d.ts b/src/plugins/monaco/types/quickcommand.api.d.ts index 0701d54..01c93fc 100644 --- a/src/plugins/monaco/types/quickcommand.api.d.ts +++ b/src/plugins/monaco/types/quickcommand.api.d.ts @@ -888,6 +888,64 @@ interface quickcommandApi { * ``` */ closeLoadingBar(loadingBar?: { id: number; close: () => void }): void; + + /** + * 与 AI 进行问答 + * @param content 对话内容 + * @param apiConfig API配置 + * @example + * // OpenAI 示例 + * const response = await quickcommand.askAI( + * { + * prompt: "你好", + * presetPrompt: "" // 使用预设提示词:translate/shell/summarize + * }, + * { + * modelType: "openai", + * apiUrl: "https://api.openai.com/v1/chat/completions", + * apiToken: "your-api-token", + * model: "gpt-3.5-turbo" + * } + * ); + * + * // Ollama 示例 + * const response = await quickcommand.askAI( + * { + * prompt: "查找进程名为chrome的进程并关闭", + * presetPrompt: "shell" + * }, + * { + * modelType: "ollama", + * apiUrl: "http://localhost:11434/api/generate", + * model: "qwen2.5:32b" + * } + * ); + */ + askAI( + content: { + /** 提示词 */ + prompt: string; + /** 预设提示词类型 */ + presetPrompt?: "" | "translate" | "shell" | "summarize"; + }, + apiConfig: { + /** 模型类型:openai/ollama */ + modelType: "openai" | "ollama"; + /** API地址 */ + apiUrl: string; + /** API令牌(仅 OpenAI 需要) */ + apiToken?: string; + /** 模型名称 */ + model: string; + } + ): Promise<{ + /** 是否成功 */ + success: boolean; + /** AI 响应内容 */ + result?: string; + /** 错误信息 */ + error?: string; + }>; } declare var quickcommand: quickcommandApi; diff --git a/src/plugins/monaco/types/quickcomposer.d.ts b/src/plugins/monaco/types/quickcomposer.d.ts index fcb5dc7..3002208 100644 --- a/src/plugins/monaco/types/quickcomposer.d.ts +++ b/src/plugins/monaco/types/quickcomposer.d.ts @@ -2512,100 +2512,4 @@ interface quickcomposerApi { */ waitForElement(selector: string, timeout?: number): Promise; }; - - /** - * 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; - }>; - }; }