diff --git a/src/util/bridge.md b/src/util/bridge.md index b8b6e6c..78a9240 100644 --- a/src/util/bridge.md +++ b/src/util/bridge.md @@ -35,7 +35,7 @@ - contextDetailResponse // 获取到的文件内容 - loadHistoryMessages // 与 historyMessages 对应 - isDevChatInstalled // 与 isDevChatInstalled 对应 -- deletedChatMessage // 与 deleteChatMessage 对应· +- deletedChatMessage // 与 deleteChatMessage 对应 - regContextList // 与 regContextList 对应 - regModelList // 与 regModelList - receiveMessagePartial // 部分对话 @@ -63,3 +63,8 @@ --vscode-input-foreground --vscode-disabledForeground --vscode-toolbar-activeBackground + +1. 请求 loadHistoryMessages 根据全局 id 返回空/对应的消息 + 1.1. 参数只有分页 +2. 请求 loadConversations,用于切换全局的 id + 2.1 loadConversations 的响应里,请求 1 diff --git a/src/util/ideaBridge.ts b/src/util/ideaBridge.ts index 243d0ed..b8c0fb7 100644 --- a/src/util/ideaBridge.ts +++ b/src/util/ideaBridge.ts @@ -20,7 +20,7 @@ const JStoIdea = { message: message, }, }; - console.log("ready to call java send message", JSON.stringify(params)); + console.log("ready to send message: ", params); window.JSJavaBridge.callJava(JSON.stringify(params)); }, getModel: () => { @@ -52,7 +52,7 @@ const JStoIdea = { }, payload: {}, }; - console.log("reday to call java command list", JSON.stringify(params)); + window.JSJavaBridge.callJava(JSON.stringify(params)); }, insertCode: (code) => { @@ -95,8 +95,9 @@ const JStoIdea = { window.JSJavaBridge.callJava(JSON.stringify(params)); }, getUserAccessKey: () => { + // 这里需要发送一个请求,获取完整的用户设置 const params = { - action: "getKey/request", + action: "getSetting/request", metadata: { callback: "IdeaToJSMessage", }, @@ -114,10 +115,19 @@ const JStoIdea = { */ const content = Array.isArray(command.content) ? command.content[0] : ""; switch (content) { - case content.includes("workbench.action.openSettings"): + case "workbench.action.openSettings": // 打开设置 + const params = { + action: "showSettingDialog/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: {}, + }; + + window.JSJavaBridge.callJava(JSON.stringify(params)); break; - case content.includes("AccessKey.DevChat"): + case "AccessKey.DevChat": // 设置key break; default: @@ -165,14 +175,56 @@ const JStoIdea = { }, getTopicDetail: (topicHash: string) => { const params = { - action: "listConversations/request", + action: "loadConversations/request", metadata: { callback: "IdeaToJSMessage", topicHash: topicHash, }, payload: {}, }; - console.log("ready to call java getTopicDetail", params); + + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + historyMessages: (message) => { + const params = { + action: "loadHistoryMessages/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + pageIndex: message?.page || 0, + }, + }; + + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + deleteChatMessage: (message) => { + const params = { + action: "deleteLastConversation/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + promptHash: message?.hash || "", + }, + }; + + window.JSJavaBridge.callJava(JSON.stringify(params)); + }, + openLink: (message) => { + if (!message?.url) { + return false; + } + const params = { + action: "openLink/request", + metadata: { + callback: "IdeaToJSMessage", + }, + payload: { + url: message?.url || "", + }, + }; + window.JSJavaBridge.callJava(JSON.stringify(params)); }, }; @@ -185,8 +237,14 @@ class IdeaBridge { this.handle = {}; // 注册全局的回调函数,用于接收来自IDEA的消息 window.IdeaToJSMessage = (res: any) => { - console.log("IdeaToJSMessage res: ", res); + console.log("IdeaToJSMessage: ", res); switch (res.action) { + case "deleteLastConversation/response": + this.resviceDeleteMessage(res); + break; + case "loadHistoryMessages/response": + this.resviceHistoryMessages(res); + break; case "sendMessage/response": this.resviceMessage(res); break; @@ -213,7 +271,7 @@ class IdeaBridge { case "listTopics/response": this.resviceTopicList(res); break; - case "listConversations/response": + case "loadConversations/response": this.resviceTopicDetail(res); break; default: @@ -222,19 +280,39 @@ class IdeaBridge { }; } - resviceTopicDetail(res) { - // 接收到这里需要触发 loadHistoryMessages - const list = res.payload.conversations.map((item) => ({ - ...item, - response: item.responses.join("\n"), - })); - this.handle.loadHistoryMessages({ - entries: list, + resviceDeleteMessage(res) { + const hash = res?.payload?.promptHash || ""; + this.handle.deletedChatMessage({ + hash, }); } + resviceHistoryMessages(res) { + const list: any = []; + if (res?.payload?.messages?.length > 0) { + res?.payload?.messages.forEach((item) => { + list.push({ + ...item, + response: item.responses?.join("\n"), + }); + }); + } + + this.handle.reloadMessage({ + entries: list.reverse(), + pageIndex: 0, + }); + } + + resviceTopicDetail(res) { + // 用于重置后端全局的 topic id + if (res?.payload?.reset) { + // 重置后请求历史消息 + JStoIdea.historyMessages({ page: 0 }); + } + } + resviceTopicList(res) { - console.log("resviceTopicList res: ", res); const list = res.payload.topics; this.handle.listTopics(list); } @@ -256,6 +334,7 @@ class IdeaBridge { resviceSettings(res) { // 用户设置的回调 const setting = res.payload.setting; + // 当前的默认模型 this.handle.getSetting({ value: setting.currentModel, @@ -307,17 +386,21 @@ class IdeaBridge { } resviceMessage(response: any) { + console.log( + "response.metadata.isFinalChunk: ", + response.metadata.isFinalChunk + ); // 接受到消息 - if (response.metadata.isFinalChunk) { + if (response.metadata?.isFinalChunk) { // 结束对话 this.handle["receiveMessage"]({ - text: response.payload.message || response.metadata.error, - isError: response.metadata.error.length > 0, - hash: response.payload.promptHash || "", + 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, + text: response?.payload?.message || "", }); } } @@ -335,13 +418,15 @@ class IdeaBridge { } sendMessage(message: any) { - console.log("sendMessage message: ", message); // 根据 command 分发到不同的方法· switch (message.command) { // 发送消息 case "sendMessage": - console.log("message: ", message); - JStoIdea.sendMessage(message.text, message.contextInfo, message.parent); + JStoIdea.sendMessage( + message.text, + message.contextInfo, + message.parent_hash + ); break; // 重新生成消息,用于发送失败时再次发送 case "regeneration": @@ -384,6 +469,15 @@ class IdeaBridge { case "getTopicDetail": JStoIdea.getTopicDetail(message.topicHash); break; + case "historyMessages": + JStoIdea.historyMessages(message); + break; + case "deleteChatMessage": + JStoIdea.deleteChatMessage(message); + break; + case "openLink": + JStoIdea.openLink(message); + break; default: break; } diff --git a/src/views/components/BalanceTip/index.tsx b/src/views/components/BalanceTip/index.tsx index be77ef5..32ff195 100644 --- a/src/views/components/BalanceTip/index.tsx +++ b/src/views/components/BalanceTip/index.tsx @@ -42,6 +42,7 @@ export default function WechatTip() { const [accessKey, setAccessKey] = useState(""); const [env, setEnv] = useState("prod"); const [loading, setLoading] = useState(false); + const platform = process.env.platform; const getSettings = () => { messageUtil.sendMessage({ @@ -95,6 +96,15 @@ export default function WechatTip() { ); }, []); + const openLink = (e) => { + e.preventDefault(); + e.stopPropagation(); + messageUtil.sendMessage({ + command: "openLink", + url: envMap[env].link, + }); + }; + if (balance === null || balance === undefined) { return null; } @@ -105,6 +115,11 @@ export default function WechatTip() { position="left" width="200" withArrow={true} + styles={{ + arrow: { + borderColor: "var(--vscode-menu-border)", + }, + }} zIndex={999} > @@ -116,16 +131,25 @@ export default function WechatTip() { Your remaining credit is {formatCurrency(balance, currency)}. Sign - in to web.devchat.ai to{" "} - {bindWechat ? "purchase more tokens." : "earn additional ¥8"} + in to{" "} + {platform === "idea" ? ( + openLink(e)}> + web.devchat.ai{" "} + + ) : ( + + web.devchat.ai{" "} + + )} + to {bindWechat ? "purchase more tokens." : "earn additional ¥8"} diff --git a/src/views/components/InputMessage/Topic.tsx b/src/views/components/InputMessage/Topic.tsx index 11f98b5..2beac6e 100644 --- a/src/views/components/InputMessage/Topic.tsx +++ b/src/views/components/InputMessage/Topic.tsx @@ -6,21 +6,20 @@ import messageUtil from "@/util/MessageUtil"; import dayjs from "dayjs"; export default function Topic({ styleName }) { + const [drawerOpened, { open: openDrawer, close: closeDrawer }] = + useDisclosure(false); const [topicList, setTopicList] = useState([]); + useEffect(() => { messageUtil.sendMessage({ command: "listTopics", }); messageUtil.registerHandler("listTopics", (data) => { - console.log("listTopics data: ", data); setTopicList(data); }); }, []); - const [drawerOpened, { open: openDrawer, close: closeDrawer }] = - useDisclosure(false); const showTopic = (root_prompt: any) => { - console.log("root_prompt: ", root_prompt); closeDrawer(); messageUtil.sendMessage({ command: "getTopicDetail", @@ -56,12 +55,29 @@ export default function Topic({ styleName }) { }} onClick={() => showTopic(item?.root_prompt)} > - - - {item?.root_prompt.request} + + + {item?.root_prompt.title} - - {dayjs(item?.latest_time * 1000).format("YYYY-MM-DD HH:mm:ss")} + + {dayjs(item?.latest_time * 1000).format("MM-DD HH:mm:ss")} diff --git a/src/views/pages/ChatPanel.tsx b/src/views/pages/ChatPanel.tsx index eba1d29..e9a8466 100644 --- a/src/views/pages/ChatPanel.tsx +++ b/src/views/pages/ChatPanel.tsx @@ -85,6 +85,9 @@ const chatPanel = observer(() => { getSettings(); getFeatureToggles(); chat.fetchHistoryMessages({ pageIndex: 0 }).then(); + messageUtil.registerHandler('reloadMessage',(message:any)=>{ + chat.reloadMessage(message); + }); messageUtil.registerHandler( "receiveMessagePartial", (message: { text: string }) => { diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index 8f4cca9..f46fbe5 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -332,6 +332,33 @@ ${yaml.dump(values)} self.isTop = false; self.isBottom = false; }, + reloadMessage:({entries,pageIndex})=>{ + if (entries.length > 0) { + self.pageIndex = pageIndex; + const messages = entries + .map((entry, index) => { + const { hash, user, date, request, response, context } = entry; + const chatContexts = context?.map(({ content }) => { + return JSON.parse(content); + }); + return [ + { type: 'user', message: request, contexts: chatContexts, date: date, hash: hash }, + { type: 'bot', message: response, date: date, hash: hash }, + ]; + }) + .flat(); + if (self.pageIndex === 0) { + self.messages = messages; + } else if (self.pageIndex > 0) { + self.messages.concat(...messages); + } + } else { + self.isLastPage = true; + if (self.messages.length === 0) { + helpMessage(true); + } + } + }, fetchHistoryMessages: flow(function* (params: { pageIndex: number }) { const { pageIndex, entries } = yield fetchHistoryMessages(params); if (entries.length > 0) {