From 542d9b72d5b413c33d5b670c5d605af71ad74695 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 16:44:12 -0700 Subject: try harder when checking for continuedev package --- extension/src/activation/environmentSetup.ts | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 168c79ad..6ea60195 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -101,9 +101,32 @@ function checkEnvExists() { } function checkRequirementsInstalled() { - return fs.existsSync( - path.join(getExtensionUri().fsPath, "scripts", ".continue_env_installed") + const envLibsPath = path.join( + getExtensionUri().fsPath, + "scripts", + "env", + process.platform == "win32" ? "Lib" : "lib" + ); + // Get the python version folder name + const pythonVersions = fs.readdirSync(envLibsPath).filter((f: string) => { + return f.startsWith("python"); + }); + if (pythonVersions.length == 0) { + return false; + } + + const continuePath = path.join( + envLibsPath, + pythonVersions[0], + "site-packages", + "continuedev" ); + + return fs.existsSync(continuePath); + + // return fs.existsSync( + // path.join(getExtensionUri().fsPath, "scripts", ".continue_env_installed") + // ); } async function setupPythonEnv() { -- cgit v1.2.3-70-g09d2 From b25b737c50fc819d422d776ad25e7221fa18b884 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 17:36:31 -0700 Subject: fixes --- continuedev/src/continuedev/server/ide.py | 12 +++++++---- continuedev/src/continuedev/steps/core/core.py | 2 +- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/src/activation/activate.ts | 3 ++- extension/src/activation/environmentSetup.ts | 28 ++++++++++++++------------ 6 files changed, 29 insertions(+), 22 deletions(-) diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py index 6a94326a..ff0b2a24 100644 --- a/continuedev/src/continuedev/server/ide.py +++ b/continuedev/src/continuedev/server/ide.py @@ -253,10 +253,14 @@ class IdeProtocolServer(AbstractIdeProtocolServer): async def getUserSecret(self, key: str) -> str: """Get a user secret""" - resp = await self._send_and_receive_json({ - "key": key - }, GetUserSecretResponse, "getUserSecret") - return resp.value + try: + resp = await self._send_and_receive_json({ + "key": key + }, GetUserSecretResponse, "getUserSecret") + return resp.value + except Exception as e: + print("Error getting user secret", e) + return "" async def saveFile(self, filepath: str): """Save a file""" diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index ad72212d..800f43b5 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -406,7 +406,7 @@ class DefaultModelEditCodeStep(Step): continue # Because really short lines might be expected to be repeated, this is only a !heuristic! # Stop when it starts copying the file_suffix - elif line.strip() == line_below_highlighted_range.strip() and len(line.strip()) > 4 and not line.strip() == original_lines_below_previous_blocks[0].strip(): + elif line.strip() == line_below_highlighted_range.strip() and len(line.strip()) > 4 and not (len(original_lines_below_previous_blocks) > 0 and line.strip() == original_lines_below_previous_blocks[0].strip()): repeating_file_suffix = True break diff --git a/extension/package-lock.json b/extension/package-lock.json index a4aff512..f8d85a19 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.79", + "version": "0.0.83", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.79", + "version": "0.0.83", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 44b55e89..4a623b74 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "Accelerating software development with language models", - "version": "0.0.79", + "version": "0.0.83", "publisher": "Continue", "engines": { "vscode": "^1.74.0" diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts index df8b6871..05589d92 100644 --- a/extension/src/activation/activate.ts +++ b/extension/src/activation/activate.ts @@ -28,7 +28,8 @@ export async function activateExtension( vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, - title: "Starting Continue Server...", + title: + "Starting Continue Server... (it may take a minute to download Python packages)", cancellable: false, }, async (progress, token) => { diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 6ea60195..4e6227c7 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -101,26 +101,28 @@ function checkEnvExists() { } function checkRequirementsInstalled() { - const envLibsPath = path.join( + let envLibsPath = path.join( getExtensionUri().fsPath, "scripts", "env", process.platform == "win32" ? "Lib" : "lib" ); - // Get the python version folder name - const pythonVersions = fs.readdirSync(envLibsPath).filter((f: string) => { - return f.startsWith("python"); - }); - if (pythonVersions.length == 0) { - return false; + // If site-packages is directly under env, use that + if (fs.existsSync(path.join(envLibsPath, "site-packages"))) { + envLibsPath = path.join(envLibsPath, "site-packages"); + } else { + // Get the python version folder name + const pythonVersions = fs.readdirSync(envLibsPath).filter((f: string) => { + return f.startsWith("python"); + }); + if (pythonVersions.length == 0) { + return false; + } + const pythonVersion = pythonVersions[0]; + envLibsPath = path.join(envLibsPath, pythonVersion, "site-packages"); } - const continuePath = path.join( - envLibsPath, - pythonVersions[0], - "site-packages", - "continuedev" - ); + const continuePath = path.join(envLibsPath, "continuedev"); return fs.existsSync(continuePath); -- cgit v1.2.3-70-g09d2 From f06c6500dc730add3082ab8101f1e21ae5f9ac95 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 17:56:42 -0700 Subject: fix steps not running after a prev cancelled step --- continuedev/src/continuedev/core/autopilot.py | 15 ++++++++------- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py index 3b2b65db..7d149e7e 100644 --- a/continuedev/src/continuedev/core/autopilot.py +++ b/continuedev/src/continuedev/core/autopilot.py @@ -139,13 +139,14 @@ class Autopilot(ContinueBaseModel): return None # If a parent step is deleted/cancelled, don't run this step - last_depth = self._step_depth - i = self.history.current_index - while i >= 0 and self.history.timeline[i].depth == last_depth - 1: - if self.history.timeline[i].deleted: - return None - last_depth = self.history.timeline[i].depth - i -= 1 + # TODO: This was problematic because when running a step after deleting one, it seemed to think that was the parent + # last_depth = self._step_depth + # i = self.history.current_index + # while i >= 0 and self.history.timeline[i].depth == last_depth - 1: + # if self.history.timeline[i].deleted: + # return None + # last_depth = self.history.timeline[i].depth + # i -= 1 capture_event(self.continue_sdk.ide.unique_id, 'step run', { 'step_name': step.name, 'params': step.dict()}) diff --git a/extension/package-lock.json b/extension/package-lock.json index f8d85a19..9557336f 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.83", + "version": "0.0.84", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.83", + "version": "0.0.84", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 4a623b74..fd18d494 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "Accelerating software development with language models", - "version": "0.0.83", + "version": "0.0.84", "publisher": "Continue", "engines": { "vscode": "^1.74.0" -- cgit v1.2.3-70-g09d2 From da62f4290d5ba661f478870a61ba5c84dd063111 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 18:28:18 -0700 Subject: remove codelens when clicked --- extension/src/suggestions.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extension/src/suggestions.ts b/extension/src/suggestions.ts index c9e29ed5..c36b9b34 100644 --- a/extension/src/suggestions.ts +++ b/extension/src/suggestions.ts @@ -231,6 +231,8 @@ function selectSuggestion( currentSuggestion.set(editorUri, Math.min(idx, suggestions.length - 1)); } rerenderDecorations(editorUri); + + editorToSuggestions.set(editorUri, suggestions); } export function acceptSuggestionCommand(key: SuggestionRanges | null = null) { -- cgit v1.2.3-70-g09d2 From dc565fd7439fa8218cc6af079619536615bdbdab Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 18:47:59 -0700 Subject: indentation fix --- continuedev/src/continuedev/libs/util/dedent.py | 16 ++++++++++++++++ continuedev/src/continuedev/steps/core/core.py | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 continuedev/src/continuedev/libs/util/dedent.py diff --git a/continuedev/src/continuedev/libs/util/dedent.py b/continuedev/src/continuedev/libs/util/dedent.py new file mode 100644 index 00000000..74edd173 --- /dev/null +++ b/continuedev/src/continuedev/libs/util/dedent.py @@ -0,0 +1,16 @@ +from typing import Tuple + + +def dedent_and_get_common_whitespace(s: str) -> Tuple[str, str]: + lines = s.splitlines() + + # Longest common whitespace prefix + lcp = lines[0].split(lines[0].strip())[0] + for i in range(1, len(lines)): + for j in range(0, len(lcp)): + if j >= len(lines[i]) or lcp[j] != lines[i][j]: + lcp = lcp[:j] + if lcp == "": + return s, "" + break + return "\n".join(map(lambda x: x.removeprefix(lcp), lines)), lcp diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index 800f43b5..1cbf3816 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -11,6 +11,7 @@ from ...models.filesystem import FileSystem, RangeInFile, RangeInFileWithContent from ...core.observation import Observation, TextObservation, TracebackObservation, UserInputObservation from ...core.main import ChatMessage, Step, SequentialStep from ...libs.util.count_tokens import MAX_TOKENS_FOR_MODEL, DEFAULT_MAX_TOKENS +from ...libs.util.dedent import dedent_and_get_common_whitespace import difflib @@ -266,6 +267,8 @@ class DefaultModelEditCodeStep(Step): file_prefix, contents, file_suffix, model_to_use = await self.get_prompt_parts( rif, sdk, full_file_contents) + contents, common_whitespace = dedent_and_get_common_whitespace( + contents) prompt = self.compile_prompt(file_prefix, contents, file_suffix, sdk) full_file_contents_lines = full_file_contents.split("\n") @@ -292,10 +295,11 @@ class DefaultModelEditCodeStep(Step): index_of_last_matched_line = -1 async def handle_generated_line(line: str): - nonlocal lines, current_block_start, current_line_in_file, original_lines, original_lines_below_previous_blocks, current_block_lines, offset_from_blocks, matched_lines_at_end_of_block, index_of_last_matched_line, LINES_TO_MATCH_BEFORE_ENDING_BLOCK + nonlocal lines, current_block_start, current_line_in_file, original_lines, original_lines_below_previous_blocks, current_block_lines, offset_from_blocks, matched_lines_at_end_of_block, index_of_last_matched_line, LINES_TO_MATCH_BEFORE_ENDING_BLOCK, common_whitespace # Highlight the line to show progress - line_to_highlight = current_line_in_file - len(current_block_lines) + # - len(current_block_lines) + line_to_highlight = current_line_in_file 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") @@ -393,6 +397,9 @@ class DefaultModelEditCodeStep(Step): # Trailing whitespace doesn't matter line = line.rstrip() + # Add the common whitespace that was removed before prompting + line = common_whitespace + line + # Lines that should signify the end of generation if self.is_end_line(line): break @@ -417,6 +424,7 @@ class DefaultModelEditCodeStep(Step): # Add the unfinished line if unfinished_line != "" and not self.line_to_be_ignored(unfinished_line, completion_lines_covered == 0) and not self.is_end_line(unfinished_line): + unfinished_line = common_whitespace + unfinished_line lines.append(unfinished_line) await handle_generated_line(unfinished_line) completion_lines_covered += 1 -- cgit v1.2.3-70-g09d2 From 784d649f1f20c13312daa35f111fe1e22569c6b2 Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 19:03:18 -0700 Subject: show UI before server loads with welcome msg --- extension/package-lock.json | 4 +- extension/package.json | 2 +- extension/react-app/src/tabs/gui.tsx | 97 +++++++++++++++++++++++++++++++++++- extension/src/activation/activate.ts | 32 ++++++------ extension/src/debugPanel.ts | 14 ++++-- 5 files changed, 123 insertions(+), 26 deletions(-) diff --git a/extension/package-lock.json b/extension/package-lock.json index 9557336f..8f35c720 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.84", + "version": "0.0.85", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.84", + "version": "0.0.85", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index fd18d494..3f030c3a 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "Accelerating software development with language models", - "version": "0.0.84", + "version": "0.0.85", "publisher": "Continue", "engines": { "vscode": "^1.74.0" diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index 13b74423..249d9785 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -64,7 +64,101 @@ function GUI(props: GUIProps) { const [dataSwitchChecked, setDataSwitchChecked] = useState(false); const [showDataSharingInfo, setShowDataSharingInfo] = useState(false); const [stepsOpen, setStepsOpen] = useState([]); - const [history, setHistory] = useState(); + const [history, setHistory] = useState({ + timeline: [ + { + step: { + name: "SequentialStep", + hide: true, + description: "Running step: SequentialStep", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + steps: [ + { + name: "Welcome to Continue", + hide: false, + description: + "Type '/' to see the list of available slash commands. If you highlight code, edits and explanations will be localized to the highlighted range. Otherwise, the currently open file is used. In both cases, the code is combined with the previous steps to construct the context.", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + message: + "Type '/' to see the list of available slash commands. If you highlight code, edits and explanations will be localized to the highlighted range. Otherwise, the currently open file is used. In both cases, the code is combined with the previous steps to construct the context.", + }, + { + name: "Welcome to Continue!", + hide: true, + description: "Welcome to Continue!", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + }, + { + name: "StepsOnStartupStep", + hide: true, + description: "Running steps on startup", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + }, + ], + }, + observation: null, + depth: 0, + deleted: false, + active: false, + }, + { + step: { + name: "Welcome to Continue", + hide: false, + description: + "Type '/' to see the list of available slash commands. If you highlight code, edits and explanations will be localized to the highlighted range. Otherwise, the currently open file is used. In both cases, the code is combined with the previous steps to construct the context.", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + message: + "Type '/' to see the list of available slash commands. If you highlight code, edits and explanations will be localized to the highlighted range. Otherwise, the currently open file is used. In both cases, the code is combined with the previous steps to construct the context.", + }, + observation: { + text: "Type '/' to see the list of available slash commands. If you highlight code, edits and explanations will be localized to the highlighted range. Otherwise, the currently open file is used. In both cases, the code is combined with the previous steps to construct the context.", + }, + depth: 1, + deleted: false, + active: false, + }, + { + step: { + name: "Welcome to Continue!", + hide: true, + description: "Welcome to Continue!", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + }, + observation: null, + depth: 1, + deleted: false, + active: false, + }, + { + step: { + name: "StepsOnStartupStep", + hide: true, + description: "Running steps on startup", + system_message: null, + chat_context: [], + manage_own_chat_context: false, + }, + observation: null, + depth: 1, + deleted: false, + active: false, + }, + ], + current_index: 3, + } as any); // { // timeline: [ // { @@ -228,7 +322,6 @@ function GUI(props: GUIProps) { }, []); useEffect(() => { - console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate); client?.onStateUpdate((state) => { // Scroll only if user is at very bottom of the window. setUsingFastModel(state.default_model === "gpt-3.5-turbo"); diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts index 05589d92..cd8f0cf3 100644 --- a/extension/src/activation/activate.ts +++ b/extension/src/activation/activate.ts @@ -24,20 +24,6 @@ export async function activateExtension( registerAllCodeLensProviders(context); registerAllCommands(context); - await new Promise((resolve, reject) => { - vscode.window.withProgress( - { - location: vscode.ProgressLocation.Notification, - title: - "Starting Continue Server... (it may take a minute to download Python packages)", - cancellable: false, - }, - async (progress, token) => { - await startContinuePythonServer(); - resolve(null); - } - ); - }); const serverUrl = getContinueServerUrl(); ideProtocolClient = new IdeProtocolClient( @@ -47,8 +33,8 @@ export async function activateExtension( // Setup the left panel (async () => { - const sessionId = await ideProtocolClient.getSessionId(); - const provider = new ContinueGUIWebviewViewProvider(sessionId); + const sessionIdPromise = ideProtocolClient.getSessionId(); + const provider = new ContinueGUIWebviewViewProvider(sessionIdPromise); context.subscriptions.push( vscode.window.registerWebviewViewProvider( @@ -61,6 +47,20 @@ export async function activateExtension( ); })(); + await new Promise((resolve, reject) => { + vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: + "Starting Continue Server... (it may take a minute to download Python packages)", + cancellable: false, + }, + async (progress, token) => { + await startContinuePythonServer(); + resolve(null); + } + ); + }); // All opened terminals should be replaced by our own terminal // vscode.window.onDidOpenTerminal((terminal) => {}); diff --git a/extension/src/debugPanel.ts b/extension/src/debugPanel.ts index b0db590a..79719a3b 100644 --- a/extension/src/debugPanel.ts +++ b/extension/src/debugPanel.ts @@ -126,7 +126,7 @@ let streamManager = new StreamManager(); export let debugPanelWebview: vscode.Webview | undefined; export function setupDebugPanel( panel: vscode.WebviewPanel | vscode.WebviewView, - sessionId: string + sessionIdPromise: Promise ): string { debugPanelWebview = panel.webview; panel.onDidDispose(() => { @@ -224,6 +224,7 @@ export function setupDebugPanel( panel.webview.onDidReceiveMessage(async (data) => { switch (data.type) { case "onLoad": { + const sessionId = await sessionIdPromise; panel.webview.postMessage({ type: "onLoad", vscMachineId: vscode.env.machineId, @@ -334,10 +335,10 @@ export class ContinueGUIWebviewViewProvider implements vscode.WebviewViewProvider { public static readonly viewType = "continue.continueGUIView"; - private readonly sessionId: string; + private readonly sessionIdPromise: Promise; - constructor(sessionId: string) { - this.sessionId = sessionId; + constructor(sessionIdPromise: Promise) { + this.sessionIdPromise = sessionIdPromise; } resolveWebviewView( @@ -345,6 +346,9 @@ export class ContinueGUIWebviewViewProvider _context: vscode.WebviewViewResolveContext, _token: vscode.CancellationToken ): void | Thenable { - webviewView.webview.html = setupDebugPanel(webviewView, this.sessionId); + webviewView.webview.html = setupDebugPanel( + webviewView, + this.sessionIdPromise + ); } } -- cgit v1.2.3-70-g09d2 From 9a1641c097b93d209d5347075a2f04f095d83bbd Mon Sep 17 00:00:00 2001 From: Nate Sesti Date: Wed, 28 Jun 2023 19:43:08 -0700 Subject: fixed error when two windows open simultaneously --- extension/package-lock.json | 4 ++-- extension/package.json | 2 +- extension/src/activation/environmentSetup.ts | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/extension/package-lock.json b/extension/package-lock.json index 8f35c720..241ea5ca 100644 --- a/extension/package-lock.json +++ b/extension/package-lock.json @@ -1,12 +1,12 @@ { "name": "continue", - "version": "0.0.85", + "version": "0.0.86", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "continue", - "version": "0.0.85", + "version": "0.0.86", "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", diff --git a/extension/package.json b/extension/package.json index 3f030c3a..7eca6042 100644 --- a/extension/package.json +++ b/extension/package.json @@ -14,7 +14,7 @@ "displayName": "Continue", "pricing": "Free", "description": "Accelerating software development with language models", - "version": "0.0.85", + "version": "0.0.86", "publisher": "Continue", "engines": { "vscode": "^1.74.0" diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts index 4e6227c7..823670fd 100644 --- a/extension/src/activation/environmentSetup.ts +++ b/extension/src/activation/environmentSetup.ts @@ -274,7 +274,10 @@ export async function startContinuePythonServer() { }); child.stderr.on("data", (data: any) => { console.log(`stderr: ${data}`); - if (data.includes("Uvicorn running on")) { + if ( + data.includes("Uvicorn running on") || // Successfully started the server + data.includes("address already in use") // The server is already running (probably a simultaneously opened VS Code window) + ) { console.log("Successfully started Continue python server"); resolve(null); } -- cgit v1.2.3-70-g09d2