From 122b63daeec6cb35d401eccd660759e1745f6778 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 13 Jun 2023 22:56:29 -0700 Subject: feedback dialog --- extension/react-app/src/components/TextDialog.tsx | 56 +++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 extension/react-app/src/components/TextDialog.tsx (limited to 'extension/react-app/src/components/TextDialog.tsx') diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx new file mode 100644 index 00000000..6b335e00 --- /dev/null +++ b/extension/react-app/src/components/TextDialog.tsx @@ -0,0 +1,56 @@ +// Write a component that displays a dialog box with a text field and a button. +import React, { useState } from "react"; +import styled from "styled-components"; +import { Button, buttonColor, secondaryDark, vscBackground } from "."; + +const DialogContainer = styled.div` + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +`; + +const Dialog = styled.div` + background-color: white; + border-radius: 8px; + padding: 8px; + display: flex; + flex-direction: column; + /* box-shadow: 0 0 10px 0 rgba(255, 255, 255, 0.5); */ + border: 2px solid ${buttonColor}; + width: fit-content; + margin: auto; +`; + +const TextArea = styled.textarea` + border: 1px solid #ccc; + border-radius: 8px; + padding: 8px; + outline: 1px solid black; + font-family: Arial, Helvetica, sans-serif; +`; + +const P = styled.p` + color: black; + margin: 8px auto; +`; + +const TextDialog = (props: { + showDialog: boolean; + onEnter: (text: string) => void; +}) => { + const [text, setText] = useState(""); + const textAreaRef = React.createRef(); + + return ( + + ); +}; + +export default TextDialog; -- cgit v1.2.3-70-g09d2 From 9100f116d0c28b231c0b746f60b8d59e00546456 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Tue, 13 Jun 2023 23:45:49 -0700 Subject: Small fixes --- .../src/continuedev/recipes/CreatePipelineRecipe/steps.py | 2 +- continuedev/src/continuedev/steps/feedback.py | 6 ++++++ extension/react-app/src/components/TextDialog.tsx | 10 +++++++++- extension/src/continueIdeClient.ts | 6 +++++- 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'extension/react-app/src/components/TextDialog.tsx') diff --git a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py index 88e27d2a..096b41c6 100644 --- a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py +++ b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/steps.py @@ -50,7 +50,7 @@ class SetupPipelineStep(Step): # editing the resource function to call the requested API resource_function_range = Range.from_shorthand(15, 0, 29, 0) - await sdk.ide.highlightCode(RangeInFile(filepath=os.path.join(await sdk.ide.getWorkspaceDirectory(), filename), range=resource_function_range)) + await sdk.ide.highlightCode(RangeInFile(filepath=os.path.join(await sdk.ide.getWorkspaceDirectory(), filename), range=resource_function_range), "#ffa50033") # sdk.set_loading_message("Writing code to call the API...") await sdk.edit_file( diff --git a/continuedev/src/continuedev/steps/feedback.py b/continuedev/src/continuedev/steps/feedback.py index bf119ab0..96081756 100644 --- a/continuedev/src/continuedev/steps/feedback.py +++ b/continuedev/src/continuedev/steps/feedback.py @@ -1,3 +1,5 @@ +from typing import Coroutine +from ..core.main import Models from ..core.main import Step from ..core.sdk import ContinueSDK from ..libs.util.telemetry import capture_event @@ -5,6 +7,10 @@ from ..libs.util.telemetry import capture_event class FeedbackStep(Step): user_input: str + name = "Thanks for your feedback!" + + async def describe(self, models: Models): + return f"`{self.user_input}`\n\nWe'll see your feedback and make improvements as soon as possible. If you'd like to directly email us, you can send an email to [nate@continue.dev](mailto:nate@continue.dev?subject=Feedback%20On%20Continue)." async def run(self, sdk: ContinueSDK): capture_event("feedback", {"feedback": self.user_input}) diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx index 6b335e00..167e12cf 100644 --- a/extension/react-app/src/components/TextDialog.tsx +++ b/extension/react-app/src/components/TextDialog.tsx @@ -47,7 +47,15 @@ const TextDialog = (props: {

Thanks for your feedback. We'll get back to you soon!

