From 458d2837163489ebaab0b21b3d6f3ab89c6a45d2 Mon Sep 17 00:00:00 2001 From: Ty Dunn <ty@tydunn.com> Date: Tue, 4 Jul 2023 21:14:35 -0700 Subject: new stop --- extension/react-app/src/components/StepContainer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'extension/react-app') diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index ab0d307f..492857b5 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -13,6 +13,9 @@ import { XMark, ArrowPath, } from "@styled-icons/heroicons-outline"; +import { + Stop, +} from "@styled-icons/heroicons-solid"; import { HistoryNode } from "../../../schema/HistoryNode"; import ReactMarkdown from "react-markdown"; import HeaderButtonWithText from "./HeaderButtonWithText"; @@ -208,7 +211,7 @@ function StepContainer(props: StepContainerProps) { }} text="Delete" > - <XMark size="1.6em" onClick={props.onDelete} /> + <Stop size="1.6em" onClick={props.onDelete} /> </HeaderButtonWithText> {props.historyNode.observation?.error ? ( <HeaderButtonWithText -- cgit v1.2.3-70-g09d2 From 0adac52b7733b32540b91e254244a08467c8650f Mon Sep 17 00:00:00 2001 From: Ty Dunn <ty@tydunn.com> Date: Tue, 4 Jul 2023 22:23:04 -0700 Subject: stop inside of circle --- extension/react-app/package-lock.json | 27 ++++++++++++++++++++++ extension/react-app/package.json | 1 + .../src/components/HeaderButtonWithText.tsx | 4 +++- .../react-app/src/components/StepContainer.tsx | 7 +++--- 4 files changed, 35 insertions(+), 4 deletions(-) (limited to 'extension/react-app') diff --git a/extension/react-app/package-lock.json b/extension/react-app/package-lock.json index 85b8633b..fb13dffd 100644 --- a/extension/react-app/package-lock.json +++ b/extension/react-app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@styled-icons/heroicons-outline": "^10.47.0", + "@styled-icons/heroicons-solid": "^10.47.0", "@types/vscode-webview": "^1.57.1", "downshift": "^7.6.0", "posthog-js": "^1.58.0", @@ -691,6 +692,23 @@ "styled-components": "*" } }, + "node_modules/@styled-icons/heroicons-solid": { + "version": "10.47.0", + "resolved": "https://registry.npmjs.org/@styled-icons/heroicons-solid/-/heroicons-solid-10.47.0.tgz", + "integrity": "sha512-j+tJx2NzLG2tc91IXJVwKNjsI/osxmak+wmLfnfBsB+49srpxMYjuLPMtl9ZY/xgbNsWO36O+/N5Zf5bkgiKcQ==", + "dependencies": { + "@babel/runtime": "^7.20.7", + "@styled-icons/styled-icon": "^10.7.0" + }, + "funding": { + "type": "GitHub", + "url": "https://github.com/sponsors/jacobwgillespie" + }, + "peerDependencies": { + "react": "*", + "styled-components": "*" + } + }, "node_modules/@styled-icons/styled-icon": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/@styled-icons/styled-icon/-/styled-icon-10.7.0.tgz", @@ -3937,6 +3955,15 @@ "@styled-icons/styled-icon": "^10.7.0" } }, + "@styled-icons/heroicons-solid": { + "version": "10.47.0", + "resolved": "https://registry.npmjs.org/@styled-icons/heroicons-solid/-/heroicons-solid-10.47.0.tgz", + "integrity": "sha512-j+tJx2NzLG2tc91IXJVwKNjsI/osxmak+wmLfnfBsB+49srpxMYjuLPMtl9ZY/xgbNsWO36O+/N5Zf5bkgiKcQ==", + "requires": { + "@babel/runtime": "^7.20.7", + "@styled-icons/styled-icon": "^10.7.0" + } + }, "@styled-icons/styled-icon": { "version": "10.7.0", "resolved": "https://registry.npmjs.org/@styled-icons/styled-icon/-/styled-icon-10.7.0.tgz", diff --git a/extension/react-app/package.json b/extension/react-app/package.json index e46fdc8c..12701906 100644 --- a/extension/react-app/package.json +++ b/extension/react-app/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@styled-icons/heroicons-outline": "^10.47.0", + "@styled-icons/heroicons-solid": "^10.47.0", "@types/vscode-webview": "^1.57.1", "downshift": "^7.6.0", "posthog-js": "^1.58.0", diff --git a/extension/react-app/src/components/HeaderButtonWithText.tsx b/extension/react-app/src/components/HeaderButtonWithText.tsx index 3ddac93c..72a653c5 100644 --- a/extension/react-app/src/components/HeaderButtonWithText.tsx +++ b/extension/react-app/src/components/HeaderButtonWithText.tsx @@ -8,15 +8,17 @@ interface HeaderButtonWithTextProps { children: React.ReactNode; disabled?: boolean; inverted?: boolean; + active?: boolean; } const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => { const [hover, setHover] = useState(false); + const paddingLeft = (props.disabled ? (props.active ? "3px" : "1px"): (hover ? "4px" : "1px")); return ( <HeaderButton inverted={props.inverted} disabled={props.disabled} - style={{ padding: "1px", paddingLeft: hover ? "4px" : "1px" }} + style={{ padding: (props.active ? "3px" : "1px"), paddingLeft, borderRadius: (props.active ? "50%" : undefined) }} onMouseEnter={() => { if (!props.disabled) { setHover(true); diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 311f68cf..183ffeef 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -10,8 +10,8 @@ import { import { ChevronDown, ChevronRight, - XMark, ArrowPath, + XMark } from "@styled-icons/heroicons-outline"; import { Stop, @@ -210,9 +210,10 @@ function StepContainer(props: StepContainerProps) { e.stopPropagation(); props.onDelete(); }} - text="Delete" + text={props.historyNode.active ? "Stop" : "Delete"} + active={props.historyNode.active} > - <Stop size="1.6em" onClick={props.onDelete} /> + {props.historyNode.active ? <Stop size="1.6em" onClick={props.onDelete} /> :<XMark size="1.6em" onClick={props.onDelete} />} </HeaderButtonWithText> {props.historyNode.observation?.error ? ( <HeaderButtonWithText -- cgit v1.2.3-70-g09d2 From 36f3845a18ed65ff6784b99cb34d9f6c4a7e0143 Mon Sep 17 00:00:00 2001 From: Nate Sesti <sestinj@gmail.com> Date: Wed, 5 Jul 2023 01:04:33 -0700 Subject: highlighted code improvements --- continuedev/src/continuedev/core/autopilot.py | 11 ++++++++- continuedev/src/continuedev/core/main.py | 1 + continuedev/src/continuedev/server/gui.py | 7 ++++++ continuedev/src/continuedev/steps/core/core.py | 1 + extension/react-app/src/components/ComboBox.tsx | 27 ++++++++++++++++++---- extension/react-app/src/components/PillButton.tsx | 27 +++++++--------------- .../src/components/UserInputContainer.tsx | 4 +++- .../src/hooks/ContinueGUIClientProtocol.ts | 2 ++ .../react-app/src/hooks/useContinueGUIProtocol.ts | 4 ++++ extension/react-app/src/tabs/gui.tsx | 6 +++++ 10 files changed, 65 insertions(+), 25 deletions(-) (limited to 'extension/react-app') diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py index 313ceded..29be3b79 100644 --- a/continuedev/src/continuedev/core/autopilot.py +++ b/continuedev/src/continuedev/core/autopilot.py @@ -69,7 +69,8 @@ class Autopilot(ContinueBaseModel): user_input_queue=self._main_user_input_queue, default_model=self.continue_sdk.config.default_model, highlighted_ranges=self._highlighted_ranges, - slash_commands=self.get_available_slash_commands() + slash_commands=self.get_available_slash_commands(), + adding_highlighted_code=self._adding_highlighted_code, ) def get_available_slash_commands(self) -> List[Dict]: @@ -140,8 +141,12 @@ class Autopilot(ContinueBaseModel): await self._run_singular_step(step) _highlighted_ranges: List[RangeInFileWithContents] = [] + _adding_highlighted_code: bool = False async def handle_highlighted_code(self, range_in_files: List[RangeInFileWithContents]): + if not self._adding_highlighted_code: + return + workspace_path = self.continue_sdk.ide.workspace_directory for rif in range_in_files: rif.filepath = os.path.basename(rif.filepath) @@ -186,6 +191,10 @@ class Autopilot(ContinueBaseModel): self._highlighted_ranges = kept_ranges await self.update_subscribers() + async def toggle_adding_highlighted_code(self): + self._adding_highlighted_code = not self._adding_highlighted_code + await self.update_subscribers() + async def _run_singular_step(self, step: "Step", is_future_step: bool = False) -> Coroutine[Observation, None, None]: # Allow config to set disallowed steps if step.__class__.__name__ in self.continue_sdk.config.disallowed_steps: diff --git a/continuedev/src/continuedev/core/main.py b/continuedev/src/continuedev/core/main.py index 8bad09d1..28fd964e 100644 --- a/continuedev/src/continuedev/core/main.py +++ b/continuedev/src/continuedev/core/main.py @@ -207,6 +207,7 @@ class FullState(ContinueBaseModel): default_model: str highlighted_ranges: List[RangeInFileWithContents] slash_commands: List[SlashCommandDescription] + adding_highlighted_code: bool class ContinueSDK: diff --git a/continuedev/src/continuedev/server/gui.py b/continuedev/src/continuedev/server/gui.py index 4e960f7c..fa573b37 100644 --- a/continuedev/src/continuedev/server/gui.py +++ b/continuedev/src/continuedev/server/gui.py @@ -85,6 +85,8 @@ class GUIProtocolServer(AbstractGUIProtocolServer): self.on_delete_at_index(data["index"]) elif message_type == "delete_context_at_indices": self.on_delete_context_at_indices(data["indices"]) + elif message_type == "toggle_adding_highlighted_code": + self.on_toggle_adding_highlighted_code() except Exception as e: print(e) @@ -128,6 +130,11 @@ class GUIProtocolServer(AbstractGUIProtocolServer): self.session.autopilot.delete_context_at_indices(indices) ) + def on_toggle_adding_highlighted_code(self): + asyncio.create_task( + self.session.autopilot.toggle_adding_highlighted_code() + ) + @router.websocket("/ws") async def websocket_endpoint(websocket: WebSocket, session: Session = Depends(websocket_session)): diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index b215b317..c74412ba 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -286,6 +286,7 @@ class DefaultModelEditCodeStep(Step): return "```" in line or "<modified_code_to_edit>" in line or "<file_prefix>" in line or "</file_prefix>" in line or "<file_suffix>" in line or "</file_suffix>" in line or "<user_request>" in line or "</user_request>" in line or "<code_to_edit>" in line async def stream_rif(self, rif: RangeInFileWithContents, sdk: ContinueSDK): + await sdk.ide.saveFile(rif.filepath) full_file_contents = await sdk.ide.readFile(rif.filepath) file_prefix, contents, file_suffix, model_to_use = await self.get_prompt_parts( diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 3e1f3e16..97f5b57e 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -11,7 +11,12 @@ import CodeBlock from "./CodeBlock"; import { RangeInFile } from "../../../src/client"; import PillButton from "./PillButton"; import HeaderButtonWithText from "./HeaderButtonWithText"; -import { Trash, LockClosed, LockOpen } from "@styled-icons/heroicons-outline"; +import { + Trash, + LockClosed, + LockOpen, + Plus, +} from "@styled-icons/heroicons-outline"; // #region styled components const mainInputFontSize = 16; @@ -100,6 +105,8 @@ interface ComboBoxProps { highlightedCodeSections: (RangeInFile & { contents: string })[]; deleteContextItems: (indices: number[]) => void; onTogglePin: () => void; + onToggleAddContext: () => void; + addingHighlightedCode: boolean; } const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { @@ -249,6 +256,19 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { </Ul> </div> <div className="px-2 flex gap-2 items-center flex-wrap"> + {highlightedCodeSections.length === 0 && ( + <HeaderButtonWithText + text={ + props.addingHighlightedCode ? "Adding Context" : "Add Context" + } + onClick={() => { + props.onToggleAddContext(); + }} + inverted={props.addingHighlightedCode} + > + <Plus size="1.6em" /> + </HeaderButtonWithText> + )} {highlightedCodeSections.length > 0 && ( <> <HeaderButtonWithText @@ -305,9 +325,8 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { ))} <span className="text-trueGray-400 ml-auto mr-4 text-xs"> - Highlight code to include as context.{" "} - {highlightedCodeSections.length === 0 && - "Otherwise using entire currently open file."} + Highlight code to include as context. Currently open file included by + default. {highlightedCodeSections.length === 0 && ""} </span> </div> <ContextDropdown diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx index 2352c3ad..5a02c6b2 100644 --- a/extension/react-app/src/components/PillButton.tsx +++ b/extension/react-app/src/components/PillButton.tsx @@ -15,6 +15,8 @@ const Button = styled.button` background-color: white; color: black; } + + cursor: pointer; `; interface PillButtonProps { @@ -39,26 +41,13 @@ const PillButton = (props: PillButtonProps) => { props.onHover(false); } }} + onClick={() => { + if (props.onDelete) { + props.onDelete(); + } + }} > - <div - style={{ display: "grid", gridTemplateColumns: "1fr auto", gap: "4px" }} - > - <span - style={{ - cursor: "pointer", - color: "red", - borderRight: "1px solid black", - paddingRight: "4px", - }} - onClick={() => { - props.onDelete?.(); - props.onHover?.(false); - }} - > - <XMark style={{ padding: "0px" }} size="1.2em" strokeWidth="2px" /> - </span> - <span>{props.title}</span> - </div> + {props.title} </Button> ); }; diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx index 44fdba38..a72f6098 100644 --- a/extension/react-app/src/components/UserInputContainer.tsx +++ b/extension/react-app/src/components/UserInputContainer.tsx @@ -14,7 +14,7 @@ interface UserInputContainerProps { historyNode: HistoryNode; } -const StyledDiv = styled.div` +const StyledDiv = styled.div<{ hidden: boolean }>` background-color: rgb(50 50 50); padding: 8px; padding-left: 16px; @@ -24,6 +24,8 @@ const StyledDiv = styled.div` font-size: 13px; display: flex; align-items: center; + visibility: ${(props) => (props.hidden ? "hidden" : "visible")}; + height: ${(props) => (props.hidden ? "0px" : "auto")}; `; const UserInputContainer = (props: UserInputContainerProps) => { diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts index 96ea7ab3..f123bb2b 100644 --- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts +++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts @@ -22,6 +22,8 @@ abstract class AbstractContinueGUIClientProtocol { abstract deleteAtIndex(index: number): void; abstract deleteContextAtIndices(indices: number[]): void; + + abstract toggleAddingHighlightedCode(): void; } export default AbstractContinueGUIClientProtocol; diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts index e950387c..49f200ae 100644 --- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts +++ b/extension/react-app/src/hooks/useContinueGUIProtocol.ts @@ -74,6 +74,10 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol { deleteContextAtIndices(indices: number[]) { this.messenger.send("delete_context_at_indices", { indices }); } + + toggleAddingHighlightedCode(): void { + this.messenger.send("toggle_adding_highlighted_code", {}); + } } export default ContinueGUIClientProtocol; diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index bbf0b126..851045d5 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -71,6 +71,7 @@ function GUI(props: GUIProps) { const [waitingForSteps, setWaitingForSteps] = useState(false); const [userInputQueue, setUserInputQueue] = useState<string[]>([]); const [highlightedRanges, setHighlightedRanges] = useState([]); + const [addingHighlightedCode, setAddingHighlightedCode] = useState(false); const [availableSlashCommands, setAvailableSlashCommands] = useState< { name: string; description: string }[] >([]); @@ -157,6 +158,7 @@ function GUI(props: GUIProps) { setHistory(state.history); setHighlightedRanges(state.highlighted_ranges); setUserInputQueue(state.user_input_queue); + setAddingHighlightedCode(state.adding_highlighted_code); setAvailableSlashCommands( state.slash_commands.map((c: any) => { return { @@ -361,6 +363,10 @@ function GUI(props: GUIProps) { onTogglePin={() => { setPinned((prev: boolean) => !prev); }} + onToggleAddContext={() => { + client?.toggleAddingHighlightedCode(); + }} + addingHighlightedCode={addingHighlightedCode} /> <ContinueButton onClick={onMainTextInput} /> </TopGUIDiv> -- cgit v1.2.3-70-g09d2 From b3eb9d934ef6e73ea4f43a9fb7584e948ea9e0b5 Mon Sep 17 00:00:00 2001 From: Nate Sesti <sestinj@gmail.com> Date: Wed, 5 Jul 2023 01:51:46 -0700 Subject: details --- continuedev/src/continuedev/core/policy.py | 64 ++++++++++++---------- extension/package-lock.json | 4 +- extension/package.json | 2 +- extension/react-app/src/components/ComboBox.tsx | 2 +- .../react-app/src/components/StepContainer.tsx | 12 ++-- .../src/components/UserInputContainer.tsx | 10 ++-- extension/react-app/src/tabs/gui.tsx | 18 +++--- 7 files changed, 61 insertions(+), 51 deletions(-) (limited to 'extension/react-app') diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py index b0853380..ef753ee4 100644 --- a/continuedev/src/continuedev/core/policy.py +++ b/continuedev/src/continuedev/core/policy.py @@ -1,5 +1,5 @@ from textwrap import dedent -from typing import List, Tuple, Type +from typing import List, Tuple, Type, Union from ..steps.welcome import WelcomeStep from .config import ContinueConfig @@ -22,6 +22,34 @@ from ..libs.util.step_name_to_steps import get_step_from_name from ..steps.custom_command import CustomCommandStep +def parse_slash_command(inp: str, config: ContinueConfig) -> Union[None, Step]: + """ + Parses a slash command, returning the command name and the rest of the input. + """ + if inp.startswith("/"): + command_name = inp.split(" ")[0] + after_command = " ".join(inp.split(" ")[1:]) + + for slash_command in config.slash_commands: + if slash_command.name == command_name[1:]: + params = slash_command.params + params["user_input"] = after_command + return get_step_from_name(slash_command.step_name, params) + return None + + +def parse_custom_command(inp: str, config: ContinueConfig) -> Union[None, Step]: + command_name = inp.split(" ")[0] + after_command = " ".join(inp.split(" ")[1:]) + for custom_cmd in config.custom_commands: + if custom_cmd.name == command_name[1:]: + slash_command = parse_slash_command(custom_cmd.prompt, config) + if slash_command is not None: + return slash_command + return CustomCommandStep(name=custom_cmd.name, prompt=custom_cmd.prompt, user_input=after_command) + return None + + class DemoPolicy(Policy): ran_code_last: bool = False @@ -46,34 +74,14 @@ class DemoPolicy(Policy): # This could be defined with ObservationTypePolicy. Ergonomics not right though. user_input = observation.user_input - if user_input.startswith("/"): - command_name = user_input.split(" ")[0] - after_command = " ".join(user_input.split(" ")[1:]) - for slash_command in config.slash_commands: - if slash_command.name == command_name[1:]: - params = slash_command.params - params["user_input"] = after_command - return get_step_from_name(slash_command.step_name, params) + slash_command = parse_slash_command(user_input) + if slash_command is not None: + return slash_command - for custom_cmd in config.custom_commands: - if custom_cmd.name == command_name[1:]: - return CustomCommandStep(name=custom_cmd.name, prompt=custom_cmd.prompt, user_input=after_command) + custom_command = parse_custom_command(user_input) + if custom_command is not None: + return custom_command - # return EditHighlightedCodeStep(user_input=user_input) return ChatWithFunctions(user_input=user_input) - return NLDecisionStep(user_input=user_input, steps=[ - (EditHighlightedCodeStep(user_input=user_input), - "Edit the highlighted code"), - # AnswerQuestionChroma(question=user_input), - # EditFileChroma(request=user_input), - (SimpleChatStep(user_input=user_input), - "Respond to the user with a chat message. Can answer questions about code or anything else."), - ], default_step=EditHighlightedCodeStep(user_input=user_input)) - - state = history.get_current() - if observation is not None and isinstance(observation, TracebackObservation): - self.ran_code_last = False - return SolveTracebackStep(traceback=observation.traceback) - else: - return None + return None diff --git a/extension/package-lock.json b/extension/package-lock.json index 82c28a90..ce1a42ee 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.109", + "version": "0.0.110", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.109", + "version": "0.0.110", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 001a696e..607c2ca6 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.109", + "version": "0.0.110", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 97f5b57e..73b7cc2d 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -324,7 +324,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { /> ))} - <span className="text-trueGray-400 ml-auto mr-4 text-xs"> + <span className="text-trueGray-400 ml-auto mr-4 text-xs text-right"> Highlight code to include as context. Currently open file included by default. {highlightedCodeSections.length === 0 && ""} </span> diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 183ffeef..2aed2e72 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -11,11 +11,9 @@ import { ChevronDown, ChevronRight, ArrowPath, - XMark + XMark, } from "@styled-icons/heroicons-outline"; -import { - Stop, -} from "@styled-icons/heroicons-solid"; +import { Stop } from "@styled-icons/heroicons-solid"; import { HistoryNode } from "../../../schema/HistoryNode"; import ReactMarkdown from "react-markdown"; import HeaderButtonWithText from "./HeaderButtonWithText"; @@ -213,7 +211,11 @@ function StepContainer(props: StepContainerProps) { text={props.historyNode.active ? "Stop" : "Delete"} active={props.historyNode.active} > - {props.historyNode.active ? <Stop size="1.6em" onClick={props.onDelete} /> :<XMark size="1.6em" onClick={props.onDelete} />} + {props.historyNode.active ? ( + <Stop size="1.2em" onClick={props.onDelete} /> + ) : ( + <XMark size="1.6em" onClick={props.onDelete} /> + )} </HeaderButtonWithText> {props.historyNode.observation?.error ? ( <HeaderButtonWithText diff --git a/extension/react-app/src/components/UserInputContainer.tsx b/extension/react-app/src/components/UserInputContainer.tsx index a72f6098..28437d35 100644 --- a/extension/react-app/src/components/UserInputContainer.tsx +++ b/extension/react-app/src/components/UserInputContainer.tsx @@ -14,8 +14,8 @@ interface UserInputContainerProps { historyNode: HistoryNode; } -const StyledDiv = styled.div<{ hidden: boolean }>` - background-color: rgb(50 50 50); +const StyledDiv = styled.div` + background-color: rgb(45 45 45); padding: 8px; padding-left: 16px; padding-right: 16px; @@ -24,14 +24,12 @@ const StyledDiv = styled.div<{ hidden: boolean }>` font-size: 13px; display: flex; align-items: center; - visibility: ${(props) => (props.hidden ? "hidden" : "visible")}; - height: ${(props) => (props.hidden ? "0px" : "auto")}; `; const UserInputContainer = (props: UserInputContainerProps) => { return ( - <StyledDiv hidden={props.historyNode.step.hide as any}> - {props.children} + <StyledDiv> + <b>{props.children}</b> <div style={{ marginLeft: "auto" }}> <HeaderButtonWithText onClick={(e) => { diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 851045d5..e5320c6a 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -295,14 +295,16 @@ function GUI(props: GUIProps) { )} {history?.timeline.map((node: HistoryNode, index: number) => { return node.step.name === "User Input" ? ( - <UserInputContainer - onDelete={() => { - client?.deleteAtIndex(index); - }} - historyNode={node} - > - {node.step.description as string} - </UserInputContainer> + node.step.hide || ( + <UserInputContainer + onDelete={() => { + client?.deleteAtIndex(index); + }} + historyNode={node} + > + {node.step.description as string} + </UserInputContainer> + ) ) : ( <StepContainer isLast={index === history.timeline.length - 1} -- cgit v1.2.3-70-g09d2 From 68831f3d0af34a6f83b120ade86a1aa69a7017ac Mon Sep 17 00:00:00 2001 From: Nate Sesti <sestinj@gmail.com> Date: Wed, 5 Jul 2023 12:09:10 -0700 Subject: explain by default --- continuedev/src/continuedev/core/config.py | 12 ++++++------ continuedev/src/continuedev/core/policy.py | 6 +++--- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/react-app/src/components/ComboBox.tsx | 5 +++++ extension/src/diffs.ts | 8 +++++++- 6 files changed, 24 insertions(+), 13 deletions(-) (limited to 'extension/react-app') diff --git a/continuedev/src/continuedev/core/config.py b/continuedev/src/continuedev/core/config.py index 8f7e0b8c..ff7b8cb0 100644 --- a/continuedev/src/continuedev/core/config.py +++ b/continuedev/src/continuedev/core/config.py @@ -33,11 +33,11 @@ DEFAULT_SLASH_COMMANDS = [ description="Edit code in the current file or the highlighted code", step_name="EditHighlightedCodeStep", ), - SlashCommand( - name="explain", - description="Reply to instructions or a question with previous steps and the highlighted code or current file as context", - step_name="SimpleChatStep", - ), + # SlashCommand( + # name="explain", + # description="Reply to instructions or a question with previous steps and the highlighted code or current file as context", + # step_name="SimpleChatStep", + # ), SlashCommand( name="config", description="Open the config file to create new and edit existing slash commands", @@ -129,7 +129,7 @@ def load_global_config() -> ContinueConfig: config_path = os.path.join(global_dir, 'config.json') if not os.path.exists(config_path): with open(config_path, 'w') as f: - json.dump(dict(ContinueConfig()), f) + json.dump(ContinueConfig().dict(), f) with open(config_path, 'r') as f: try: config_dict = json.load(f) diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py index ef753ee4..fc9266ab 100644 --- a/continuedev/src/continuedev/core/policy.py +++ b/continuedev/src/continuedev/core/policy.py @@ -74,14 +74,14 @@ class DemoPolicy(Policy): # This could be defined with ObservationTypePolicy. Ergonomics not right though. user_input = observation.user_input - slash_command = parse_slash_command(user_input) + slash_command = parse_slash_command(user_input, config) if slash_command is not None: return slash_command - custom_command = parse_custom_command(user_input) + custom_command = parse_custom_command(user_input, config) if custom_command is not None: return custom_command - return ChatWithFunctions(user_input=user_input) + return SimpleChatStep(user_input=user_input) return None diff --git a/extension/package-lock.json b/extension/package-lock.json index ce1a42ee..169b13b5 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.110", + "version": "0.0.111", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.110", + "version": "0.0.111", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 607c2ca6..6a0f9eb3 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.110", + "version": "0.0.111", "publisher": "Continue", "engines": { "vscode": "^1.67.0" diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 73b7cc2d..545be32a 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -195,6 +195,11 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { ) { // Prevent Downshift's default 'Enter' behavior. (event.nativeEvent as any).preventDownshiftDefault = true; + + // cmd+enter to /edit + if (event.metaKey) { + event.currentTarget.value = `/edit ${event.currentTarget}`; + } if (props.onEnter) props.onEnter(event); setInputValue(""); const value = event.currentTarget.value; diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts index 19ec80ab..b70c3b59 100644 --- a/extension/src/diffs.ts +++ b/extension/src/diffs.ts @@ -16,7 +16,7 @@ class DiffManager { // Doing this because virtual files are read-only private diffs: Map<string, DiffInfo> = new Map(); - constructor() { + private setupDirectory() { // Make sure the diff directory exists if (!fs.existsSync(DIFF_DIRECTORY)) { fs.mkdirSync(DIFF_DIRECTORY, { @@ -25,6 +25,10 @@ class DiffManager { } } + constructor() { + this.setupDirectory(); + } + private escapeFilepath(filepath: string): string { return filepath.replace(/\\/g, "_").replace(/\//g, "_"); } @@ -47,6 +51,8 @@ class DiffManager { } writeDiff(originalFilepath: string, newContent: string): string { + this.setupDirectory(); + // Create or update existing diff const newFilepath = path.join( DIFF_DIRECTORY, -- cgit v1.2.3-70-g09d2 From 8a5cda89378640cef375689d6be48f9ab21cab7e Mon Sep 17 00:00:00 2001 From: Nate Sesti <sestinj@gmail.com> Date: Wed, 5 Jul 2023 16:28:58 -0700 Subject: setting to show codelens in diff editor --- extension/package-lock.json | 4 ++-- extension/package.json | 3 ++- extension/react-app/src/components/ComboBox.tsx | 2 +- extension/react-app/src/main.tsx | 4 ++++ extension/src/diffs.ts | 6 ++++++ extension/src/lang-server/codeLens.ts | 24 ++++++++++++++++++++---- 6 files changed, 35 insertions(+), 8 deletions(-) (limited to 'extension/react-app') diff --git a/extension/package-lock.json b/extension/package-lock.json index 169b13b5..6e527583 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.111", + "version": "0.0.112", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.111", + "version": "0.0.112", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 6a0f9eb3..413e5b89 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.111", + "version": "0.0.112", "publisher": "Continue", "engines": { "vscode": "^1.67.0" @@ -39,6 +39,7 @@ "onView:continueGUIView" ], "main": "./out/extension.js", + "browser": "./out/extension.js", "contributes": { "configuration": { "title": "Continue", diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 545be32a..61c9ab1e 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -198,7 +198,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => { // cmd+enter to /edit if (event.metaKey) { - event.currentTarget.value = `/edit ${event.currentTarget}`; + event.currentTarget.value = `/edit ${event.currentTarget.value}`; } if (props.onEnter) props.onEnter(event); setInputValue(""); diff --git a/extension/react-app/src/main.tsx b/extension/react-app/src/main.tsx index 1b94dc82..0b02575c 100644 --- a/extension/react-app/src/main.tsx +++ b/extension/react-app/src/main.tsx @@ -8,6 +8,10 @@ import { PostHogProvider } from "posthog-js/react"; posthog.init("phc_JS6XFROuNbhJtVCEdTSYk6gl5ArRrTNMpCcguAXlSPs", { api_host: "https://app.posthog.com", + session_recording: { + // WARNING: Only enable this if you understand the security implications + recordCrossOriginIframes: true, + } as any, }); ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts index b70c3b59..178b1a9d 100644 --- a/extension/src/diffs.ts +++ b/extension/src/diffs.ts @@ -47,6 +47,12 @@ class DiffManager { if (!editor) { throw new Error("No active text editor found for Continue Diff"); } + + // Change the vscode setting to allow codeLens in diff editor + vscode.workspace + .getConfiguration("diffEditor", editor.document.uri) + .update("codeLens", true, vscode.ConfigurationTarget.Global); + return editor; } diff --git a/extension/src/lang-server/codeLens.ts b/extension/src/lang-server/codeLens.ts index 08435a3b..381a0084 100644 --- a/extension/src/lang-server/codeLens.ts +++ b/extension/src/lang-server/codeLens.ts @@ -67,11 +67,9 @@ class DiffViewerCodeLensProvider implements vscode.CodeLensProvider { document: vscode.TextDocument, token: vscode.CancellationToken ): vscode.CodeLens[] | Thenable<vscode.CodeLens[]> { - if (path.dirname(document.uri.fsPath) !== DIFF_DIRECTORY) { - return []; - } else { + if (path.dirname(document.uri.fsPath) === DIFF_DIRECTORY) { const codeLenses: vscode.CodeLens[] = []; - const range = new vscode.Range(0, 0, 0, 0); + const range = new vscode.Range(0, 0, 1, 0); codeLenses.push( new vscode.CodeLens(range, { title: "Accept ✅", @@ -85,6 +83,24 @@ class DiffViewerCodeLensProvider implements vscode.CodeLensProvider { }) ); return codeLenses; + } else { + return []; + } + } + + onDidChangeCodeLenses?: vscode.Event<void> | undefined; + + constructor(emitter?: vscode.EventEmitter<void>) { + if (emitter) { + this.onDidChangeCodeLenses = emitter.event; + this.onDidChangeCodeLenses(() => { + if (vscode.window.activeTextEditor) { + this.provideCodeLenses( + vscode.window.activeTextEditor.document, + new vscode.CancellationTokenSource().token + ); + } + }); } } } -- cgit v1.2.3-70-g09d2 From 22b02641b4b14ffad32914d046e645cf6f850253 Mon Sep 17 00:00:00 2001 From: Nate Sesti <sestinj@gmail.com> Date: Wed, 5 Jul 2023 20:35:59 -0700 Subject: stuff --- continuedev/src/continuedev/core/autopilot.py | 4 ++++ continuedev/src/continuedev/steps/core/core.py | 19 +++++++++++-------- extension/package-lock.json | 4 ++-- extension/package.json | 6 +++--- extension/react-app/src/components/ComboBox.tsx | 2 +- extension/src/diffs.ts | 22 ++++++++++++++++++---- 6 files changed, 39 insertions(+), 18 deletions(-) (limited to 'extension/react-app') diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py index 29be3b79..b1c4f471 100644 --- a/continuedev/src/continuedev/core/autopilot.py +++ b/continuedev/src/continuedev/core/autopilot.py @@ -147,6 +147,10 @@ class Autopilot(ContinueBaseModel): if not self._adding_highlighted_code: return + # Filter out rifs from ~/.continue/diffs folder + range_in_files = [ + rif for rif in range_in_files if not os.path.dirname(rif.filepath) == os.path.expanduser("~/.continue/diffs")] + workspace_path = self.continue_sdk.ide.workspace_directory for rif in range_in_files: rif.filepath = os.path.basename(rif.filepath) diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index c74412ba..3a7c8876 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -332,8 +332,9 @@ class DefaultModelEditCodeStep(Step): # Highlight the line to show progress line_to_highlight = current_line_in_file - len(current_block_lines) - await sdk.ide.highlightCode(RangeInFile(filepath=rif.filepath, range=Range.from_shorthand( - line_to_highlight, 0, line_to_highlight, 0)), "#FFFFFF22" if len(current_block_lines) == 0 else "#00FF0022") + if False: + await sdk.ide.highlightCode(RangeInFile(filepath=rif.filepath, range=Range.from_shorthand( + line_to_highlight, 0, line_to_highlight, 0)), "#FFFFFF22" if len(current_block_lines) == 0 else "#00FF0022") if len(current_block_lines) == 0: # Set this as the start of the next block @@ -382,12 +383,14 @@ class DefaultModelEditCodeStep(Step): replacement = "\n".join(current_block_lines) start_line = current_block_start end_line = current_block_start + index_of_last_line_in_block - await sdk.ide.showSuggestion(FileEdit( - filepath=rif.filepath, - range=Range.from_shorthand( - start_line, 0, end_line, 0), - replacement=replacement - )) + + if False: + await sdk.ide.showSuggestion(FileEdit( + filepath=rif.filepath, + range=Range.from_shorthand( + start_line, 0, end_line, 0), + replacement=replacement + )) # Reset current block / update variables current_line_in_file += 1 diff --git a/extension/package-lock.json b/extension/package-lock.json index 6e527583..b322acb7 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.112", + "version": "0.0.113", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.112", + "version": "0.0.113", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 413e5b89..09703da4 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "The open-source coding autopilot", - "version": "0.0.112", + "version": "0.0.113", "publisher": "Continue", "engines": { "vscode": "^1.67.0" @@ -130,12 +130,12 @@ "key": "shift+ctrl+enter" }, { - "command": "continue.acceptAllSuggestions", + "command": "continue.acceptDiff", "mac": "shift+cmd+enter", "key": "shift+ctrl+enter" }, { - "command": "continue.rejectAllSuggestions", + "command": "continue.rejectDiff", "mac": "shift+cmd+backspace", "key": "shift+ctrl+backspace" } diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx index 61c9ab1e..81b148b9 100644 --- a/extension/react-app/src/components/ComboBox.tsx +++ b/extension/react-app/src/components/ComboBox.tsx @@ -55,7 +55,7 @@ const MainTextInput = styled.textarea` } `; -const UlMaxHeight = 200; +const UlMaxHeight = 400; const Ul = styled.ul<{ hidden: boolean; showAbove: boolean; diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts index 178b1a9d..1b8888e8 100644 --- a/extension/src/diffs.ts +++ b/extension/src/diffs.ts @@ -92,7 +92,14 @@ class DiffManager { fs.unlinkSync(diffInfo.newFilepath); } - acceptDiff(newFilepath: string) { + acceptDiff(newFilepath?: string) { + // If no newFilepath is provided and there is only one in the dictionary, use that + if (!newFilepath && this.diffs.size === 1) { + newFilepath = Array.from(this.diffs.keys())[0]; + } + if (!newFilepath) { + return; + } // Get the diff info, copy new file to original, then delete from record and close the corresponding editor const diffInfo = this.diffs.get(newFilepath); if (!diffInfo) { @@ -105,7 +112,14 @@ class DiffManager { this.cleanUpDiff(diffInfo); } - rejectDiff(newFilepath: string) { + rejectDiff(newFilepath?: string) { + // If no newFilepath is provided and there is only one in the dictionary, use that + if (!newFilepath && this.diffs.size === 1) { + newFilepath = Array.from(this.diffs.keys())[0]; + } + if (!newFilepath) { + return; + } const diffInfo = this.diffs.get(newFilepath); if (!diffInfo) { return; @@ -117,10 +131,10 @@ class DiffManager { export const diffManager = new DiffManager(); -export async function acceptDiffCommand(newFilepath: string) { +export async function acceptDiffCommand(newFilepath?: string) { diffManager.acceptDiff(newFilepath); } -export async function rejectDiffCommand(newFilepath: string) { +export async function rejectDiffCommand(newFilepath?: string) { diffManager.rejectDiff(newFilepath); } -- cgit v1.2.3-70-g09d2