diff options
-rw-r--r-- | continuedev/src/continuedev/server/ide.py | 9 | ||||
-rw-r--r-- | continuedev/src/continuedev/server/ide_protocol.py | 4 | ||||
-rw-r--r-- | continuedev/src/continuedev/steps/chat.py | 22 | ||||
-rw-r--r-- | continuedev/src/continuedev/steps/core/core.py | 3 | ||||
-rw-r--r-- | extension/src/continueIdeClient.ts | 9 | ||||
-rw-r--r-- | extension/src/debugPanel.ts | 18 | ||||
-rw-r--r-- | extension/src/lang-server/codeLens.ts | 7 | ||||
-rw-r--r-- | extension/src/suggestions.ts | 1 |
8 files changed, 55 insertions, 18 deletions
diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py index cc8cb15e..65f3ee74 100644 --- a/continuedev/src/continuedev/server/ide.py +++ b/continuedev/src/continuedev/server/ide.py @@ -132,6 +132,8 @@ class IdeProtocolServer(AbstractIdeProtocolServer): await self.openGUI() elif message_type == "setFileOpen": await self.setFileOpen(data["filepath"], data["open"]) + elif message_type == "setSuggestionsLocked": + await self.setSuggestionsLocked(data["filepath"], data["locked"]) elif message_type == "fileEdits": fileEdits = list( map(lambda d: FileEditWithFullContents.parse_obj(d), data["fileEdits"])) @@ -158,6 +160,13 @@ class IdeProtocolServer(AbstractIdeProtocolServer): "open": open }) + async def setSuggestionsLocked(self, filepath: str, locked: bool = True): + # Lock suggestions in the file so they don't ruin the offset before others are inserted + await self._send_json("setSuggestionsLocked", { + "filepath": filepath, + "locked": locked + }) + async def openGUI(self): session_id = self.session_manager.new_session(self) await self._send_json("openGUI", { diff --git a/continuedev/src/continuedev/server/ide_protocol.py b/continuedev/src/continuedev/server/ide_protocol.py index 79820c36..d2dafa9a 100644 --- a/continuedev/src/continuedev/server/ide_protocol.py +++ b/continuedev/src/continuedev/server/ide_protocol.py @@ -24,6 +24,10 @@ class AbstractIdeProtocolServer(ABC): """Set whether a file is open""" @abstractmethod + async def setSuggestionsLocked(self, filepath: str, locked: bool = True): + """Set whether suggestions are locked""" + + @abstractmethod async def openGUI(self): """Open a GUI""" diff --git a/continuedev/src/continuedev/steps/chat.py b/continuedev/src/continuedev/steps/chat.py index 5b4318c3..6a2c136e 100644 --- a/continuedev/src/continuedev/steps/chat.py +++ b/continuedev/src/continuedev/steps/chat.py @@ -152,8 +152,8 @@ class ChatWithFunctions(Step): )) last_function_called_index_in_history = None - # GPT keeps wanting to call the non-existent 'python' function repeatedly, so limiting to once - already_called_python = False + last_function_called_name = None + last_function_called_params = None while True: was_function_called = False func_args = "" @@ -196,10 +196,8 @@ class ChatWithFunctions(Step): )) break else: + last_function_called = func_name if func_name == "python" and "python" not in step_name_step_class_map: - if already_called_python: - return - already_called_python = True # GPT must be fine-tuned to believe this exists, but it doesn't always func_name = "EditHighlightedCodeStep" func_args = json.dumps({"user_input": self.user_input}) @@ -239,8 +237,6 @@ class ChatWithFunctions(Step): if func_name not in step_name_step_class_map: raise Exception( f"The model tried to call a function ({func_name}) that does not exist. Please try again.") - step_to_run = step_name_step_class_map[func_name]( - **fn_call_params) # if func_name == "AddFileStep": # step_to_run.hide = True @@ -251,9 +247,17 @@ class ChatWithFunctions(Step): # else: # self.description += f"\n`Running function {func_name}`\n\n" if func_name == "EditHighlightedCodeStep": - step_to_run.user_input = self.user_input + fn_call_params["user_input"] = self.user_input elif func_name == "EditFile": - step_to_run.instructions = self.user_input + fn_call_params["instructions"] = self.user_input + + step_to_run = step_name_step_class_map[func_name]( + **fn_call_params) + if last_function_called_name is not None and last_function_called_name == func_name and last_function_called_params is not None and last_function_called_params == fn_call_params: + # If it's calling the same function more than once in a row, it's probably looping and confused + return + last_function_called_name = func_name + last_function_called_params = fn_call_params await sdk.run_step(step_to_run) await sdk.update_ui() diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index e9420ea9..46c6a615 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -490,8 +490,9 @@ class DefaultModelEditCodeStep(Step): for rif in rif_with_contents: await sdk.ide.setFileOpen(rif.filepath) + await sdk.ide.setSuggestionsLocked(rif.filepath, True) await self.stream_rif(rif, sdk) - # await sdk.ide.saveFile(rif.filepath) + await sdk.ide.setSuggestionsLocked(rif.filepath, False) class EditFileStep(Step): diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index 2e641054..1ccc070c 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -1,5 +1,6 @@ // import { ShowSuggestionRequest } from "../schema/ShowSuggestionRequest"; import { + editorSuggestionsLocked, showSuggestion as showSuggestionInEditor, SuggestionRanges, } from "./suggestions"; @@ -119,6 +120,9 @@ class IdeProtocolClient { this.openFile(data.filepath); // TODO: Close file if False break; + case "setSuggestionsLocked": + this.setSuggestionsLocked(data.filepath, data.locked); + break; case "showSuggestion": this.showSuggestion(data.edit); break; @@ -204,6 +208,11 @@ class IdeProtocolClient { openEditorAndRevealRange(filepath, undefined, vscode.ViewColumn.One); } + setSuggestionsLocked(filepath: string, locked: boolean) { + editorSuggestionsLocked.set(filepath, locked); + // TODO: Rerender? + } + async getUserSecret(key: string) { // Check if secret already exists in VS Code settings (global) let secret = vscode.workspace.getConfiguration("continue").get(key); diff --git a/extension/src/debugPanel.ts b/extension/src/debugPanel.ts index 4f3d097c..b176eee7 100644 --- a/extension/src/debugPanel.ts +++ b/extension/src/debugPanel.ts @@ -113,7 +113,13 @@ class WebsocketConnection { if (typeof message !== "string") { message = JSON.stringify(message); } - this._ws.send(message); + if (this._ws.readyState === WebSocket.OPEN) { + this._ws.send(message); + } else { + this._ws.addEventListener("open", () => { + this._ws.send(message); + }); + } } public close() { @@ -231,7 +237,9 @@ export function setupDebugPanel( apiUrl: getContinueServerUrl(), sessionId, vscMediaUrl, - dataSwitchOn: vscode.workspace.getConfiguration("continue").get<boolean>("dataSwitch") + dataSwitchOn: vscode.workspace + .getConfiguration("continue") + .get<boolean>("dataSwitch"), }); // // Listen for changes to server URL in settings @@ -249,10 +257,10 @@ export function setupDebugPanel( break; } case "toggleDataSwitch": { - // Set the setting in vscode + // Set the setting in vscode await vscode.workspace - .getConfiguration("continue") - .update("dataSwitch", data.on, vscode.ConfigurationTarget.Global); + .getConfiguration("continue") + .update("dataSwitch", data.on, vscode.ConfigurationTarget.Global); break; } case "websocketForwardingOpen": { diff --git a/extension/src/lang-server/codeLens.ts b/extension/src/lang-server/codeLens.ts index 5b55589c..03a9a0a7 100644 --- a/extension/src/lang-server/codeLens.ts +++ b/extension/src/lang-server/codeLens.ts @@ -1,5 +1,5 @@ import * as vscode from "vscode"; -import { editorToSuggestions } from "../suggestions"; +import { editorToSuggestions, editorSuggestionsLocked } from "../suggestions"; class SuggestionsCodeLensProvider implements vscode.CodeLensProvider { public provideCodeLenses( @@ -10,6 +10,7 @@ class SuggestionsCodeLensProvider implements vscode.CodeLensProvider { if (!suggestions) { return []; } + const locked = editorSuggestionsLocked.get(document.uri.fsPath.toString()); const codeLenses: vscode.CodeLens[] = []; for (const suggestion of suggestions) { @@ -20,12 +21,12 @@ class SuggestionsCodeLensProvider implements vscode.CodeLensProvider { codeLenses.push( new vscode.CodeLens(range, { title: "Accept ✅", - command: "continue.acceptSuggestion", + command: locked ? "" : "continue.acceptSuggestion", arguments: [suggestion], }), new vscode.CodeLens(range, { title: "Reject ❌", - command: "continue.rejectSuggestion", + command: locked ? "" : "continue.rejectSuggestion", arguments: [suggestion], }) ); diff --git a/extension/src/suggestions.ts b/extension/src/suggestions.ts index 8bed202c..e269f38a 100644 --- a/extension/src/suggestions.ts +++ b/extension/src/suggestions.ts @@ -17,6 +17,7 @@ export const editorToSuggestions: Map< string, // URI of file SuggestionRanges[] > = new Map(); +export const editorSuggestionsLocked: Map<string, boolean> = new Map(); // Map from editor URI to whether the suggestions are locked export const currentSuggestion: Map<string, number> = new Map(); // Map from editor URI to index of current SuggestionRanges in editorToSuggestions // When tab is reopened, rerender the decorations: |