- +
); diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index 782219dc..3308068a 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -121,7 +121,11 @@ class IdeProtocolClient { } } getWorkspaceDirectory() { - return vscode.workspace.workspaceFolders![0].uri.fsPath; + if (!vscode.workspace.workspaceFolders) { + // Return the home directory + return process.env.HOME || process.env.USERPROFILE || "/"; + } + return vscode.workspace.workspaceFolders[0].uri.fsPath; } // ------------------------------------ // -- cgit v1.2.3-70-g09d2 From 5a6fa9ae784c5942f1e37c7a0ae3acdd6337c459 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Fri, 16 Jun 2023 23:42:10 -0700 Subject: polishing --- continuedev/src/continuedev/core/config.py | 15 ++++++++++-- continuedev/src/continuedev/core/sdk.py | 3 +++ .../src/continuedev/libs/llm/proxy_server.py | 2 +- .../continuedev/libs/util/step_name_to_steps.py | 2 ++ continuedev/src/continuedev/steps/clear_history.py | 10 ++++++++ continuedev/src/continuedev/steps/core/core.py | 2 ++ extension/package-lock.json | 4 ++-- extension/package.json | 8 +++---- extension/react-app/src/components/ComboBox.tsx | 21 ++++++++++++++++ .../src/components/HeaderButtonWithText.tsx | 4 +--- .../react-app/src/components/StepContainer.tsx | 1 - extension/react-app/src/components/TextDialog.tsx | 28 ++++++++++++++++++++-- extension/react-app/src/tabs/gui.tsx | 3 +++ extension/src/commands.ts | 5 +--- extension/src/continueIdeClient.ts | 2 +- 15 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 continuedev/src/continuedev/steps/clear_history.py (limited to 'extension/react-app/src/components/TextDialog.tsx') diff --git a/continuedev/src/continuedev/core/config.py b/continuedev/src/continuedev/core/config.py index 8f703758..1ee3a7f8 100644 --- a/continuedev/src/continuedev/core/config.py +++ b/continuedev/src/continuedev/core/config.py @@ -52,6 +52,11 @@ class ContinueConfig(BaseModel): name="feedback", description="Send feedback to improve Continue", step_name="FeedbackStep", + ), + SlashCommand( + name="clear", + description="Clear step history", + step_name="ClearHistoryStep", ) ] on_traceback: Optional[List[OnTracebackSteps]] = [ @@ -68,10 +73,16 @@ def load_config(config_file: str) -> ContinueConfig: _, ext = os.path.splitext(config_file) if ext == '.yaml': with open(config_file, 'r') as f: - config_dict = yaml.safe_load(f) + try: + config_dict = yaml.safe_load(f) + except: + return ContinueConfig() elif ext == '.json': with open(config_file, 'r') as f: - config_dict = json.load(f) + try: + config_dict = json.load(f) + except: + return ContinueConfig() else: raise ValueError(f'Unknown config file extension: {ext}') return ContinueConfig(**config_dict) diff --git a/continuedev/src/continuedev/core/sdk.py b/continuedev/src/continuedev/core/sdk.py index 7639d010..4ab2f027 100644 --- a/continuedev/src/continuedev/core/sdk.py +++ b/continuedev/src/continuedev/core/sdk.py @@ -192,3 +192,6 @@ class ContinueSDK(AbstractContinueSDK): async def update_ui(self): await self.__autopilot.update_subscribers() + + async def clear_history(self): + await self.__autopilot.clear_history() diff --git a/continuedev/src/continuedev/libs/llm/proxy_server.py b/continuedev/src/continuedev/libs/llm/proxy_server.py index 93f2d48a..dd0d3aca 100644 --- a/continuedev/src/continuedev/libs/llm/proxy_server.py +++ b/continuedev/src/continuedev/libs/llm/proxy_server.py @@ -18,7 +18,7 @@ CHAT_MODELS = { } # SERVER_URL = "http://127.0.0.1:8080" -SERVER_URL = "https://proxy-server-l6vsfbzhba-uc.a.run.app" +SERVER_URL = "https://proxy-server-l6vsfbzhba-uw.a.run.app" class ProxyServer(LLM): diff --git a/continuedev/src/continuedev/libs/util/step_name_to_steps.py b/continuedev/src/continuedev/libs/util/step_name_to_steps.py index 2c4474af..f431f317 100644 --- a/continuedev/src/continuedev/libs/util/step_name_to_steps.py +++ b/continuedev/src/continuedev/libs/util/step_name_to_steps.py @@ -11,6 +11,7 @@ from ...recipes.CreatePipelineRecipe.main import CreatePipelineRecipe from ...recipes.DDtoBQRecipe.main import DDtoBQRecipe from ...recipes.DeployPipelineAirflowRecipe.main import DeployPipelineAirflowRecipe from ...steps.on_traceback import DefaultOnTracebackStep +from ...steps.clear_history import ClearHistoryStep # This mapping is used to convert from string in ContinueConfig json to corresponding Step class. # Used for example in slash_commands and steps_on_startup @@ -25,6 +26,7 @@ step_name_to_step_class = { "DDtoBQRecipe": DDtoBQRecipe, "DeployPipelineAirflowRecipe": DeployPipelineAirflowRecipe, "DefaultOnTracebackStep": DefaultOnTracebackStep, + "ClearHistoryStep": ClearHistoryStep, } diff --git a/continuedev/src/continuedev/steps/clear_history.py b/continuedev/src/continuedev/steps/clear_history.py new file mode 100644 index 00000000..a875c6d3 --- /dev/null +++ b/continuedev/src/continuedev/steps/clear_history.py @@ -0,0 +1,10 @@ +from ..core.main import Step +from ..core.sdk import ContinueSDK + + +class ClearHistoryStep(Step): + name: str = "Clear History" + hide: bool = True + + async def run(self, sdk: ContinueSDK): + await sdk.clear_history() diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index 59af5f38..330f60ed 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -186,6 +186,8 @@ class DefaultModelEditCodeStep(Step): completion = completion.removesuffix(eot_token) # Remove tags and If it accidentally includes prefix or suffix, remove it + if completion.strip().startswith("```"): + completion = completion.strip().removeprefix("```").removesuffix("```") completion = completion.replace("", "").replace("", "").replace( "", "").replace("", "").replace("", "") completion = completion.removeprefix(segs[0]) diff --git a/extension/package-lock.json b/extension/package-lock.json index 86c816e0..92df6a4f 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.47", + "version": "0.0.50", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.47", + "version": "0.0.50", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 3a3927f3..a875c82d 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "Refine code 10x faster", - "version": "0.0.47", + "version": "0.0.50", "publisher": "Continue", "engines": { "vscode": "^1.74.0" @@ -86,8 +86,8 @@ "activitybar": [ { "id": "continue", - "title": "Continue", - "icon": "media/continue-gradient.png" + "title": "Continue ", + "icon": "react-app/dist/continue_arrow.png" } ] }, @@ -96,7 +96,7 @@ { "type": "webview", "id": "continue.continueGUIView", - "name": ")", + "name": " )", "visibility": "visible" } ] diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 2b140567..29f8a53b 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -68,6 +68,9 @@ interface ComboBoxProps { } const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { + const [history, setHistory] = React.useState([]); + // The position of the current command you are typing now, so the one that will be appended to history once you press enter + const [positionInHistory, setPositionInHistory] = React.useState(0); const [items, setItems] = React.useState(props.items); const { isOpen, @@ -113,9 +116,27 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { (event.nativeEvent as any).preventDownshiftDefault = true; if (props.onEnter) props.onEnter(event); setInputValue(""); + const value = event.currentTarget.value; + if (value !== "") { + setPositionInHistory(history.length + 1); + setHistory([...history, value]); + } } else if (event.key === "Tab" && items.length > 0) { setInputValue(items[0].name); event.preventDefault(); + } else if (event.key === "ArrowUp" && !isOpen) { + if (positionInHistory == 0) return; + setInputValue(history[positionInHistory - 1]); + setPositionInHistory((prev) => prev - 1); + } else if (event.key === "ArrowDown" && !isOpen) { + if (positionInHistory >= history.length - 1) { + setInputValue(""); + } else { + setInputValue(history[positionInHistory + 1]); + } + setPositionInHistory((prev) => + Math.min(prev + 1, history.length) + ); } }, ref: ref as any, diff --git a/extension/react-app/src/components/HeaderButtonWithText.tsx b/extension/react-app/src/components/HeaderButtonWithText.tsx index c4f22211..f9483f0f 100644 --- a/extension/react-app/src/components/HeaderButtonWithText.tsx +++ b/extension/react-app/src/components/HeaderButtonWithText.tsx @@ -15,9 +15,7 @@ const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => { style={{ padding: "3px" }} onMouseEnter={() => setHover(true)} onMouseLeave={() => { - setTimeout(() => { - setHover(false); - }, 100); + setHover(false); }} onClick={props.onClick} > diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 480f517f..7adbd7c2 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -63,7 +63,6 @@ const HeaderDiv = styled.div<{ error: boolean }>` const ContentDiv = styled.div` padding: 8px; padding-left: 16px; - background-color: ${vscBackground}; `; const OnHoverDiv = styled.div` diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx index 167e12cf..31a385d5 100644 --- a/extension/react-app/src/components/TextDialog.tsx +++ b/extension/react-app/src/components/TextDialog.tsx @@ -1,5 +1,5 @@ // Write a component that displays a dialog box with a text field and a button. -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import styled from "styled-components"; import { Button, buttonColor, secondaryDark, vscBackground } from "."; @@ -28,6 +28,10 @@ const TextArea = styled.textarea` padding: 8px; outline: 1px solid black; font-family: Arial, Helvetica, sans-serif; + + &:focus { + outline: 1px solid orange; + } `; const P = styled.p` @@ -38,19 +42,39 @@ const P = styled.p` const TextDialog = (props: { showDialog: boolean; onEnter: (text: string) => void; + onClose: () => void; }) => { const [text, setText] = useState(""); const textAreaRef = React.createRef(); + useEffect(() => { + if (textAreaRef.current) { + textAreaRef.current.focus(); + } + }, [props.showDialog]); + return (