diff options
Diffstat (limited to 'extension/react-app/src')
| -rw-r--r-- | extension/react-app/src/components/CodeBlock.tsx | 1 | ||||
| -rw-r--r-- | extension/react-app/src/components/StepContainer.tsx | 67 | ||||
| -rw-r--r-- | extension/react-app/src/components/index.ts | 18 | ||||
| -rw-r--r-- | extension/react-app/src/hooks/ContinueGUIClientProtocol.ts | 6 | ||||
| -rw-r--r-- | extension/react-app/src/hooks/useContinueGUIProtocol.ts | 8 | ||||
| -rw-r--r-- | extension/react-app/src/tabs/chat/MessageDiv.tsx | 4 | ||||
| -rw-r--r-- | extension/react-app/src/tabs/gui.tsx | 286 | 
7 files changed, 239 insertions, 151 deletions
| diff --git a/extension/react-app/src/components/CodeBlock.tsx b/extension/react-app/src/components/CodeBlock.tsx index e0336554..eedae3fb 100644 --- a/extension/react-app/src/components/CodeBlock.tsx +++ b/extension/react-app/src/components/CodeBlock.tsx @@ -11,6 +11,7 @@ const StyledPre = styled.pre`    border: 1px solid gray;    border-radius: ${defaultBorderRadius};    background-color: ${vscBackground}; +  padding: 8px;  `;  const StyledCode = styled.code` diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 3408053b..ca142b06 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -7,6 +7,7 @@ import {    vscBackground,    GradientBorder,    vscBackgroundTransparent, +  HeaderButton,  } from ".";  import { RangeInFile, FileEdit } from "../../../src/client";  import CodeBlock from "./CodeBlock"; @@ -15,7 +16,7 @@ import SubContainer from "./SubContainer";  import {    ChevronDown,    ChevronRight, -  Backward, +  XMark,    ArrowPath,  } from "@styled-icons/heroicons-outline";  import { HistoryNode } from "../../../schema/HistoryNode"; @@ -31,6 +32,7 @@ interface StepContainerProps {    onRefinement: (input: string) => void;    onUserInput: (input: string) => void;    onRetry: () => void; +  onDelete: () => void;    open?: boolean;  } @@ -54,8 +56,10 @@ const HeaderDiv = styled.div<{ error: boolean }>`    background-color: ${(props) =>      props.error ? "#522" : vscBackgroundTransparent};    display: grid; -  grid-template-columns: 1fr auto; +  grid-template-columns: 1fr auto auto; +  grid-gap: 8px;    align-items: center; +  padding-right: 8px;  `;  const ContentDiv = styled.div` @@ -64,26 +68,21 @@ const ContentDiv = styled.div`    background-color: ${vscBackground};  `; -const HeaderButton = styled.button` -  background-color: transparent; -  border: 1px solid white; -  border-radius: ${defaultBorderRadius}; -  padding: 2px; -  cursor: pointer; -  color: white; - -  &:hover { -    background-color: white; -    color: black; -  } -`; -  const OnHoverDiv = styled.div`    text-align: center;    padding: 10px;    animation: ${appear} 0.3s ease-in-out;  `; +const MarkdownPre = styled.pre` +  background-color: ${secondaryDark}; +  padding: 10px; +  border-radius: ${defaultBorderRadius}; +  border: 0.5px solid white; +`; + +const MarkdownCode = styled.code``; +  function StepContainer(props: StepContainerProps) {    const [open, setOpen] = useState(      typeof props.open === "undefined" ? true : props.open @@ -152,18 +151,28 @@ function StepContainer(props: StepContainerProps) {                <Backward size="1.6em" onClick={props.onReverse}></Backward>              </HeaderButton> */} -            {props.historyNode.observation?.error ? ( +            <>                <HeaderButton                  onClick={(e) => {                    e.stopPropagation(); -                  props.onRetry(); +                  props.onDelete();                  }}                > -                <ArrowPath size="1.6em" onClick={props.onRetry}></ArrowPath> +                <XMark size="1.6em" onClick={props.onDelete} />                </HeaderButton> -            ) : ( -              <></> -            )} +              {props.historyNode.observation?.error ? ( +                <HeaderButton +                  onClick={(e) => { +                    e.stopPropagation(); +                    props.onRetry(); +                  }} +                > +                  <ArrowPath size="1.6em" onClick={props.onRetry} /> +                </HeaderButton> +              ) : ( +                <></> +              )} +            </>            </HeaderDiv>          </GradientBorder>          <ContentDiv hidden={!open}> @@ -182,7 +191,19 @@ function StepContainer(props: StepContainerProps) {                {props.historyNode.observation.error as string}              </pre>            ) : ( -            <ReactMarkdown key={1} className="overflow-scroll"> +            <ReactMarkdown +              key={1} +              className="overflow-scroll" +              components={{ +                pre: ({ node, ...props }) => { +                  return ( +                    <CodeBlock +                      children={props.children[0] as string} +                    ></CodeBlock> +                  ); +                }, +              }} +            >                {props.historyNode.step.description as any}              </ReactMarkdown>            )} diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts index 4966f3e8..525989af 100644 --- a/extension/react-app/src/components/index.ts +++ b/extension/react-app/src/components/index.ts @@ -143,3 +143,21 @@ export const appear = keyframes`          transform: translateY(0px);      }  `; + +export const HeaderButton = styled.button` +  background-color: transparent; +  border: 1px solid white; +  border-radius: ${defaultBorderRadius}; +  cursor: pointer; +  color: white; + +  &:hover { +    background-color: white; +    color: black; +  } +  display: flex; +  align-items: center; +  justify-content: center; +  gap: 4px; +  padding: 1px; +`; diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts index 18a91de7..71303c70 100644 --- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts +++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts @@ -8,6 +8,12 @@ abstract class AbstractContinueGUIClientProtocol {    abstract sendStepUserInput(input: string, index: number): void;    abstract onStateUpdate(state: any): void; + +  abstract sendClear(): void; + +  abstract retryAtIndex(index: number): void; + +  abstract deleteAtIndex(index: number): void;  }  export default AbstractContinueGUIClientProtocol; diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts index f27895fb..a8e28fc5 100644 --- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts +++ b/extension/react-app/src/hooks/useContinueGUIProtocol.ts @@ -45,9 +45,17 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {      });    } +  sendClear() { +    this.messenger.send("clear_history", {}); +  } +    retryAtIndex(index: number) {      this.messenger.send("retry_at_index", { index });    } + +  deleteAtIndex(index: number) { +    this.messenger.send("delete_at_index", { index }); +  }  }  export default ContinueGUIClientProtocol; diff --git a/extension/react-app/src/tabs/chat/MessageDiv.tsx b/extension/react-app/src/tabs/chat/MessageDiv.tsx index 1d7bb5f5..3543dd93 100644 --- a/extension/react-app/src/tabs/chat/MessageDiv.tsx +++ b/extension/react-app/src/tabs/chat/MessageDiv.tsx @@ -58,7 +58,9 @@ function MessageDiv(props: ChatMessage) {    }, [richContent, isStreaming]);    useEffect(() => { -    setRichContent([<ReactMarkdown key={1}>{props.content}</ReactMarkdown>]); +    setRichContent([ +      <ReactMarkdown key={1} children={props.content}></ReactMarkdown>, +    ]);    }, [props.content]);    return ( diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 5c75579b..cb7a5440 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -4,6 +4,7 @@ import {    vscBackground,    Loader,    MainTextInput, +  HeaderButton,  } from "../components";  import ContinueButton from "../components/ContinueButton";  import { useCallback, useEffect, useRef, useState } from "react"; @@ -11,7 +12,7 @@ import { History } from "../../../schema/History";  import { HistoryNode } from "../../../schema/HistoryNode";  import StepContainer from "../components/StepContainer";  import useContinueGUIProtocol from "../hooks/useWebsocket"; - +import { Trash } from "@styled-icons/heroicons-outline";  let TopGUIDiv = styled.div`    display: grid;    grid-template-columns: 1fr; @@ -26,6 +27,14 @@ let UserInputQueueItem = styled.div`    text-align: center;  `; +const TopBar = styled.div` +  display: flex; +  flex-direction: row; +  justify-content: space-between; +  padding: 8px; +  align-items: center; +`; +  interface GUIProps {    firstObservation?: any;  } @@ -33,143 +42,150 @@ interface GUIProps {  function GUI(props: GUIProps) {    const [waitingForSteps, setWaitingForSteps] = useState(false);    const [userInputQueue, setUserInputQueue] = useState<string[]>([]); -  const [history, setHistory] = useState<History | undefined>(); -  //   { -  //   timeline: [ -  //     { -  //       step: { -  //         name: "Waiting for user input", -  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //         description: -  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`", -  //       }, -  //       observation: { -  //         title: "ERROR FOUND", -  //         error: -  //           "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", -  //       }, -  //       output: [ -  //         { -  //           traceback: { -  //             frames: [ -  //               { -  //                 filepath: -  //                   "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //                 lineno: 7, -  //                 function: "<module>", -  //                 code: "print(sum(first, second))", -  //               }, -  //             ], -  //             message: "unsupported operand type(s) for +: 'int' and 'str'", -  //             error_type: -  //               '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError', -  //             full_traceback: -  //               "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", -  //           }, -  //         }, -  //         null, -  //       ], -  //     }, -  //     { -  //       step: { -  //         name: "EditCodeStep", -  //         range_in_files: [ -  //           { -  //             filepath: -  //               "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //             range: { -  //               start: { -  //                 line: 0, -  //                 character: 0, -  //               }, -  //               end: { -  //                 line: 6, -  //                 character: 25, -  //               }, -  //             }, -  //           }, -  //         ], -  //         prompt: -  //           "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n", -  //         description: -  //           "Editing files: /Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //       }, -  //       output: [ -  //         null, -  //         { -  //           reversible: true, -  //           actions: [ -  //             { -  //               reversible: true, -  //               filesystem: {}, -  //               filepath: -  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //               range: { -  //                 start: { -  //                   line: 0, -  //                   character: 0, -  //                 }, -  //                 end: { -  //                   line: 6, -  //                   character: 25, -  //                 }, -  //               }, -  //               replacement: -  //                 "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))", -  //             }, -  //           ], -  //         }, -  //       ], -  //     }, -  //     { -  //       step: { -  //         name: "SolveTracebackStep", -  //         traceback: { -  //           frames: [ -  //             { -  //               filepath: -  //                 "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //               lineno: 7, -  //               function: "<module>", -  //               code: "print(sum(first, second))", -  //             }, -  //           ], -  //           message: "unsupported operand type(s) for +: 'int' and 'str'", -  //           error_type: -  //             '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError', -  //           full_traceback: -  //             "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", -  //         }, -  //         description: "Running step: SolveTracebackStep", -  //       }, -  //       output: [null, null], -  //     }, -  //     { -  //       step: { -  //         name: "RunCodeStep", -  //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py", -  //         description: -  //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`", -  //       }, -  //       output: [null, null], -  //     }, -  //   ], -  //   current_index: 0, -  // } as any); +  const [history, setHistory] = useState<History | undefined>({ +    timeline: [ +      { +        step: { +          name: "Waiting for user input", +          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py", +          description: +            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and ```\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3", +        }, +        observation: { +          title: "ERROR FOUND", +          error: +            "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", +        }, +        output: [ +          { +            traceback: { +              frames: [ +                { +                  filepath: +                    "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", +                  lineno: 7, +                  function: "<module>", +                  code: "print(sum(first, second))", +                }, +              ], +              message: "unsupported operand type(s) for +: 'int' and 'str'", +              error_type: +                '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError', +              full_traceback: +                "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", +            }, +          }, +          null, +        ], +      }, +      { +        step: { +          name: "EditCodeStep", +          range_in_files: [ +            { +              filepath: +                "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", +              range: { +                start: { +                  line: 0, +                  character: 0, +                }, +                end: { +                  line: 6, +                  character: 25, +                }, +              }, +            }, +          ], +          prompt: +            "I ran into this problem with my Python code:\n\n                Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'\n\n                Below are the files that might need to be fixed:\n\n                {code}\n\n                This is what the code should be in order to avoid the problem:\n", +          description: +            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py` and\n```python\nprint(sum(first, second))\n```\n- Testing\n- Testing 2\n- Testing 3", +        }, +        output: [ +          null, +          { +            reversible: true, +            actions: [ +              { +                reversible: true, +                filesystem: {}, +                filepath: +                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", +                range: { +                  start: { +                    line: 0, +                    character: 0, +                  }, +                  end: { +                    line: 6, +                    character: 25, +                  }, +                }, +                replacement: +                  "\nfrom sum import sum\n\nfirst = 1\nsecond = 2\n\nprint(sum(first, second))", +              }, +            ], +          }, +        ], +      }, +      { +        step: { +          name: "SolveTracebackStep", +          traceback: { +            frames: [ +              { +                filepath: +                  "/Users/natesesti/Desktop/continue/extension/examples/python/main.py", +                lineno: 7, +                function: "<module>", +                code: "print(sum(first, second))", +              }, +            ], +            message: "unsupported operand type(s) for +: 'int' and 'str'", +            error_type: +              '          ^^^^^^^^^^^^^^^^^^\n  File "/Users/natesesti/Desktop/continue/extension/examples/python/sum.py", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError', +            full_traceback: +              "Traceback (most recent call last):\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/main.py\", line 7, in <module>\n    print(sum(first, second))\n          ^^^^^^^^^^^^^^^^^^\n  File \"/Users/natesesti/Desktop/continue/extension/examples/python/sum.py\", line 2, in sum\n    return a + b\n           ~~^~~\nTypeError: unsupported operand type(s) for +: 'int' and 'str'", +          }, +          description: "Running step: SolveTracebackStep", +        }, +        output: [null, null], +      }, +      { +        step: { +          name: "RunCodeStep", +          cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py", +          description: +            "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`", +        }, +        output: [null, null], +      }, +    ], +    current_index: 3, +  } as any);    const topGuiDivRef = useRef<HTMLDivElement>(null);    const client = useContinueGUIProtocol(); +  const [scrollTimeout, setScrollTimeout] = useState<NodeJS.Timeout | null>( +    null +  );    const scrollToBottom = useCallback(() => { +    if (scrollTimeout) { +      clearTimeout(scrollTimeout); +    } +    // Debounced smooth scroll to bottom of screen      if (topGuiDivRef.current) { -      setTimeout(() => { +      const timeout = setTimeout(() => {          window.scrollTo({            top: window.outerHeight,            behavior: "smooth",          }); -      }, 100); +      }, 200); +      setScrollTimeout(timeout);      } -  }, [topGuiDivRef.current]); +  }, [topGuiDivRef.current, scrollTimeout]);    useEffect(() => {      console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate); @@ -253,6 +269,19 @@ function GUI(props: GUIProps) {          }        }}      > +      <TopBar> +        <h3>Continue</h3> +        <HeaderButton style={{ padding: "3px" }}> +          Clear History +          <Trash +            size="1.6em" +            onClick={() => { +              client?.sendClear(); +            }} +          /> +        </HeaderButton> +      </TopBar> +        {typeof client === "undefined" && (          <>            <Loader></Loader> @@ -280,6 +309,9 @@ function GUI(props: GUIProps) {                client?.retryAtIndex(index);                setWaitingForSteps(true);              }} +            onDelete={() => { +              client?.deleteAtIndex(index); +            }}            />          );        })} | 
