summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--continuedev/src/continuedev/core/autopilot.py10
-rw-r--r--continuedev/src/continuedev/libs/util/calculate_diff.py14
-rw-r--r--continuedev/src/continuedev/server/gui.py10
-rw-r--r--continuedev/src/continuedev/server/gui_protocol.py8
-rw-r--r--continuedev/src/continuedev/steps/core/core.py2
-rw-r--r--extension/react-app/src/components/StepContainer.tsx44
-rw-r--r--extension/react-app/src/components/index.ts18
-rw-r--r--extension/react-app/src/hooks/ContinueGUIClientProtocol.ts6
-rw-r--r--extension/react-app/src/hooks/useContinueGUIProtocol.ts8
-rw-r--r--extension/react-app/src/tabs/gui.tsx272
10 files changed, 245 insertions, 147 deletions
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) {
<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}>
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/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index 9f7e651f..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,129 +42,128 @@ 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` 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 [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();
@@ -261,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>
@@ -288,6 +309,9 @@ function GUI(props: GUIProps) {
client?.retryAtIndex(index);
setWaitingForSteps(true);
}}
+ onDelete={() => {
+ client?.deleteAtIndex(index);
+ }}
/>
);
})}