From 8b43283566e1cb006b21d3f2f0b11448df3ef056 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 23 Aug 2023 19:53:55 +0800 Subject: [PATCH 1/2] Add 'help' command to DevChat - Added a new 'help' command to the command menu in InputStore.ts. - Modified the behavior of the 'Enter' and 'Tab' keys in InputMessage/index.tsx to display a help message when the 'help' command is selected. - Refactored ChatStore.ts to include a new 'helpMessage' function that displays a help message. - Removed redundant code in ChatStore.ts and reorganized the remaining code for better readability. --- src/views/components/InputMessage/index.tsx | 8 +- src/views/stores/ChatStore.ts | 314 ++++++++++---------- src/views/stores/InputStore.ts | 1 + 3 files changed, 169 insertions(+), 154 deletions(-) diff --git a/src/views/components/InputMessage/index.tsx b/src/views/components/InputMessage/index.tsx index 167c40a..b78fb21 100644 --- a/src/views/components/InputMessage/index.tsx +++ b/src/views/components/InputMessage/index.tsx @@ -83,7 +83,13 @@ const InputMessage = observer((props: any) => { } if ((event.key === 'Enter' || event.key === 'Tab') && !event.shiftKey) { const commandNode = commandMenusNode[currentMenuIndex]; - input.setValue(`/${commandNode.props['data-pattern']} `); + const commandPattern = commandNode.props['data-pattern']; + if (commandPattern === 'help') { + chat.helpMessage(); + input.setValue(''); + } else { + input.setValue(`/${commandPattern} `); + } input.closeMenu(); event.preventDefault(); } diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index eeba061..727d78d 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -75,150 +75,20 @@ export const ChatStore = types.model('Chat', { isTop: false, scrollBottom: 0 }) - .actions(self => ({ - startGenerating: (text: string, chatContexts) => { - self.generating = true; - self.responsed = false; - self.hasDone = false; - self.errorMessage = ''; - self.currentMessage = ''; - let lastNonEmptyHash; - for (let i = self.messages.length - 1; i >= 0; i--) { - if (self.messages[i].hash) { - lastNonEmptyHash = self.messages[i].hash; - break; - } - } - // Process and send the message to the extension - const contextInfo = chatContexts.map((item, index: number) => { - const { file, path, content, command } = item; - return { - file, - context: { - path: path, - command: command, - content: content, - } - }; - }); - messageUtil.sendMessage({ - command: 'sendMessage', - text: text, - contextInfo: contextInfo, - parent_hash: lastNonEmptyHash === 'message' ? null : lastNonEmptyHash - }); - }, - startSystemMessage: () => { - self.generating = true; - self.responsed = false; - self.hasDone = false; - self.errorMessage = ''; - self.currentMessage = ''; - }, - reGenerating: () => { - self.generating = true; - self.responsed = false; - self.hasDone = false; - self.errorMessage = ''; - self.currentMessage = ''; - self.messages.pop(); - messageUtil.sendMessage({ - command: 'regeneration' - }); - }, - stopGenerating: (hasDone: boolean, message: Instance | Instance) => { - self.generating = false; - self.responsed = false; - self.hasDone = hasDone; - if (hasDone) { - const { hash } = message ? message : { hash: '' }; - const messagesLength = self.messages.length; + .actions(self => { - if (messagesLength > 1) { - self.messages[messagesLength - 2].hash = hash; - self.messages[messagesLength - 1].hash = hash; - } else if (messagesLength > 0) { - self.messages[messagesLength - 1].hash = hash; - } - } - }, - startResponsing: (message: string) => { - self.responsed = true; - self.currentMessage = message; - }, - newMessage: (message: IMessage) => { - self.messages.push(message); - }, - addMessages: (messages: IMessage[]) => { - self.messages.push(...messages); - }, - updateLastMessage: (message: string) => { - if (self.messages.length > 0) { - self.messages[self.messages.length - 1].message = message; - } - }, - shiftMessage: () => { - self.messages.splice(0, 1); - }, - popMessage: () => { - self.messages.pop(); - }, - clearMessages: () => { - self.messages.length = 0; - }, - happendError: (errorMessage: string) => { - self.errorMessage = errorMessage; - }, - onMessagesTop: () => { - self.isTop = true; - self.isBottom = false; - }, - onMessagesBottom: () => { - self.isTop = false; - self.isBottom = true; - }, - onMessagesMiddle: () => { - self.isTop = false; - self.isBottom = false; - }, - goScrollBottom: () => { - self.scrollBottom++; - }, - fetchHistoryMessages: flow(function* (params: { pageIndex: number }) { - const { pageIndex, entries } = yield fetchHistoryMessages(params); - 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.push(...messages); - } else if (self.pageIndex > 0) { - self.messages.concat(...messages); - } - } else { - self.isLastPage = true; - if (self.messages.length === 0) { - self.messages.push( - Message.create({ - type: 'user', - message: "How do I use DevChat?" - })); - self.messages.push( - Message.create({ - type: 'bot', - message: ` + const helpMessage = (originalMessage = false) => { + self.messages.push( + Message.create({ + type: 'user', + message: originalMessage ? "How do I use DevChat?" : '/help' + })); + self.messages.push( + Message.create({ + type: 'bot', + message: ` Do you want to write some code or have a question about the project? Simply right-click on your chosen files or code snippets and add them to DevChat. Feel free to ask me anything or let me help you with coding. - + Don't forget to check out the "+" button on the left of the input to add more context. To see a list of workflows you can run in the context, just type "/". Happy prompting! To get started, here are the things that DevChat can do: @@ -226,18 +96,156 @@ To get started, here are the things that DevChat can do: [/ask_code: ask questions about your own codebase](#ask_code) - `})); + `})); + }; + + return { + helpMessage, + startGenerating: (text: string, chatContexts) => { + self.generating = true; + self.responsed = false; + self.hasDone = false; + self.errorMessage = ''; + self.currentMessage = ''; + let lastNonEmptyHash; + for (let i = self.messages.length - 1; i >= 0; i--) { + if (self.messages[i].hash) { + lastNonEmptyHash = self.messages[i].hash; + break; + } } - } - }), - deleteMessage: flow(function* (messageHash: string) { - const { hash } = yield deleteMessage(messageHash); - const index = self.messages.findIndex((item: any) => item.hash === hash); - if (index > -1) { - self.messages.splice(index); - } - }) - })); + // Process and send the message to the extension + const contextInfo = chatContexts.map((item, index: number) => { + const { file, path, content, command } = item; + return { + file, + context: { + path: path, + command: command, + content: content, + } + }; + }); + messageUtil.sendMessage({ + command: 'sendMessage', + text: text, + contextInfo: contextInfo, + parent_hash: lastNonEmptyHash === 'message' ? null : lastNonEmptyHash + }); + }, + startSystemMessage: () => { + self.generating = true; + self.responsed = false; + self.hasDone = false; + self.errorMessage = ''; + self.currentMessage = ''; + }, + reGenerating: () => { + self.generating = true; + self.responsed = false; + self.hasDone = false; + self.errorMessage = ''; + self.currentMessage = ''; + self.messages.pop(); + messageUtil.sendMessage({ + command: 'regeneration' + }); + }, + stopGenerating: (hasDone: boolean, message: Instance | Instance) => { + self.generating = false; + self.responsed = false; + self.hasDone = hasDone; + if (hasDone) { + const { hash } = message ? message : { hash: '' }; + const messagesLength = self.messages.length; + + if (messagesLength > 1) { + self.messages[messagesLength - 2].hash = hash; + self.messages[messagesLength - 1].hash = hash; + } else if (messagesLength > 0) { + self.messages[messagesLength - 1].hash = hash; + } + } + }, + startResponsing: (message: string) => { + self.responsed = true; + self.currentMessage = message; + }, + newMessage: (message: IMessage) => { + self.messages.push(message); + }, + addMessages: (messages: IMessage[]) => { + self.messages.push(...messages); + }, + updateLastMessage: (message: string) => { + if (self.messages.length > 0) { + self.messages[self.messages.length - 1].message = message; + } + }, + shiftMessage: () => { + self.messages.splice(0, 1); + }, + popMessage: () => { + self.messages.pop(); + }, + clearMessages: () => { + self.messages.length = 0; + }, + happendError: (errorMessage: string) => { + self.errorMessage = errorMessage; + }, + onMessagesTop: () => { + self.isTop = true; + self.isBottom = false; + }, + onMessagesBottom: () => { + self.isTop = false; + self.isBottom = true; + }, + onMessagesMiddle: () => { + self.isTop = false; + self.isBottom = false; + }, + goScrollBottom: () => { + self.scrollBottom++; + }, + fetchHistoryMessages: flow(function* (params: { pageIndex: number }) { + const { pageIndex, entries } = yield fetchHistoryMessages(params); + 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.push(...messages); + } else if (self.pageIndex > 0) { + self.messages.concat(...messages); + } + } else { + self.isLastPage = true; + if (self.messages.length === 0) { + helpMessage(true); + } + } + }), + deleteMessage: flow(function* (messageHash: string) { + const { hash } = yield deleteMessage(messageHash); + const index = self.messages.findIndex((item: any) => item.hash === hash); + if (index > -1) { + self.messages.splice(index); + } + }) + }; + }); export type IMessage = Instance; \ No newline at end of file diff --git a/src/views/stores/InputStore.ts b/src/views/stores/InputStore.ts index 51f9e13..07353f3 100644 --- a/src/views/stores/InputStore.ts +++ b/src/views/stores/InputStore.ts @@ -101,6 +101,7 @@ export const InputStore = types try { const items = yield regCommandMenus(); self.commandMenus.push(...items); + self.commandMenus.push({ name: 'help', description: 'View the DevChat documentation.', pattern: 'help' }); } catch (error) { console.error("Failed to fetch command menus", error); } From 8d777feeed411684aef047d7d40ebdc9a2bb7b95 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 23 Aug 2023 19:56:28 +0800 Subject: [PATCH 2/2] Revert "Remove unused features from initial bot message in ChatStore" This reverts commit be4888f54cb0623b254c44a47466fa8545bccd14. --- src/views/stores/ChatStore.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index 727d78d..a84275f 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -93,8 +93,16 @@ Don't forget to check out the "+" button on the left of the input to add more co To get started, here are the things that DevChat can do: +[/code: write code based on your prompt](#code) + +[/commit_message: write a commit message based on your code](#commit_message) + +[/release_note: write the release code based on your code](#release_note) + [/ask_code: ask questions about your own codebase](#ask_code) +[/extension: create extensions for DevChat](#extension) + `})); };