From 01e7d90d3ade5d5ac6e22a71853f34cac4cc5946 Mon Sep 17 00:00:00 2001 From: smallstone <> Date: Mon, 20 Nov 2023 16:40:11 +0800 Subject: [PATCH] feat: add request for idea --- src/util/MessageUtil.ts | 1 - src/util/bridge.md | 43 ++++++++ src/util/ideaBridge.ts | 212 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 src/util/bridge.md create mode 100644 src/util/ideaBridge.ts diff --git a/src/util/MessageUtil.ts b/src/util/MessageUtil.ts index f3a762c..3010b50 100644 --- a/src/util/MessageUtil.ts +++ b/src/util/MessageUtil.ts @@ -61,7 +61,6 @@ class MessageUtil { // Send a message to the VSCode API sendMessage(message: any) { - console.log("util sendMessage message: ", message); if (process.env.platform === "idea") { IdeaBridge.sendMessage(message); } else { diff --git a/src/util/bridge.md b/src/util/bridge.md new file mode 100644 index 0000000..82733d0 --- /dev/null +++ b/src/util/bridge.md @@ -0,0 +1,43 @@ +## sendMessage + +- getUserAccessKey // 获取 access key +- doCommit // 提交代码 +- updateSetting // 更新设置(目前只有更换模型) +- getSetting // 获取默认模型 +- deleteChatMessage // 删除最近一条消息 +- show_diff // 调用 editor 代码对比 + -- later -- +- stopDevChat // 停止生成 +- doCommand // + -- content + // 1. 打开设置 + // 2. 启动 ask code 安装 + // 3. 设置 access key +- featureToggles ?? +- isDevChatInstalled // 判断 ask code 是否安装 + +- historyMessages // 页面的历史消息 +- contextDetail // 获取 appendContext 响应之后,发送次请求获取文件的内容 +- addContext // 点击 context 菜单(比如 git diff)之后发送到消息 +- code_file_apply // 代码应用到 editor,替换 current file +- code_apply // 代码应用到 editor 光标位置 +- sendMessage // 发送消息 +- regeneration // 错误时重新生成 +- regContextList // git diff 之类的列表 +- regModelList // model 列表 +- regCommandList // 输入 / 之后出现的列表 + +## registerHandler + +- getUserAccessKey // 获取 access key +- regCommandList // 获取 / 之后出现的列表 +- appendContext // 右键添加到 context 或者 context 菜单点击的响应 +- contextDetailResponse // 获取到的文件内容 +- loadHistoryMessages // 与 historyMessages 对应 +- isDevChatInstalled // 与 isDevChatInstalled 对应 +- deletedChatMessage // 与 deleteChatMessage 对应· +- regContextList // 与 regContextList 对应 +- regModelList // 与 regModelList +- receiveMessagePartial // 部分对话 +- receiveMessage // 对话 +- systemMessage ?? diff --git a/src/util/ideaBridge.ts b/src/util/ideaBridge.ts new file mode 100644 index 0000000..89aee54 --- /dev/null +++ b/src/util/ideaBridge.ts @@ -0,0 +1,212 @@ +const JStoIdea = { + sendMessage: (message: string, context: string = "", parent: string = "") => { + const params = { + action: "sendMessage/request", + metadata: { + callback: "IdeaToJSMessage", + parent: parent, + }, + payload: { + contexts: [], + message: message, + }, + }; + + console.log("ready to call java params: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + getModel: () => { + const params = { + action: "listModels/request", + metadata: { + callback: "IdeaToJSMessage", + }, + }; + + console.log("getModel ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + getContextList: () => { + const params = { + action: "listContexts/request", + metadata: { + callback: "IdeaToJSMessage", + }, + }; + console.log("getContextList ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + getCommandList: () => { + const params = { + action: "listCommands/request", + metadata: { + callback: "IdeaToJSMessage", + }, + }; + console.log("getCommandList ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + insertCode: (code) => { + const params = { + action: "insertCode/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + content: code, + }, + }; + console.log("insertCode ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + + replaceFileContent: (code) => { + const params = { + action: "replaceFileContent/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + content: code, + }, + }; + console.log("replaceFileContent ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + + viewDiff: (code) => { + const params = { + action: "viewDiff/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + content: code, + }, + }; + console.log("viewDiff ready to call java: ", params); + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, +}; + +class IdeaBridge { + private static instance: IdeaBridge; + handle: any = {}; + + constructor() { + this.handle = {}; + // 注册全局的回调函数,用于接收来自IDEA的消息 + window.IdeaToJSMessage = (res: any) => { + console.log("IdeaToJSMessage message: ", res); + switch (res.action) { + case "sendMessage/response": + this.resviceMessage(res); + break; + case "listModels/response": + this.resviceModelList(res); + break; + case "listContexts/response": + this.resviceContextList(res); + break; + case "listCommands/response": + this.resviceCommandList(res); + break; + default: + break; + } + }; + } + + resviceCommandList(res) { + const result = res.payload.commands.map((item) => ({ + name: item.name, + pattern: item.name, + description: item.description, + })); + this.handle.regCommandList({ + result, + }); + } + + resviceContextList(res) { + // 接受到的上下文列表 + console.log("resviceContextList res: ", res); + const result = res.payload.contexts.map((item) => ({ + name: item.command, + pattern: item.command, + description: item.description, + })); + console.log("resviceContextList result: ", result); + this.handle.regContextList({ result }); + } + + resviceModelList(response: any) { + console.log("resviceModelList response: ", response); + // 接受到模型列表 + this.handle["regModelList"]({ + result: response.payload.models, + }); + } + + resviceMessage(response: any) { + // 接受到消息 + if (response.metadata.isFinalChunk) { + // 结束对话 + this.handle["receiveMessage"]({ + text: response.payload.message || response.metadata.error, + isError: response.metadata.error.length > 0, + hash: response.payload.promptHash || "", + }); + } else { + this.handle["receiveMessagePartial"]({ + text: response.payload.message, + }); + } + } + + public static getInstance(): IdeaBridge { + if (!IdeaBridge.instance) { + IdeaBridge.instance = new IdeaBridge(); + } + return IdeaBridge.instance; + } + + registerHandler(messageType: string, handler: any) { + // 注册回调函数 + this.handle[messageType] = handler; + } + + sendMessage(message: any) { + // 根据 command 分发到不同的方法· + switch (message.command) { + // 发送消息 + case "sendMessage": + JStoIdea.sendMessage(message.text, message.context, message.parent); + break; + // 重新生成消息,用于发送失败时再次发送 + case "regeneration": + JStoIdea.sendMessage(message.text, message.context, message.parent); + break; + // 请求 model 列表 + case "regModelList": + JStoIdea.getModel(); + break; + case "regContextList": + JStoIdea.getContextList(); + break; + case "regCommandList": + JStoIdea.getCommandList(); + break; + case "code_apply": + JStoIdea.insertCode(message.content); + break; + case "code_file_apply": + JStoIdea.replaceFileContent(message.content); + break; + default: + break; + } + } +} + +export default IdeaBridge.getInstance();