From 792b65745b89bb59802294357378113493d25b63 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 12 Jun 2023 10:50:33 -0700 Subject: calculate diff and highlight changes --- extension/package.json | 80 ---------------------- extension/react-app/src/components/CodeBlock.tsx | 1 + .../react-app/src/components/StepContainer.tsx | 23 ++++++- extension/react-app/src/tabs/chat/MessageDiv.tsx | 4 +- extension/react-app/src/tabs/gui.tsx | 20 ++++-- extension/src/continueIdeClient.ts | 31 ++++++++- extension/src/decorations.ts | 19 +++-- 7 files changed, 83 insertions(+), 95 deletions(-) (limited to 'extension') diff --git a/extension/package.json b/extension/package.json index 1d2fd995..8ee8cb4c 100644 --- a/extension/package.json +++ b/extension/package.json @@ -54,93 +54,13 @@ } }, "commands": [ - { - "command": "continue.writeDocstring", - "category": "Continue", - "title": "Write a docstring for the current function" - }, { "command": "continue.openContinueGUI", "category": "Continue", "title": "Open Continue GUI" - }, - { - "command": "continue.askQuestionFromInput", - "Category": "Continue", - "title": "Ask a question from input box" - }, - { - "command": "continue.openCapturedTerminal", - "Category": "Continue", - "title": "Open Captured Terminal" - }, - { - "command": "continue.askQuestion", - "Category": "Continue", - "title": "Ask a question from webview" - }, - { - "command": "continue.createTerminal", - "category": "Continue", - "title": "Create Terminal" - }, - { - "command": "continue.debugTest", - "category": "Continue", - "title": "Debug Test" - }, - { - "command": "continue.suggestionDown", - "category": "Continue", - "title": "Suggestion Down" - }, - { - "command": "continue.suggestionUp", - "category": "Continue", - "title": "Suggestion Up" - }, - { - "command": "continue.acceptSuggestion", - "category": "Continue", - "title": "Accept Suggestion" - }, - { - "command": "continue.rejectSuggestion", - "category": "Continue", - "title": "Reject Suggestion" - }, - { - "command": "continue.writeUnitTest", - "title": "Write Unit Test", - "category": "Continue" - }, - { - "command": "continue.findSuspiciousCode", - "title": "Find Suspicious Code", - "category": "Continue" - }, - { - "command": "continue.focusContinueInput", - "title": "Focus Continue Input", - "category": "Continue" } ], "keybindings": [ - { - "command": "continue.suggestionDown", - "mac": "shift+ctrl+down", - "key": "shift+ctrl+down" - }, - { - "command": "continue.suggestionUp", - "mac": "shift+ctrl+up", - "key": "shift+ctrl+up" - }, - { - "command": "continue.acceptSuggestion", - "mac": "shift+ctrl+enter", - "key": "shift+ctrl+enter" - }, { "command": "continue.focusContinueInput", "mac": "cmd+k", 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 8ea54325..fb0143b5 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -84,6 +84,15 @@ const OnHoverDiv = styled.div` 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 @@ -182,7 +191,19 @@ function StepContainer(props: StepContainerProps) { {props.historyNode.observation.error as string} ) : ( - + { + return ( + + ); + }, + }} + > {props.historyNode.step.description as any} )} 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([{props.content}]); + setRichContent([ + , + ]); }, [props.content]); return ( diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 5c75579b..9f7e651f 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -41,7 +41,7 @@ function GUI(props: GUIProps) { // 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`", + // "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", @@ -92,7 +92,7 @@ function GUI(props: GUIProps) { // 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 \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", + // "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, @@ -154,22 +154,30 @@ function GUI(props: GUIProps) { // output: [null, null], // }, // ], - // current_index: 0, + // current_index: 3, // } as any); const topGuiDivRef = useRef(null); const client = useContinueGUIProtocol(); + const [scrollTimeout, setScrollTimeout] = useState( + 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); diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index bbaf5f08..c395ae0e 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -13,6 +13,7 @@ import { FileEditWithFullContents } from "../schema/FileEditWithFullContents"; import fs = require("fs"); import { WebsocketMessenger } from "./util/messenger"; import { CapturedTerminal } from "./terminal/terminalEmulator"; +import { decorationManager } from "./decorations"; class IdeProtocolClient { private messenger: WebsocketMessenger | null = null; @@ -281,8 +282,36 @@ class IdeProtocolClient { edit.range.start.line, edit.range.start.character, edit.range.end.line, - edit.range.end.character + 1 + edit.range.end.character ); + const decorationKey = + edit.replacement === "" + ? { + editorUri: editor.document.uri.fsPath, + options: { + range: new vscode.Range( + new vscode.Position(range.start.line, 0), + new vscode.Position(range.end.line + 1, 0) + ), + // after: { + // contentText: "Removed", + // }, + }, + decorationType: vscode.window.createTextEditorDecorationType({ + backgroundColor: "rgba(255, 0, 0, 0.2)", + }), + } + : { + editorUri: editor.document.uri.fsPath, + options: { + range, + }, + decorationType: vscode.window.createTextEditorDecorationType({ + backgroundColor: "rgba(66, 105, 55, 1.0)", + isWholeLine: true, + }), + }; + decorationManager.addDecoration(decorationKey); editor.edit((editBuilder) => { this._makingEdit += 2; // editBuilder.replace takes 2 edits: delete and insert editBuilder.replace(range, edit.replacement); diff --git a/extension/src/decorations.ts b/extension/src/decorations.ts index 456f0c10..d2c94135 100644 --- a/extension/src/decorations.ts +++ b/extension/src/decorations.ts @@ -94,15 +94,22 @@ class DecorationManager { decorationTypes = new Map(); decorationTypes.set(key.decorationType, [key.options]); this.editorToDecorations.set(key.editorUri, decorationTypes); - } - - const decorations = decorationTypes.get(key.decorationType); - if (!decorations) { - decorationTypes.set(key.decorationType, [key.options]); } else { - decorations.push(key.options); + const decorations = decorationTypes.get(key.decorationType); + if (!decorations) { + decorationTypes.set(key.decorationType, [key.options]); + } else { + decorations.push(key.options); + } } + this.rerenderDecorations(key.editorUri, key.decorationType); + + vscode.window.onDidChangeTextEditorSelection((event) => { + if (event.textEditor.document.fileName === key.editorUri) { + this.deleteAllDecorations(key.editorUri); + } + }); } deleteDecoration(key: DecorationKey) { -- cgit v1.2.3-70-g09d2 From 0851b826c069cbdd1706a4107feb90f0ffa13129 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 12 Jun 2023 12:21:26 -0700 Subject: cleaner highlighting (from server side) --- .../src/continuedev/server/session_manager.py | 1 + continuedev/src/continuedev/steps/core/core.py | 45 +++++++++++++++++++--- continuedev/src/continuedev/steps/main.py | 28 +++++++++++--- extension/src/continueIdeClient.ts | 31 +-------------- 4 files changed, 65 insertions(+), 40 deletions(-) (limited to 'extension') diff --git a/continuedev/src/continuedev/server/session_manager.py b/continuedev/src/continuedev/server/session_manager.py index 0dbfaf38..ebea08a5 100644 --- a/continuedev/src/continuedev/server/session_manager.py +++ b/continuedev/src/continuedev/server/session_manager.py @@ -28,6 +28,7 @@ class DemoAutopilot(Autopilot): cumulative_edit_string = "" def handle_manual_edits(self, edits: List[FileEditWithFullContents]): + return for edit in edits: self.cumulative_edit_string += edit.fileEdit.replacement self._manual_edits_buffer.append(edit) diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index 57689f19..4288ffd2 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -3,8 +3,10 @@ import os import subprocess from textwrap import dedent from typing import Coroutine, List, Union -from ...libs.llm.prompt_utils import MarkdownStyleEncoderDecoder +from ...models.main import Range +from ...libs.util.calculate_diff import calculate_diff2, apply_edit_to_str +from ...libs.llm.prompt_utils import MarkdownStyleEncoderDecoder from ...models.filesystem_edit import EditDiff, FileEdit, FileEditWithFullContents, FileSystemEdit from ...models.filesystem import FileSystem, RangeInFile, RangeInFileWithContents from ...core.observation import Observation, TextObservation, TracebackObservation, UserInputObservation @@ -149,7 +151,11 @@ class Gpt35EditCodeStep(Step): _prompt_and_completion: str = "" async def describe(self, models: Models) -> Coroutine[str, None, None]: - return models.gpt35.complete(f"{self._prompt_and_completion}\n\nPlease give brief a description of the changes made above using markdown bullet points:") + description = models.gpt35.complete( + f"{self._prompt_and_completion}\n\nPlease give brief a description of the changes made above using markdown bullet points. Be concise and only mention changes made to the commit before, not prefix or suffix:") + self.name = models.gpt35.complete( + f"Write a short title for this description: {description}") + return description async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]: rif_with_contents = [] @@ -174,11 +180,40 @@ class Gpt35EditCodeStep(Step): self._prompt_and_completion += prompt + completion - await sdk.ide.applyFileSystemEdit( - FileEdit(filepath=rif.filepath, range=rif.range, replacement=completion)) - await sdk.ide.saveFile(rif.filepath) + # Calculate diff, open file, apply edits, and highlight changed lines + edits = calculate_diff2( + rif.filepath, rif.contents, completion.removesuffix("\n")) + await sdk.ide.setFileOpen(rif.filepath) + lines_to_highlight = set() + for edit in edits: + edit.range.start.line += rif.range.start.line + edit.range.start.character += rif.range.start.character + edit.range.end.line += rif.range.start.line + edit.range.end.character += rif.range.start.character if edit.range.end.line == 0 else 0 + + for line in range(edit.range.start.line, edit.range.end.line + 1): + lines_to_highlight.add(line) + + await sdk.ide.applyFileSystemEdit(edit) + + current_start = None + last_line = None + for line in sorted(list(lines_to_highlight)): + if current_start is None: + current_start = line + elif line != last_line + 1: + await sdk.ide.highlightCode(RangeInFile(filepath=edit.filepath, range=Range.from_shorthand(current_start, 0, last_line, 0))) + current_start = line + + last_line = line + + if current_start is not None: + await sdk.ide.highlightCode(RangeInFile(filepath=edit.filepath, range=Range.from_shorthand(current_start, 0, last_line, 0))) + + await sdk.ide.saveFile(rif.filepath) + class EditFileStep(Step): filepath: str diff --git a/continuedev/src/continuedev/steps/main.py b/continuedev/src/continuedev/steps/main.py index 24335b4f..9634c726 100644 --- a/continuedev/src/continuedev/steps/main.py +++ b/continuedev/src/continuedev/steps/main.py @@ -16,6 +16,7 @@ from ..core.sdk import ContinueSDK, Models from ..core.observation import Observation import subprocess from .core.core import Gpt35EditCodeStep +from ..libs.util.calculate_diff import calculate_diff2 class SetupContinueWorkspaceStep(Step): @@ -216,7 +217,8 @@ class StarCoderEditHighlightedCodeStep(Step): async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]: range_in_files = await sdk.ide.getHighlightedCode() - if len(range_in_files) == 0: + found_highlighted_code = len(range_in_files) > 0 + if not found_highlighted_code: # Get the full contents of all open files files = await sdk.ide.getOpenFiles() contents = {} @@ -239,15 +241,29 @@ class StarCoderEditHighlightedCodeStep(Step): for rif in rif_with_contents: prompt = self._prompt.format( code=rif.contents, user_request=self.user_input) - completion = str(sdk.models.starcoder.complete(prompt)) + + if found_highlighted_code: + full_file_contents = await sdk.ide.readFile(rif.filepath) + segs = full_file_contents.split(rif.contents) + prompt = f"{segs[0]}{segs[1]}" + prompt + + completion = str((await sdk.models.starcoder()).complete(prompt)) eot_token = "<|endoftext|>" - if completion.endswith(eot_token): - completion = completion[:completion.rindex(eot_token)] + completion = completion.removesuffix(eot_token) + + if found_highlighted_code: + rif.contents = segs[0] + rif.contents + segs[1] + completion = segs[0] + completion + segs[1] self._prompt_and_completion += prompt + completion - await sdk.ide.applyFileSystemEdit( - FileEdit(filepath=rif.filepath, range=rif.range, replacement=completion)) + edits = calculate_diff2( + rif.filepath, rif.contents, completion.removesuffix("\n")) + for edit in edits: + await sdk.ide.applyFileSystemEdit(edit) + + # await sdk.ide.applyFileSystemEdit( + # FileEdit(filepath=rif.filepath, range=rif.range, replacement=completion)) await sdk.ide.saveFile(rif.filepath) await sdk.ide.setFileOpen(rif.filepath) diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index c395ae0e..035778a5 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -278,40 +278,13 @@ class IdeProtocolClient { undefined, vscode.ViewColumn.One ).then((editor) => { - let range = new vscode.Range( + const range = new vscode.Range( edit.range.start.line, edit.range.start.character, edit.range.end.line, edit.range.end.character ); - const decorationKey = - edit.replacement === "" - ? { - editorUri: editor.document.uri.fsPath, - options: { - range: new vscode.Range( - new vscode.Position(range.start.line, 0), - new vscode.Position(range.end.line + 1, 0) - ), - // after: { - // contentText: "Removed", - // }, - }, - decorationType: vscode.window.createTextEditorDecorationType({ - backgroundColor: "rgba(255, 0, 0, 0.2)", - }), - } - : { - editorUri: editor.document.uri.fsPath, - options: { - range, - }, - decorationType: vscode.window.createTextEditorDecorationType({ - backgroundColor: "rgba(66, 105, 55, 1.0)", - isWholeLine: true, - }), - }; - decorationManager.addDecoration(decorationKey); + editor.edit((editBuilder) => { this._makingEdit += 2; // editBuilder.replace takes 2 edits: delete and insert editBuilder.replace(range, edit.replacement); -- cgit v1.2.3-70-g09d2 From a13cb867ec0ea831d78e6d928463bd256babced5 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Mon, 12 Jun 2023 13:18:16 -0700 Subject: clear history and delete step buttons --- continuedev/src/continuedev/core/autopilot.py | 10 + .../src/continuedev/libs/util/calculate_diff.py | 14 ++ continuedev/src/continuedev/server/gui.py | 10 + continuedev/src/continuedev/server/gui_protocol.py | 8 + continuedev/src/continuedev/steps/core/core.py | 2 +- .../react-app/src/components/StepContainer.tsx | 44 ++-- extension/react-app/src/components/index.ts | 18 ++ .../src/hooks/ContinueGUIClientProtocol.ts | 6 + .../react-app/src/hooks/useContinueGUIProtocol.ts | 8 + extension/react-app/src/tabs/gui.tsx | 272 +++++++++++---------- 10 files changed, 245 insertions(+), 147 deletions(-) (limited to 'extension') diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py index c979d53a..1642003c 100644 --- a/continuedev/src/continuedev/core/autopilot.py +++ b/continuedev/src/continuedev/core/autopilot.py @@ -40,6 +40,12 @@ class Autopilot(ContinueBaseModel): def get_full_state(self) -> FullState: return FullState(history=self.history, active=self._active, user_input_queue=self._main_user_input_queue) + async def clear_history(self): + self.history = History.from_empty() + self._main_user_input_queue = [] + self._active = False + await self.update_subscribers() + def on_update(self, callback: Coroutine["FullState", None, None]): """Subscribe to changes to state""" self._on_update_callbacks.append(callback) @@ -88,6 +94,10 @@ class Autopilot(ContinueBaseModel): async def retry_at_index(self, index: int): self._retry_queue.post(str(index), None) + async def delete_at_index(self, index: int): + self.history.timeline[index].step.hide = True + await self.update_subscribers() + async def _run_singular_step(self, step: "Step", is_future_step: bool = False) -> Coroutine[Observation, None, None]: capture_event( 'step run', {'step_name': step.name, 'params': step.dict()}) diff --git a/continuedev/src/continuedev/libs/util/calculate_diff.py b/continuedev/src/continuedev/libs/util/calculate_diff.py index d778891b..ff0a135f 100644 --- a/continuedev/src/continuedev/libs/util/calculate_diff.py +++ b/continuedev/src/continuedev/libs/util/calculate_diff.py @@ -67,6 +67,20 @@ def calculate_diff(filepath: str, original: str, updated: str) -> List[FileEdit] def calculate_diff2(filepath: str, original: str, updated: str) -> List[FileEdit]: + # original_lines = original.splitlines() + # updated_lines = updated.splitlines() + # offset = 0 + # while len(original_lines) and len(updated_lines) and original_lines[0] == updated_lines[0]: + # original_lines = original_lines[1:] + # updated_lines = updated_lines[1:] + + # while len(original_lines) and len(updated_lines) and original_lines[-1] == updated_lines[-1]: + # original_lines = original_lines[:-1] + # updated_lines = updated_lines[:-1] + + # original = "\n".join(original_lines) + # updated = "\n".join(updated_lines) + edits = [] max_iterations = 1000 i = 0 diff --git a/continuedev/src/continuedev/server/gui.py b/continuedev/src/continuedev/server/gui.py index b873a88f..e8b52004 100644 --- a/continuedev/src/continuedev/server/gui.py +++ b/continuedev/src/continuedev/server/gui.py @@ -77,6 +77,10 @@ class GUIProtocolServer(AbstractGUIProtocolServer): self.on_reverse_to_index(data["index"]) elif message_type == "retry_at_index": self.on_retry_at_index(data["index"]) + elif message_type == "clear_history": + self.on_clear_history() + elif message_type == "delete_at_index": + self.on_delete_at_index(data["index"]) except Exception as e: print(e) @@ -106,6 +110,12 @@ class GUIProtocolServer(AbstractGUIProtocolServer): asyncio.create_task( self.session.autopilot.retry_at_index(index)) + def on_clear_history(self): + asyncio.create_task(self.session.autopilot.clear_history()) + + def on_delete_at_index(self, index: int): + asyncio.create_task(self.session.autopilot.delete_at_index(index)) + @router.websocket("/ws") async def websocket_endpoint(websocket: WebSocket, session: Session = Depends(websocket_session)): diff --git a/continuedev/src/continuedev/server/gui_protocol.py b/continuedev/src/continuedev/server/gui_protocol.py index 287f9e3b..889c6761 100644 --- a/continuedev/src/continuedev/server/gui_protocol.py +++ b/continuedev/src/continuedev/server/gui_protocol.py @@ -30,3 +30,11 @@ class AbstractGUIProtocolServer(ABC): @abstractmethod def on_retry_at_index(self, index: int): """Called when the user requests a retry at a previous index""" + + @abstractmethod + def on_clear_history(self): + """Called when the user requests to clear the history""" + + @abstractmethod + def on_delete_at_index(self, index: int): + """Called when the user requests to delete a step at a given index""" diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index 4288ffd2..dacf0e7b 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -193,7 +193,7 @@ class Gpt35EditCodeStep(Step): edit.range.end.line += rif.range.start.line edit.range.end.character += rif.range.start.character if edit.range.end.line == 0 else 0 - for line in range(edit.range.start.line, edit.range.end.line + 1): + for line in range(edit.range.start.line, edit.range.end.line + 1 + len(edit.replacement.splitlines()) - (edit.range.end.line - edit.range.start.line + 1)): lines_to_highlight.add(line) await sdk.ide.applyFileSystemEdit(edit) diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index fb0143b5..2d85b4f0 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,20 +68,6 @@ 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; @@ -161,18 +151,28 @@ function StepContainer(props: StepContainerProps) { */} - {props.historyNode.observation?.error ? ( + <> { e.stopPropagation(); - props.onRetry(); + props.onDelete(); }} > - + - ) : ( - <> - )} + {props.historyNode.observation?.error ? ( + { + e.stopPropagation(); + props.onRetry(); + }} + > + + + ) : ( + <> + )} +