summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--continuedev/src/continuedev/core/main.py3
-rw-r--r--continuedev/src/continuedev/core/policy.py4
-rw-r--r--continuedev/src/continuedev/core/sdk.py3
-rw-r--r--continuedev/src/continuedev/server/ide.py11
-rw-r--r--continuedev/src/continuedev/server/ide_protocol.py6
-rw-r--r--continuedev/src/continuedev/steps/chat.py10
-rw-r--r--continuedev/src/continuedev/steps/core/core.py5
-rw-r--r--continuedev/src/continuedev/steps/custom_command.py11
-rw-r--r--continuedev/src/continuedev/steps/on_traceback.py8
-rw-r--r--extension/package-lock.json4
-rw-r--r--extension/package.json6
-rw-r--r--extension/react-app/src/components/ComboBox.tsx7
-rw-r--r--extension/react-app/src/tabs/gui.tsx10
-rw-r--r--extension/src/activation/environmentSetup.ts4
-rw-r--r--extension/src/continueIdeClient.ts10
-rw-r--r--extension/src/diffs.ts22
17 files changed, 77 insertions, 49 deletions
diff --git a/README.md b/README.md
index c72bbb53..a91fbdf4 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
![Twitter URL](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Fgithub.com%2Fcontinuedev%2Fcontinue)
- <a target="_blank" href="https://discord.gg/DvACJvjx" style="background:none">
+ <a target="_blank" href="https://discord.gg/vapESyrFmJ" style="background:none">
<img src="https://img.shields.io/badge/discord-join-continue.svg?labelColor=191937&color=6F6FF7&logo=discord" />
</a>
diff --git a/continuedev/src/continuedev/core/main.py b/continuedev/src/continuedev/core/main.py
index 403e5417..4ea17f20 100644
--- a/continuedev/src/continuedev/core/main.py
+++ b/continuedev/src/continuedev/core/main.py
@@ -38,7 +38,8 @@ class ChatMessage(ContinueBaseModel):
del d[key]
if not with_functions:
- d["role"] = "assistant"
+ if d["role"] == "function":
+ d["role"] = "assistant"
if "name" in d:
del d["name"]
if "function_call" in d:
diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py
index 6ee2d03f..b8363df2 100644
--- a/continuedev/src/continuedev/core/policy.py
+++ b/continuedev/src/continuedev/core/policy.py
@@ -46,7 +46,7 @@ def parse_custom_command(inp: str, config: ContinueConfig) -> Union[None, Step]:
slash_command = parse_slash_command(custom_cmd.prompt, config)
if slash_command is not None:
return slash_command
- return CustomCommandStep(name=custom_cmd.name, description=custom_cmd.description, prompt=custom_cmd.prompt, user_input=after_command)
+ return CustomCommandStep(name=custom_cmd.name, description=custom_cmd.description, prompt=custom_cmd.prompt, user_input=after_command, slash_command=command_name)
return None
@@ -82,6 +82,6 @@ class DemoPolicy(Policy):
if custom_command is not None:
return custom_command
- return SimpleChatStep(user_input=user_input)
+ return SimpleChatStep()
return None
diff --git a/continuedev/src/continuedev/core/sdk.py b/continuedev/src/continuedev/core/sdk.py
index 49513013..ed670799 100644
--- a/continuedev/src/continuedev/core/sdk.py
+++ b/continuedev/src/continuedev/core/sdk.py
@@ -192,7 +192,8 @@ class ContinueSDK(AbstractContinueSDK):
async def get_chat_context(self) -> List[ChatMessage]:
history_context = self.history.to_chat_history()
- highlighted_code = self.__autopilot._highlighted_ranges
+ highlighted_code = [
+ hr.range for hr in self.__autopilot._highlighted_ranges]
preface = "The following code is highlighted"
diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py
index 1d51758e..e4a6266a 100644
--- a/continuedev/src/continuedev/server/ide.py
+++ b/continuedev/src/continuedev/server/ide.py
@@ -152,6 +152,8 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
self.onAcceptRejectDiff(data["accepted"])
elif message_type == "mainUserInput":
self.onMainUserInput(data["input"])
+ elif message_type == "deleteAtIndex":
+ self.onDeleteAtIndex(data["index"])
elif message_type in ["highlightedCode", "openFiles", "readFile", "editFile", "workspaceDirectory", "getUserSecret", "runCommand", "uniqueId"]:
self.sub_queue.post(message_type, data)
else:
@@ -164,10 +166,11 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
"edit": file_edit.dict()
})
- async def showDiff(self, filepath: str, replacement: str):
+ async def showDiff(self, filepath: str, replacement: str, step_index: int):
await self._send_json("showDiff", {
"filepath": filepath,
- "replacement": replacement
+ "replacement": replacement,
+ "step_index": step_index
})
async def setFileOpen(self, filepath: str, open: bool = True):
@@ -245,6 +248,10 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
for _, session in self.session_manager.sessions.items():
session.autopilot.handle_manual_edits(edits)
+ def onDeleteAtIndex(self, index: int):
+ for _, session in self.session_manager.sessions.items():
+ asyncio.create_task(session.autopilot.delete_at_index(index))
+
def onCommandOutput(self, output: str):
# Send the output to ALL autopilots.
# Maybe not ideal behavior
diff --git a/continuedev/src/continuedev/server/ide_protocol.py b/continuedev/src/continuedev/server/ide_protocol.py
index 2e1f78d7..dfdca504 100644
--- a/continuedev/src/continuedev/server/ide_protocol.py
+++ b/continuedev/src/continuedev/server/ide_protocol.py
@@ -96,7 +96,11 @@ class AbstractIdeProtocolServer(ABC):
"""Called when highlighted code is updated"""
@abstractmethod
- async def showDiff(self, filepath: str, replacement: str):
+ def onDeleteAtIndex(self, index: int):
+ """Called when a step is deleted at a given index"""
+
+ @abstractmethod
+ async def showDiff(self, filepath: str, replacement: str, step_index: int):
"""Show a diff"""
@abstractproperty
diff --git a/continuedev/src/continuedev/steps/chat.py b/continuedev/src/continuedev/steps/chat.py
index c26f8ff9..a10319d8 100644
--- a/continuedev/src/continuedev/steps/chat.py
+++ b/continuedev/src/continuedev/steps/chat.py
@@ -19,19 +19,15 @@ openai.api_key = OPENAI_API_KEY
class SimpleChatStep(Step):
- user_input: str
name: str = "Generating Response..."
manage_own_chat_context: bool = True
description: str = ""
+ messages: List[ChatMessage] = None
async def run(self, sdk: ContinueSDK):
- if self.user_input.strip() == "":
- self.user_input = "Explain this code's function is a concise list of markdown bullets."
- self.description = ""
- await sdk.update_ui()
-
completion = ""
- async for chunk in sdk.models.gpt4.stream_chat(await sdk.get_chat_context()):
+ messages = self.messages or await sdk.get_chat_context()
+ async for chunk in sdk.models.gpt4.stream_chat(messages, temperature=0.5):
if sdk.current_step_was_deleted():
return
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index f22297ae..10853828 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -305,7 +305,10 @@ class DefaultModelEditCodeStep(Step):
full_suffix_lines = full_file_contents_lines[rif.range.end.line:]
new_file_contents = "\n".join(
full_prefix_lines) + "\n" + completion + "\n" + "\n".join(full_suffix_lines)
- await sdk.ide.showDiff(rif.filepath, new_file_contents)
+
+ step_index = sdk.history.current_index
+
+ await sdk.ide.showDiff(rif.filepath, new_file_contents, step_index)
# Important state variables
# -------------------------
diff --git a/continuedev/src/continuedev/steps/custom_command.py b/continuedev/src/continuedev/steps/custom_command.py
index 9d675091..5a56efb0 100644
--- a/continuedev/src/continuedev/steps/custom_command.py
+++ b/continuedev/src/continuedev/steps/custom_command.py
@@ -1,5 +1,6 @@
from ..core.main import Step
from ..core.sdk import ContinueSDK
+from ..steps.core.core import UserInputStep
from ..steps.chat import ChatWithFunctions, SimpleChatStep
@@ -7,6 +8,7 @@ class CustomCommandStep(Step):
name: str
prompt: str
user_input: str
+ slash_command: str
hide: bool = True
async def describe(self):
@@ -14,4 +16,11 @@ class CustomCommandStep(Step):
async def run(self, sdk: ContinueSDK):
prompt_user_input = f"Task: {self.prompt}. Additional info: {self.user_input}"
- await sdk.run_step(SimpleChatStep(user_input=prompt_user_input))
+ messages = await sdk.get_chat_context()
+ # Find the last chat message with this slash command and replace it with the user input
+ for i in range(len(messages) - 1, -1, -1):
+ if messages[i].role == "user" and messages[i].content.startswith(self.slash_command):
+ messages[i] = messages[i].copy(
+ update={"content": prompt_user_input})
+ break
+ await sdk.run_step(SimpleChatStep(messages=messages))
diff --git a/continuedev/src/continuedev/steps/on_traceback.py b/continuedev/src/continuedev/steps/on_traceback.py
index 3f8c5a76..efb4c703 100644
--- a/continuedev/src/continuedev/steps/on_traceback.py
+++ b/continuedev/src/continuedev/steps/on_traceback.py
@@ -1,4 +1,6 @@
import os
+
+from .core.core import UserInputStep
from ..core.main import ChatMessage, Step
from ..core.sdk import ContinueSDK
from .chat import SimpleChatStep
@@ -21,7 +23,5 @@ class DefaultOnTracebackStep(Step):
content=f"The contents of {seg}:\n```\n{file_contents}\n```",
summary=""
))
-
- await sdk.run_step(SimpleChatStep(
- name="Help With Traceback",
- user_input=f"""I got the following error, can you please help explain how to fix it?\n\n{self.output}"""))
+ await sdk.run_step(UserInputStep(user_input=f"""I got the following error, can you please help explain how to fix it?\n\n{self.output}"""))
+ await sdk.run_step(SimpleChatStep(name="Help With Traceback"))
diff --git a/extension/package-lock.json b/extension/package-lock.json
index 7b1ad703..043f0892 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.118",
+ "version": "0.0.125",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.118",
+ "version": "0.0.125",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index f5ded456..1d4b8055 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.118",
+ "version": "0.0.125",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
@@ -146,8 +146,8 @@
},
{
"command": "continue.quickTextEntry",
- "mac": "cmd+h",
- "key": "ctrl+h"
+ "mac": "cmd+shift+l",
+ "key": "ctrl+shift+l"
}
],
"menus": {
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx
index 4dab8bcd..e6632360 100644
--- a/extension/react-app/src/components/ComboBox.tsx
+++ b/extension/react-app/src/components/ComboBox.tsx
@@ -293,8 +293,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
event.key === "Enter" &&
(!downshiftProps.isOpen || items.length === 0)
) {
- downshiftProps.setInputValue("");
- const value = event.currentTarget.value;
+ const value = downshiftProps.inputValue;
if (value !== "") {
setPositionInHistory(history.length + 1);
setHistory([...history, value]);
@@ -302,10 +301,6 @@ 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.value}`;
- }
if (props.onEnter) props.onEnter(event);
} else if (event.key === "Tab" && items.length > 0) {
downshiftProps.setInputValue(items[0].name);
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index 1ea70dd2..e1ecec9e 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -217,9 +217,13 @@ function GUI(props: GUIProps) {
[client]
);
- const onMainTextInput = () => {
+ const onMainTextInput = (event?: any) => {
if (mainTextInputRef.current) {
- const input = (mainTextInputRef.current as any).inputValue;
+ let input = (mainTextInputRef.current as any).inputValue;
+ // cmd+enter to /edit
+ if (event?.metaKey) {
+ input = `/edit ${input}`;
+ }
(mainTextInputRef.current as any).setInputValue("");
if (!client) return;
@@ -352,7 +356,7 @@ function GUI(props: GUIProps) {
// }
ref={mainTextInputRef}
onEnter={(e) => {
- onMainTextInput();
+ onMainTextInput(e);
e.stopPropagation();
e.preventDefault();
}}
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index f6cc129e..bbf93f65 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -10,7 +10,7 @@ import * as vscode from "vscode";
import fkill from "fkill";
import { sendTelemetryEvent, TelemetryEvent } from "../telemetry";
-const MAX_RETRIES = 0;
+const MAX_RETRIES = 3;
async function retryThenFail(
fn: () => Promise<any>,
retries: number = MAX_RETRIES
@@ -197,7 +197,7 @@ async function setupPythonEnv() {
} else if (stderr) {
if (stderr.includes("running scripts is disabled on this system")) {
vscode.window.showErrorMessage(
- "A Python virtual enviroment cannot be activated because running scripts is disabled for this user. Please enable signed scripts to run with this command in PowerShell: `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`, reload VS Code, and then try again."
+ "A Python virtual enviroment cannot be activated because running scripts is disabled for this user. Please enable signed scripts to run with this command in PowerShell: `Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser`, reload VS Code, and then try again."
);
}
throw new Error(stderr);
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts
index 9b16a7a2..679d94ba 100644
--- a/extension/src/continueIdeClient.ts
+++ b/extension/src/continueIdeClient.ts
@@ -164,7 +164,7 @@ class IdeProtocolClient {
this.showSuggestion(data.edit);
break;
case "showDiff":
- this.showDiff(data.filepath, data.replacement);
+ this.showDiff(data.filepath, data.replacement, data.step_index);
break;
case "openGUI":
case "connected":
@@ -243,8 +243,8 @@ class IdeProtocolClient {
);
}
- showDiff(filepath: string, replacement: string) {
- diffManager.writeDiff(filepath, replacement);
+ showDiff(filepath: string, replacement: string, step_index: number) {
+ diffManager.writeDiff(filepath, replacement, step_index);
}
openFile(filepath: string) {
@@ -431,6 +431,10 @@ class IdeProtocolClient {
sendMainUserInput(input: string) {
this.messenger?.send("mainUserInput", { input });
}
+
+ deleteAtIndex(index: number) {
+ this.messenger?.send("deleteAtIndex", { index });
+ }
}
export default IdeProtocolClient;
diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts
index 52a54046..dbfd8f59 100644
--- a/extension/src/diffs.ts
+++ b/extension/src/diffs.ts
@@ -8,6 +8,7 @@ interface DiffInfo {
originalFilepath: string;
newFilepath: string;
editor?: vscode.TextEditor;
+ step_index: number;
}
export const DIFF_DIRECTORY = path.join(os.homedir(), ".continue", "diffs");
@@ -36,8 +37,7 @@ class DiffManager {
private openDiffEditor(
originalFilepath: string,
- newFilepath: string,
- newContent: string
+ newFilepath: string
): vscode.TextEditor | undefined {
// If the file doesn't yet exist, don't open the diff editor
if (!fs.existsSync(newFilepath)) {
@@ -62,7 +62,11 @@ class DiffManager {
return editor;
}
- writeDiff(originalFilepath: string, newContent: string): string {
+ writeDiff(
+ originalFilepath: string,
+ newContent: string,
+ step_index: number
+ ): string {
this.setupDirectory();
// Create or update existing diff
@@ -77,6 +81,7 @@ class DiffManager {
const diffInfo: DiffInfo = {
originalFilepath,
newFilepath,
+ step_index,
};
this.diffs.set(newFilepath, diffInfo);
}
@@ -84,11 +89,7 @@ class DiffManager {
// Open the editor if it hasn't been opened yet
const diffInfo = this.diffs.get(newFilepath);
if (diffInfo && !diffInfo?.editor) {
- diffInfo.editor = this.openDiffEditor(
- originalFilepath,
- newFilepath,
- newContent
- );
+ diffInfo.editor = this.openDiffEditor(originalFilepath, newFilepath);
this.diffs.set(newFilepath, diffInfo);
}
@@ -101,7 +102,7 @@ class DiffManager {
vscode.window.showTextDocument(diffInfo.editor.document);
vscode.commands.executeCommand("workbench.action.closeActiveEditor");
}
- // this.diffs.delete(diffInfo.newFilepath);
+ this.diffs.delete(diffInfo.newFilepath);
fs.unlinkSync(diffInfo.newFilepath);
}
@@ -138,6 +139,9 @@ class DiffManager {
return;
}
+ // Stop the step at step_index in case it is still streaming
+ ideProtocolClient.deleteAtIndex(diffInfo.step_index);
+
this.cleanUpDiff(diffInfo);
}
}