From c8058af1d5c2f102c0241636522bcde882a16fb7 Mon Sep 17 00:00:00 2001 From: Amnish Date: Thu, 1 Feb 2024 16:48:37 -0500 Subject: [PATCH 1/4] Add a command to show list of supported commands --- src/Chat/ChatBase.tsx | 17 +++++++----- src/components/Message/AppMessage/Help.tsx | 30 ++++++++++++++++++--- src/components/Message/AppMessage/index.tsx | 13 +++++++++ src/lib/ChatCraftMessage.ts | 8 ++++++ src/lib/commands/CommandsHelpCommand.ts | 13 +++++++++ src/lib/commands/index.ts | 2 ++ 6 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 src/lib/commands/CommandsHelpCommand.ts diff --git a/src/Chat/ChatBase.tsx b/src/Chat/ChatBase.tsx index dc3bcc52..b9230da2 100644 --- a/src/Chat/ChatBase.tsx +++ b/src/Chat/ChatBase.tsx @@ -168,14 +168,19 @@ function ChatBase({ chat }: ChatBaseProps) { }); } } else { - error({ - title: `Unknown Command`, - message: `Command not recognized. Use /help to get help on valid commands.`, - }); - - console.log("TODO: show help"); // The input was a command, but not a recognized one. // Handle this case as appropriate for your application. + const commandFunction = ChatCraftCommandRegistry.getCommand("/commands")!; + setShouldAutoScroll(true); + try { + await commandFunction(chat, user); + forceScroll(); + } catch (err: any) { + error({ + title: `Unknown Command`, + message: `Command not recognized. Use /help to get help on valid commands.`, + }); + } } setLoading(false); diff --git a/src/components/Message/AppMessage/Help.tsx b/src/components/Message/AppMessage/Help.tsx index 509d7fb5..9038326c 100644 --- a/src/components/Message/AppMessage/Help.tsx +++ b/src/components/Message/AppMessage/Help.tsx @@ -57,7 +57,7 @@ through documentation. > \`\`\` > ...function... > \`\`\` -> +> > \`\`\` > ...text of error message > \`\`\` @@ -80,7 +80,7 @@ function greeting(name: string) { \`\`\` You can also use [headings](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#headings), [lists](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#lists), [tables](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables#creating-a-table), [links](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#links), -etc. to create more readable text. +etc. to create more readable text. ## Commands @@ -133,9 +133,31 @@ have an idea for a feature, or think you've found a bug, get in touch with us: - [Discord](https://discord.gg/PE2GWHnR) `; -function Help(props: MessageBaseProps) { +const commandsHelpText = `## Commands + +You can use "slash" commands to help accomplish various tasks. Any prompt that begins +with a "/" (e.g., "/help") will be interpreted as a command that ChatCraft should run. +Some commands accept arguments as well. + +| Command | Description | +|-----|------| +| /help | Shows this help message. | +| /commands | Shows a list of **supported commands** in ChatCraft | +| /new | Creates a new chat. | +| /clear | Erases all messages in the current chat. | +| /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). | +| /import  | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. |`; + +interface HelpMessageProps extends MessageBaseProps { + onlyCommands?: boolean; +} + +function Help(props: HelpMessageProps) { // Override the text of the message - const message = new ChatCraftAppMessage({ ...props.message, text: helpText }); + const message = new ChatCraftAppMessage({ + ...props.message, + text: props.onlyCommands ? commandsHelpText : helpText, + }); return ; } diff --git a/src/components/Message/AppMessage/index.tsx b/src/components/Message/AppMessage/index.tsx index d211b86f..b69352bf 100644 --- a/src/components/Message/AppMessage/index.tsx +++ b/src/components/Message/AppMessage/index.tsx @@ -41,6 +41,19 @@ function AppMessage(props: AppMessageProps) { ); } + if (ChatCraftAppMessage.isCommandsHelp(message)) { + return ( + + ); + } + // Otherwise, use a basic message type and show the text return ( Date: Fri, 2 Feb 2024 12:42:12 -0500 Subject: [PATCH 2/4] Display a toast message indicating the incorrect command --- src/Chat/ChatBase.tsx | 8 ++++++-- src/components/Message/AppMessage/Help.tsx | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Chat/ChatBase.tsx b/src/Chat/ChatBase.tsx index b9230da2..31f23a1e 100644 --- a/src/Chat/ChatBase.tsx +++ b/src/Chat/ChatBase.tsx @@ -173,12 +173,16 @@ function ChatBase({ chat }: ChatBaseProps) { const commandFunction = ChatCraftCommandRegistry.getCommand("/commands")!; setShouldAutoScroll(true); try { + error({ + title: `Unknown Command`, + message: `Command '${prompt}' not recognized. Please refer to the list of supported commands.`, + }); await commandFunction(chat, user); forceScroll(); } catch (err: any) { error({ - title: `Unknown Command`, - message: `Command not recognized. Use /help to get help on valid commands.`, + title: `Error Running Command`, + message: `There was an error running the command: ${err.message}.`, }); } } diff --git a/src/components/Message/AppMessage/Help.tsx b/src/components/Message/AppMessage/Help.tsx index 9038326c..859517ff 100644 --- a/src/components/Message/AppMessage/Help.tsx +++ b/src/components/Message/AppMessage/Help.tsx @@ -91,6 +91,7 @@ Some commands accept arguments as well. | Command | Description | |-----|------| | /help | Shows this help message. | +| /commands | Shows a list of **supported commands** in ChatCraft | | /new | Creates a new chat. | | /clear | Erases all messages in the current chat. | | /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). | From 84273dc1c06df6ac733f3607d9ee97c1528a778d Mon Sep 17 00:00:00 2001 From: Amnish Date: Fri, 2 Feb 2024 17:55:02 -0500 Subject: [PATCH 3/4] Single source of truth for commands help text --- src/components/Message/AppMessage/Help.tsx | 45 ++++++++-------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/src/components/Message/AppMessage/Help.tsx b/src/components/Message/AppMessage/Help.tsx index 859517ff..979d8be1 100644 --- a/src/components/Message/AppMessage/Help.tsx +++ b/src/components/Message/AppMessage/Help.tsx @@ -3,6 +3,21 @@ import { memo } from "react"; import MessageBase, { type MessageBaseProps } from "../MessageBase"; import { ChatCraftAppMessage } from "../../../lib/ChatCraftMessage"; +const commandsHelpText = `## Commands + +You can use "slash" commands to help accomplish various tasks. Any prompt that begins +with a "/" (e.g., "/help") will be interpreted as a command that ChatCraft should run. +Some commands accept arguments as well. + +| Command | Description | +|-----|------| +| /help | Shows this help message. | +| /commands | Shows a list of **supported commands** in ChatCraft | +| /new | Creates a new chat. | +| /clear | Erases all messages in the current chat. | +| /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). | +| /import  | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. |`; + const helpText = `## ChatCraft.org Help ChatCraft.org lets you chat with large language models (LLM) from various vendors and @@ -82,20 +97,7 @@ function greeting(name: string) { You can also use [headings](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#headings), [lists](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#lists), [tables](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-tables#creating-a-table), [links](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#links), etc. to create more readable text. -## Commands - -You can use "slash" commands to help accomplish various tasks. Any prompt that begins -with a "/" (e.g., "/help") will be interpreted as a command that ChatCraft should run. -Some commands accept arguments as well. - -| Command | Description | -|-----|------| -| /help | Shows this help message. | -| /commands | Shows a list of **supported commands** in ChatCraft | -| /new | Creates a new chat. | -| /clear | Erases all messages in the current chat. | -| /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). | -| /import  | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. | +${commandsHelpText} ## Functions @@ -134,21 +136,6 @@ have an idea for a feature, or think you've found a bug, get in touch with us: - [Discord](https://discord.gg/PE2GWHnR) `; -const commandsHelpText = `## Commands - -You can use "slash" commands to help accomplish various tasks. Any prompt that begins -with a "/" (e.g., "/help") will be interpreted as a command that ChatCraft should run. -Some commands accept arguments as well. - -| Command | Description | -|-----|------| -| /help | Shows this help message. | -| /commands | Shows a list of **supported commands** in ChatCraft | -| /new | Creates a new chat. | -| /clear | Erases all messages in the current chat. | -| /summary [max-length] | Uses ChatGPT to create a summary of the current chat. Optionally takes a maximum word length (defaults to 500). | -| /import  | Loads the provided URL and imports the text. Where possible, ChatCraft will try to get raw text vs. HTML from sites like GitHub. NOTE: to prevent abuse, you must be logged into use the import command. |`; - interface HelpMessageProps extends MessageBaseProps { onlyCommands?: boolean; } From 8a8d1ae84cf0a4475fb68819eef90a187182283e Mon Sep 17 00:00:00 2001 From: Amnish Date: Wed, 7 Feb 2024 00:28:40 -0500 Subject: [PATCH 4/4] Show the invalid command inline with commands help text --- src/Chat/ChatBase.tsx | 11 ++++++----- src/components/Message/AppMessage/Help.tsx | 16 +++++++++++++++- src/components/Message/AppMessage/index.tsx | 2 ++ src/lib/ChatCraftMessage.ts | 2 +- src/lib/commands/CommandsHelpCommand.ts | 10 ++++++++-- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/Chat/ChatBase.tsx b/src/Chat/ChatBase.tsx index 31f23a1e..5bb04235 100644 --- a/src/Chat/ChatBase.tsx +++ b/src/Chat/ChatBase.tsx @@ -23,6 +23,7 @@ import { ChatCraftFunction } from "../lib/ChatCraftFunction"; import { useAutoScroll } from "../hooks/use-autoscroll"; import { useAlert } from "../hooks/use-alert"; import { ChatCraftCommandRegistry } from "../lib/commands"; +import { ChatCraftCommand } from "../lib/ChatCraftCommand"; type ChatBaseProps = { chat: ChatCraftChat; @@ -170,13 +171,13 @@ function ChatBase({ chat }: ChatBaseProps) { } else { // The input was a command, but not a recognized one. // Handle this case as appropriate for your application. - const commandFunction = ChatCraftCommandRegistry.getCommand("/commands")!; + + // We are sure that this won't return null + // since prompt is definitely a command + const { command } = ChatCraftCommand.parseCommand(prompt)!; + const commandFunction = ChatCraftCommandRegistry.getCommand(`/commands ${command}`)!; setShouldAutoScroll(true); try { - error({ - title: `Unknown Command`, - message: `Command '${prompt}' not recognized. Please refer to the list of supported commands.`, - }); await commandFunction(chat, user); forceScroll(); } catch (err: any) { diff --git a/src/components/Message/AppMessage/Help.tsx b/src/components/Message/AppMessage/Help.tsx index 979d8be1..e71edcc8 100644 --- a/src/components/Message/AppMessage/Help.tsx +++ b/src/components/Message/AppMessage/Help.tsx @@ -2,6 +2,7 @@ import { memo } from "react"; import MessageBase, { type MessageBaseProps } from "../MessageBase"; import { ChatCraftAppMessage } from "../../../lib/ChatCraftMessage"; +import { ChatCraftCommand } from "../../../lib/ChatCraftCommand"; const commandsHelpText = `## Commands @@ -138,13 +139,26 @@ have an idea for a feature, or think you've found a bug, get in touch with us: interface HelpMessageProps extends MessageBaseProps { onlyCommands?: boolean; + // This property can be used to report the + // closest matching command in the future + queriedCommand?: string; } function Help(props: HelpMessageProps) { // Override the text of the message + const isQueriedCommandValid = + props.onlyCommands && props.queriedCommand && ChatCraftCommand.isCommand(props.queriedCommand); + + const messageText = + props.onlyCommands && props.queriedCommand?.length && !isQueriedCommandValid + ? `**"${props.queriedCommand}" is not a valid command!**\n\n${commandsHelpText}` + : props.onlyCommands + ? commandsHelpText + : helpText; + const message = new ChatCraftAppMessage({ ...props.message, - text: props.onlyCommands ? commandsHelpText : helpText, + text: messageText, }); return ; diff --git a/src/components/Message/AppMessage/index.tsx b/src/components/Message/AppMessage/index.tsx index b69352bf..f4ea0200 100644 --- a/src/components/Message/AppMessage/index.tsx +++ b/src/components/Message/AppMessage/index.tsx @@ -5,6 +5,7 @@ import MessageBase, { type MessageBaseProps } from "../MessageBase"; import { ChatCraftAppMessage } from "../../../lib/ChatCraftMessage"; import Instructions from "./Instructions"; import Help from "./Help"; +import { CommandsHelpCommand } from "../../../lib/commands/CommandsHelpCommand"; type AppMessageProps = Omit; @@ -46,6 +47,7 @@ function AppMessage(props: AppMessageProps) {