394 lines
9.8 KiB
TypeScript
Raw Normal View History

2023-11-20 16:40:11 +08:00
const JStoIdea = {
2023-12-03 18:47:50 +08:00
sendMessage: (message: string, context: any = [], parent: string = "") => {
const paramsContext: any = [];
if (Array.isArray(context) && context.length > 0) {
context.forEach((item) => {
paramsContext.push({
type: "code",
...item.context,
});
});
}
2023-11-20 16:40:11 +08:00
const params = {
action: "sendMessage/request",
metadata: {
callback: "IdeaToJSMessage",
parent: parent,
},
payload: {
2023-12-03 18:47:50 +08:00
contexts: paramsContext,
2023-11-20 16:40:11 +08:00
message: message,
},
};
2023-12-03 18:47:50 +08:00
console.log("ready to call java send message", JSON.stringify(params));
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
getModel: () => {
const params = {
action: "listModels/request",
metadata: {
callback: "IdeaToJSMessage",
},
2023-12-03 18:47:50 +08:00
payload: {},
2023-11-20 16:40:11 +08:00
};
window.JSJavaBridge.callJava(JSON.stringify(params));
},
getContextList: () => {
const params = {
action: "listContexts/request",
metadata: {
callback: "IdeaToJSMessage",
},
2023-12-03 18:47:50 +08:00
payload: {},
2023-11-20 16:40:11 +08:00
};
2023-11-20 18:45:32 +08:00
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
getCommandList: () => {
const params = {
action: "listCommands/request",
metadata: {
callback: "IdeaToJSMessage",
},
2023-12-03 18:47:50 +08:00
payload: {},
2023-11-20 16:40:11 +08:00
};
2023-12-03 18:47:50 +08:00
console.log("reday to call java command list", JSON.stringify(params));
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
insertCode: (code) => {
const params = {
action: "insertCode/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {
content: code,
},
};
2023-11-20 18:45:32 +08:00
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
replaceFileContent: (code) => {
const params = {
action: "replaceFileContent/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {
content: code,
},
};
2023-11-20 18:45:32 +08:00
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
viewDiff: (code) => {
const params = {
action: "viewDiff/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {
content: code,
},
};
2023-12-03 18:47:50 +08:00
2023-11-20 16:40:11 +08:00
window.JSJavaBridge.callJava(JSON.stringify(params));
},
2023-11-20 18:45:32 +08:00
getUserAccessKey: () => {
const params = {
action: "getKey/request",
metadata: {
callback: "IdeaToJSMessage",
},
2023-12-03 18:47:50 +08:00
payload: {},
2023-11-20 18:45:32 +08:00
};
window.JSJavaBridge.callJava(JSON.stringify(params));
},
etcCommand: (command: any) => {
/**
*
* 1. workbench.action.openSettings
* 2. AskCodeIndexStart
* 3. AccessKey.OpenAI
* 4. AccessKey.DevChat
*/
const content = Array.isArray(command.content) ? command.content[0] : "";
switch (content) {
case content.includes("workbench.action.openSettings"):
// 打开设置
break;
case content.includes("AccessKey.DevChat"):
// 设置key
break;
default:
break;
}
},
2023-12-03 18:47:50 +08:00
getTopicList: () => {
// 获取 topic 列表
const params = {
action: "listTopics/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {},
};
window.JSJavaBridge.callJava(JSON.stringify(params));
},
2023-11-23 14:42:15 +08:00
updateSetting: (value: string) => {
// 因为现在只有更换模型,所以直接取 value
const params = {
action: "updateSetting/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {
setting: {
currentModel: value,
},
},
};
window.JSJavaBridge.callJava(JSON.stringify(params));
},
commit: (code: string) => {
const params = {
action: "commitCode/request",
metadata: {
callback: "IdeaToJSMessage",
},
payload: {
message: code,
},
};
window.JSJavaBridge.callJava(JSON.stringify(params));
},
2023-12-03 18:47:50 +08:00
getTopicDetail: (topicHash: string) => {
const params = {
action: "listConversations/request",
metadata: {
callback: "IdeaToJSMessage",
topicHash: topicHash,
},
payload: {},
};
console.log("ready to call java getTopicDetail", params);
window.JSJavaBridge.callJava(JSON.stringify(params));
},
2023-11-20 16:40:11 +08:00
};
class IdeaBridge {
private static instance: IdeaBridge;
handle: any = {};
constructor() {
this.handle = {};
// 注册全局的回调函数用于接收来自IDEA的消息
window.IdeaToJSMessage = (res: any) => {
2023-11-23 14:42:15 +08:00
console.log("IdeaToJSMessage res: ", res);
2023-11-20 16:40:11 +08:00
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;
2023-11-23 14:42:15 +08:00
// 这里暂时不用,因为获取到的只有 key信息不全
// 所以用 resviceSettings 来获取
// case "getKey/response":
// this.resviceAccessKey(res.payload.key);
// break;
case "addContext/notify":
this.resviesContext(res);
break;
case "getSetting/response":
this.resviceSettings(res);
2023-11-20 18:45:32 +08:00
break;
2023-12-03 18:47:50 +08:00
case "listTopics/response":
this.resviceTopicList(res);
break;
case "listConversations/response":
this.resviceTopicDetail(res);
break;
2023-11-20 16:40:11 +08:00
default:
break;
}
};
}
2023-12-03 18:47:50 +08:00
resviceTopicDetail(res) {
// 接收到这里需要触发 loadHistoryMessages
const list = res.payload.conversations.map((item) => ({
...item,
response: item.responses.join("\n"),
}));
this.handle.loadHistoryMessages({
entries: list,
});
}
resviceTopicList(res) {
console.log("resviceTopicList res: ", res);
const list = res.payload.topics;
this.handle.listTopics(list);
}
2023-11-23 14:42:15 +08:00
resviesContext(res) {
const params = {
file: res.payload.path,
result: "",
};
const contextObj = {
path: res.payload.path,
content: res.payload.content,
command: "",
};
params.result = JSON.stringify(contextObj);
this.handle.contextDetailResponse(params);
}
resviceSettings(res) {
// 用户设置的回调
const setting = res.payload.setting;
// 当前的默认模型
this.handle.getSetting({
value: setting.currentModel,
});
this.handle.getUserAccessKey({
endPoint: setting.apiBase,
accessKey: setting.apiKey,
keyType: setting.apiKey.startsWith("DC") ? "DevChat" : "OpenAi",
});
}
2023-11-20 18:45:32 +08:00
resviceAccessKey(res: string = "") {
const params = {
endPoint: "",
accessKey: res,
keyType: res.startsWith("DC") ? "DevChat" : "OpenAi",
};
this.handle.getUserAccessKey(params);
}
2023-11-20 16:40:11 +08:00
resviceCommandList(res) {
const result = res.payload.commands.map((item) => ({
name: item.name,
pattern: item.name,
description: item.description,
}));
this.handle.regCommandList({
result,
});
}
resviceContextList(res) {
// 接受到的上下文列表
2023-11-20 18:45:32 +08:00
2023-11-20 16:40:11 +08:00
const result = res.payload.contexts.map((item) => ({
name: item.command,
pattern: item.command,
description: item.description,
}));
2023-11-20 18:45:32 +08:00
2023-11-20 16:40:11 +08:00
this.handle.regContextList({ result });
}
resviceModelList(response: any) {
// 接受到模型列表
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) {
2023-12-03 18:47:50 +08:00
console.log("sendMessage message: ", message);
2023-11-20 16:40:11 +08:00
// 根据 command 分发到不同的方法·
switch (message.command) {
// 发送消息
case "sendMessage":
2023-12-03 18:47:50 +08:00
console.log("message: ", message);
JStoIdea.sendMessage(message.text, message.contextInfo, message.parent);
2023-11-20 16:40:11 +08:00
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;
2023-11-20 18:45:32 +08:00
case "getUserAccessKey":
JStoIdea.getUserAccessKey();
break;
case "doCommand":
JStoIdea.etcCommand(message);
break;
2023-11-23 14:42:15 +08:00
case "show_diff":
JStoIdea.viewDiff(message.content);
break;
case "updateSetting":
JStoIdea.updateSetting(message.value);
break;
case "doCommit":
JStoIdea.commit(message.content);
break;
2023-12-03 18:47:50 +08:00
case "listTopics":
JStoIdea.getTopicList();
break;
case "getTopicDetail":
JStoIdea.getTopicDetail(message.topicHash);
break;
2023-11-20 16:40:11 +08:00
default:
break;
}
}
}
export default IdeaBridge.getInstance();