From ae8ab99bf3e18683a1ab850bea9522339d9d9fd7 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Mon, 13 Jan 2025 16:40:25 +0100 Subject: [PATCH 01/36] Fix syntax highlighting for .class files Signed-off-by: Fred Bricon --- core/util/index.test.ts | 11 ++++++++--- core/util/index.ts | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/core/util/index.test.ts b/core/util/index.test.ts index 74ee3ccc86..fc48a49b27 100644 --- a/core/util/index.test.ts +++ b/core/util/index.test.ts @@ -207,7 +207,7 @@ World it("should handle strings with only whitespace", () => { const result = dedent` - + `; expect(result).toBe(""); }); @@ -249,9 +249,9 @@ World it("should handle a string with only one non-empty line", () => { const result = dedent` - + Hello World! - + `; expect(result).toBe("Hello World!"); }); @@ -373,11 +373,16 @@ describe("getMarkdownLanguageTagForFile", () => { expect(getMarkdownLanguageTagForFile("test.py")).toBe("python"); expect(getMarkdownLanguageTagForFile("test.tsx")).toBe("tsx"); expect(getMarkdownLanguageTagForFile("test.java")).toBe("java"); + expect(getMarkdownLanguageTagForFile("test.class")).toBe("java"); expect(getMarkdownLanguageTagForFile("test.md")).toBe("markdown"); expect(getMarkdownLanguageTagForFile("test.sh")).toBe("shell"); expect(getMarkdownLanguageTagForFile("test.sql")).toBe("sql"); }); + it("should sanitize ranges from the extension", () => { + expect(getMarkdownLanguageTagForFile("test.java (1-5)")).toBe("java"); + }); + it("should return the extension if not in the known list", () => { expect(getMarkdownLanguageTagForFile("file.unknownext")).toBe("unknownext"); }); diff --git a/core/util/index.ts b/core/util/index.ts index 04dc6d5675..4cb0f4920e 100644 --- a/core/util/index.ts +++ b/core/util/index.ts @@ -74,6 +74,7 @@ export function getMarkdownLanguageTagForFile(filepath: string): string { tsx: "tsx", ts: "typescript", java: "java", + class:"java", //.class files decompile to Java go: "go", rb: "ruby", rs: "rust", @@ -96,17 +97,28 @@ export function getMarkdownLanguageTagForFile(filepath: string): string { ps1: "powershell", }; - const ext = filepath.split(".").pop(); + const ext = sanitizeExtension(filepath.split(".").pop()); return ext ? (extToLangMap[ext] ?? ext) : ""; } + +function sanitizeExtension(ext?: string): string|undefined { + if (ext) { + //ignore ranges in extension eg. "java (11-23)" + const match = ext.match(/^(\S+)\s*(\(.*\))?$/); + if (match) { + ext = match[1]; + } + } + return ext; +} + export function copyOf(obj: any): any { if (obj === null || obj === undefined) { return obj; } return JSON.parse(JSON.stringify(obj)); } -``; export function deduplicateArray( array: T[], From 16b9a21a34f4f91b2758458e16d35252eafeb1f0 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Wed, 15 Jan 2025 19:07:24 +0100 Subject: [PATCH 02/36] Intercept Ollama errors before Webview, to display Download/Start options Signed-off-by: Fred Bricon --- core/util/ollamaHelper.ts | 8 +++--- .../src/autocomplete/completionProvider.ts | 6 ++--- extensions/vscode/src/commands.ts | 4 +++ extensions/vscode/src/webviewProtocol.ts | 25 ++++++++++++++++++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/core/util/ollamaHelper.ts b/core/util/ollamaHelper.ts index 1e9c524908..a00e869dd0 100644 --- a/core/util/ollamaHelper.ts +++ b/core/util/ollamaHelper.ts @@ -11,7 +11,7 @@ export async function isOllamaInstalled(): Promise { }); } -export async function startLocalOllama(ide: IDE): Promise { +export async function startLocalOllama(ide: IDE): Promise { let startCommand: string | undefined; switch (process.platform) { @@ -20,16 +20,16 @@ export async function startLocalOllama(ide: IDE): Promise { break; case "win32"://Windows - startCommand = `& "ollama app.exe"\n`; + startCommand = "& \"ollama app.exe\"\n"; break; default: //Linux... - const start_script_path = path.resolve(__dirname, './start_ollama.sh'); + const start_script_path = path.resolve(__dirname, "./start_ollama.sh"); if (await ide.fileExists(`file:/${start_script_path}`)) { startCommand = `set -e && chmod +x ${start_script_path} && ${start_script_path}\n`; console.log(`Ollama Linux startup script at : ${start_script_path}`); } else { - ide.showToast("error", `Cannot start Ollama: could not find ${start_script_path}!`) + return ide.showToast("error", `Cannot start Ollama: could not find ${start_script_path}!`) } } if (startCommand) { diff --git a/extensions/vscode/src/autocomplete/completionProvider.ts b/extensions/vscode/src/autocomplete/completionProvider.ts index c10d4d5f18..b7680b6868 100644 --- a/extensions/vscode/src/autocomplete/completionProvider.ts +++ b/extensions/vscode/src/autocomplete/completionProvider.ts @@ -44,11 +44,11 @@ export class ContinueCompletionProvider implements vscode.InlineCompletionItemProvider { private onError(e: any) { - const options = ["Documentation"]; + let options = ["Documentation"]; if (e.message.includes("Ollama may not be installed")) { options.push("Download Ollama"); } else if (e.message.includes("Ollama may not be running")) { - options.unshift("Start Ollama"); // We want "Start" to be the default choice + options = ["Start Ollama"]; // We want "Start" to be the only choice } if (e.message.includes("Please sign in with GitHub")) { @@ -70,7 +70,7 @@ export class ContinueCompletionProvider ); } else if (val === "Download Ollama") { vscode.env.openExternal(vscode.Uri.parse("https://ollama.ai/download")); - } else if (val == "Start Ollama") { + } else if (val === "Start Ollama") { startLocalOllama(this.ide); } }); diff --git a/extensions/vscode/src/commands.ts b/extensions/vscode/src/commands.ts index d8019cfe17..bbf1cfd749 100644 --- a/extensions/vscode/src/commands.ts +++ b/extensions/vscode/src/commands.ts @@ -33,6 +33,7 @@ import { Battery } from "./util/battery"; import { VsCodeIde } from "./VsCodeIde"; import type { VsCodeWebviewProtocol } from "./webviewProtocol"; +import { startLocalOllama } from "core/util/ollamaHelper"; let fullScreenPanel: vscode.WebviewPanel | undefined; @@ -1000,6 +1001,9 @@ const getCommandsMap: ( "continue.openAccountDialog": () => { sidebar.webviewProtocol?.request("openDialogMessage", "account"); }, + "continue.startLocalOllama": () => { + startLocalOllama(ide); + }, }; }; diff --git a/extensions/vscode/src/webviewProtocol.ts b/extensions/vscode/src/webviewProtocol.ts index bfbb37ce60..c5853d12ad 100644 --- a/extensions/vscode/src/webviewProtocol.ts +++ b/extensions/vscode/src/webviewProtocol.ts @@ -81,6 +81,30 @@ export class VsCodeWebviewProtocol respond({ done: true, content: response ?? {}, status: "success" }); } } catch (e: any) { + let message = e.message; + //Intercept Ollama errors for special handling + if (message.includes("Ollama may not")) { + const options = []; + if (message.includes("be installed")) { + options.push("Download Ollama"); + } else if (message.includes("be running")) { + options.push("Start Ollama"); + } + if (options.length > 0) { + // Respond without an error, so the UI doesn't show the error component + respond({ done: true, status: "error" }); + // Show native vscode error message instead, with options to download/start Ollama + vscode.window.showErrorMessage(e.message, ...options).then(async (val) => { + if (val === "Download Ollama") { + vscode.env.openExternal(vscode.Uri.parse("https://ollama.ai/download")); + } else if (val === "Start Ollama") { + vscode.commands.executeCommand("continue.startLocalOllama"); + } + }); + return; + } + } + respond({ done: true, error: e.message, status: "error" }); const stringified = JSON.stringify({ msg }, null, 2); @@ -96,7 +120,6 @@ export class VsCodeWebviewProtocol return; } - let message = e.message; if (e.cause) { if (e.cause.name === "ConnectTimeoutError") { message = `Connection timed out. If you expect it to take a long time to connect, you can increase the timeout in config.json by setting "requestOptions": { "timeout": 10000 }. You can find the full config reference here: https://docs.continue.dev/reference/config`; From 3b7029350ba265ea1dcd70b7cbbdcdadac3a160a Mon Sep 17 00:00:00 2001 From: henry Date: Wed, 15 Jan 2025 17:54:05 -0600 Subject: [PATCH 03/36] full screen opens in front of vscode --- extensions/vscode/src/commands.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/vscode/src/commands.ts b/extensions/vscode/src/commands.ts index d8019cfe17..b322d6afb4 100644 --- a/extensions/vscode/src/commands.ts +++ b/extensions/vscode/src/commands.ts @@ -776,6 +776,7 @@ const getCommandsMap: ( sessionId, ); } + panel.reveal(); sessionLoader.dispose(); }); From fb1c022caa4633e7dd5c2a24eb0ab45bfb10ff96 Mon Sep 17 00:00:00 2001 From: ferenci84 Date: Sat, 1 Feb 2025 23:43:46 +0100 Subject: [PATCH 04/36] add error handling in RecentlyEditedTracker --- .../vscode/src/autocomplete/recentlyEdited.ts | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/extensions/vscode/src/autocomplete/recentlyEdited.ts b/extensions/vscode/src/autocomplete/recentlyEdited.ts index 6ab614c90a..f06341e7d5 100644 --- a/extensions/vscode/src/autocomplete/recentlyEdited.ts +++ b/extensions/vscode/src/autocomplete/recentlyEdited.ts @@ -51,32 +51,42 @@ export class RecentlyEditedTracker { let range = this.recentlyEditedRanges[i]; if (range.range.intersection(editedRange.range)) { const union = range.range.union(editedRange.range); - const contents = await this._getContentsForRange({ - ...range, - range: union, - }); - range = { - ...range, - range: union, - lines: contents.split("\n"), - symbols: getSymbolsForSnippet(contents), - }; - return; + try { + const contents = await this._getContentsForRange({ + ...range, + range: union, + }); + range = { + ...range, + range: union, + lines: contents.split("\n"), + symbols: getSymbolsForSnippet(contents), + }; + return; + } catch (error) { + console.debug('insertRange: Failed to get contents for: ' + range.uri, error); + } } } // Otherwise, just add the new and maintain max size - const contents = await this._getContentsForRange(editedRange); - const newLength = this.recentlyEditedRanges.unshift({ - ...editedRange, - lines: contents.split("\n"), - symbols: getSymbolsForSnippet(contents), - }); - if (newLength >= RecentlyEditedTracker.maxRecentlyEditedRanges) { - this.recentlyEditedRanges = this.recentlyEditedRanges.slice( - 0, - RecentlyEditedTracker.maxRecentlyEditedRanges, - ); + try { + const contents = await this._getContentsForRange(editedRange); + const newLength = this.recentlyEditedRanges.unshift({ + ...editedRange, + lines: contents.split("\n"), + symbols: getSymbolsForSnippet(contents), + }); + if (newLength >= RecentlyEditedTracker.maxRecentlyEditedRanges) { + this.recentlyEditedRanges = this.recentlyEditedRanges.slice( + 0, + RecentlyEditedTracker.maxRecentlyEditedRanges, + ); + } + } catch (error) { + console.error('Failed to get contents for new range: ' + editedRange.uri, error); + // Skip adding the new range if we can't get its contents + return; } } From 5b01b45a73c2e619e858c8750b20501e1eb26df4 Mon Sep 17 00:00:00 2001 From: ferenci84 Date: Sat, 1 Feb 2025 23:52:26 +0100 Subject: [PATCH 05/36] ignore output scheme ranges in RecentlyEditedTracker --- .../vscode/src/autocomplete/recentlyEdited.ts | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/extensions/vscode/src/autocomplete/recentlyEdited.ts b/extensions/vscode/src/autocomplete/recentlyEdited.ts index f06341e7d5..69b9b4d0f5 100644 --- a/extensions/vscode/src/autocomplete/recentlyEdited.ts +++ b/extensions/vscode/src/autocomplete/recentlyEdited.ts @@ -46,48 +46,44 @@ export class RecentlyEditedTracker { private async insertRange( editedRange: Omit, ): Promise { + + if (editedRange.uri.scheme === "output") { + return; + } + // Check for overlap with any existing ranges for (let i = 0; i < this.recentlyEditedRanges.length; i++) { let range = this.recentlyEditedRanges[i]; if (range.range.intersection(editedRange.range)) { const union = range.range.union(editedRange.range); - try { - const contents = await this._getContentsForRange({ - ...range, - range: union, - }); - range = { - ...range, - range: union, - lines: contents.split("\n"), - symbols: getSymbolsForSnippet(contents), - }; - return; - } catch (error) { - console.debug('insertRange: Failed to get contents for: ' + range.uri, error); - } + const contents = await this._getContentsForRange({ + ...range, + range: union, + }); + range = { + ...range, + range: union, + lines: contents.split("\n"), + symbols: getSymbolsForSnippet(contents), + }; + return; } } // Otherwise, just add the new and maintain max size - try { - const contents = await this._getContentsForRange(editedRange); - const newLength = this.recentlyEditedRanges.unshift({ - ...editedRange, - lines: contents.split("\n"), - symbols: getSymbolsForSnippet(contents), - }); - if (newLength >= RecentlyEditedTracker.maxRecentlyEditedRanges) { - this.recentlyEditedRanges = this.recentlyEditedRanges.slice( - 0, - RecentlyEditedTracker.maxRecentlyEditedRanges, - ); - } - } catch (error) { - console.error('Failed to get contents for new range: ' + editedRange.uri, error); - // Skip adding the new range if we can't get its contents - return; + const contents = await this._getContentsForRange(editedRange); + const newLength = this.recentlyEditedRanges.unshift({ + ...editedRange, + lines: contents.split("\n"), + symbols: getSymbolsForSnippet(contents), + }); + if (newLength >= RecentlyEditedTracker.maxRecentlyEditedRanges) { + this.recentlyEditedRanges = this.recentlyEditedRanges.slice( + 0, + RecentlyEditedTracker.maxRecentlyEditedRanges, + ); } + } private insertDocument(uri: vscode.Uri): void { From 787c4632c58faa195ef8acc032546076459e4b80 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Sun, 2 Feb 2025 17:05:19 -0800 Subject: [PATCH 06/36] include message in messenger error handling --- binary/src/IpcMessenger.ts | 8 ++++---- binary/src/TcpMessenger.ts | 6 +++--- core/core.ts | 1 - core/protocol/messenger/index.ts | 6 +++--- extensions/vscode/src/webviewProtocol.ts | 11 +++++------ 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/binary/src/IpcMessenger.ts b/binary/src/IpcMessenger.ts index e90fbeb849..b92a8e6a23 100644 --- a/binary/src/IpcMessenger.ts +++ b/binary/src/IpcMessenger.ts @@ -75,7 +75,7 @@ class IPCMessengerBase< console.warn(`Error running handler for "${msg.messageType}": `, e); this._onErrorHandlers.forEach((handler) => { - handler(e); + handler(msg, e); }); } }); @@ -112,9 +112,9 @@ class IPCMessengerBase< lines.forEach((line) => this._handleLine(line)); } - private _onErrorHandlers: ((error: Error) => void)[] = []; + private _onErrorHandlers: ((message: Message, error: Error) => void)[] = []; - onError(handler: (error: Error) => void) { + onError(handler: (message: Message, error: Error) => void) { this._onErrorHandlers.push(handler); } @@ -217,7 +217,7 @@ export class CoreBinaryMessenger< extends IPCMessengerBase implements IMessenger { - private errorHandler: (error: Error) => void = () => {}; + private errorHandler: (message: Message, error: Error) => void = () => {}; private messageHandlers: Map< keyof ToProtocol, (message: Message) => Promise | any diff --git a/binary/src/TcpMessenger.ts b/binary/src/TcpMessenger.ts index ad47134737..907e32ed75 100644 --- a/binary/src/TcpMessenger.ts +++ b/binary/src/TcpMessenger.ts @@ -41,9 +41,9 @@ export class TcpMessenger< }); } - private _onErrorHandlers: ((error: Error) => void)[] = []; + private _onErrorHandlers: ((message: Message, error: Error) => void)[] = []; - onError(handler: (error: Error) => void) { + onError(handler: (message: Message, error: Error) => void) { this._onErrorHandlers.push(handler); } @@ -111,7 +111,7 @@ export class TcpMessenger< console.warn(`Error running handler for "${msg.messageType}": `, e); this._onErrorHandlers.forEach((handler) => { - handler(e); + handler(msg, e); }); } }); diff --git a/core/core.ts b/core/core.ts index 52e5a58cd3..4bc7e88939 100644 --- a/core/core.ts +++ b/core/core.ts @@ -57,7 +57,6 @@ import type { FromCoreProtocol, ToCoreProtocol } from "./protocol"; import type { IMessenger, Message } from "./protocol/messenger"; export class Core { - // implements IMessenger configHandler: ConfigHandler; codebaseIndexerPromise: Promise; completionProvider: CompletionProvider; diff --git a/core/protocol/messenger/index.ts b/core/protocol/messenger/index.ts index 8b7245224d..fb2528ae27 100644 --- a/core/protocol/messenger/index.ts +++ b/core/protocol/messenger/index.ts @@ -21,7 +21,7 @@ export interface IMessenger< ToProtocol extends IProtocol, FromProtocol extends IProtocol, > { - onError(handler: (error: Error) => void): void; + onError(handler: (message: Message, error: Error) => void): void; send( messageType: T, data: FromProtocol[T][0], @@ -64,9 +64,9 @@ export class InProcessMessenger< (message: Message) => any >(); - protected _onErrorHandlers: ((error: Error) => void)[] = []; + protected _onErrorHandlers: ((message: Message, error: Error) => void)[] = []; - onError(handler: (error: Error) => void) { + onError(handler: (message: Message, error: Error) => void) { this._onErrorHandlers.push(handler); } diff --git a/extensions/vscode/src/webviewProtocol.ts b/extensions/vscode/src/webviewProtocol.ts index 2129c0ce37..5c78da15fb 100644 --- a/extensions/vscode/src/webviewProtocol.ts +++ b/extensions/vscode/src/webviewProtocol.ts @@ -10,7 +10,8 @@ import { IMessenger } from "../../../core/protocol/messenger"; import { showFreeTrialLoginMessage } from "./util/messages"; export class VsCodeWebviewProtocol - implements IMessenger { + implements IMessenger +{ listeners = new Map< keyof FromWebviewProtocol, ((message: Message) => any)[] @@ -114,8 +115,7 @@ export class VsCodeWebviewProtocol message = message.split("\n").filter((l: string) => l !== "")[1]; try { message = JSON.parse(message).message; - } catch { - } + } catch {} if (message.includes("exceeded")) { message += " To keep using Continue, you can set up a local model or use your own API key."; @@ -152,8 +152,7 @@ export class VsCodeWebviewProtocol this._webviewListener = this._webview.onDidReceiveMessage(handleMessage); } - constructor(private readonly reloadConfig: () => void) { - } + constructor(private readonly reloadConfig: () => void) {} invoke( messageType: T, @@ -163,7 +162,7 @@ export class VsCodeWebviewProtocol throw new Error("Method not implemented."); } - onError(handler: (error: Error) => void): void { + onError(handler: (message: Message, error: Error) => void): void { throw new Error("Method not implemented."); } From ffb180b99e1413068b671e10778bbc0188a7a0d9 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Sun, 2 Feb 2025 17:11:18 -0800 Subject: [PATCH 07/36] implement fix --- core/core.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/core/core.ts b/core/core.ts index 4bc7e88939..5eefc706ef 100644 --- a/core/core.ts +++ b/core/core.ts @@ -208,13 +208,23 @@ export class Core { // Note, VsCode's in-process messenger doesn't do anything with this // It will only show for jetbrains - this.messenger.onError((err) => { - console.error(err); + this.messenger.onError((message, err) => { void Telemetry.capture("core_messenger_error", { message: err.message, stack: err.stack, }); - void this.ide.showToast("error", err.message); + + // Again, specifically for jetbrains to prevent duplicate error messages + // The same logic can currently be found in the webview protocol + // bc streaming errors are handled in the GUI + if ( + ["llm/streamChat", "chatDescriber/describe"].includes( + message.messageType, + ) + ) { + } else { + void this.ide.showToast("error", err.message); + } }); on("update/selectTabAutocompleteModel", async (msg) => { From 631dc07a01458d6552738d9cc86a96a9dba5aec4 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Sun, 2 Feb 2025 17:34:02 -0800 Subject: [PATCH 08/36] cleanup --- core/core.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/core/core.ts b/core/core.ts index 5eefc706ef..403b45c5bd 100644 --- a/core/core.ts +++ b/core/core.ts @@ -222,6 +222,7 @@ export class Core { message.messageType, ) ) { + return; } else { void this.ide.showToast("error", err.message); } From d072af95b440ffa3f76e0a24ac7c71211d7286dd Mon Sep 17 00:00:00 2001 From: Samuel Huang Date: Tue, 4 Feb 2025 19:07:39 -0500 Subject: [PATCH 09/36] Specify name and icon for GUI view --- extensions/vscode/package.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index c688eda3ff..a2dafa82dc 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -580,7 +580,8 @@ { "type": "webview", "id": "continue.continueGUIView", - "name": "", + "name": "Continue", + "icon": "media/sidebar-icon.png", "visibility": "visible" } ] @@ -702,6 +703,7 @@ "ncp": "^2.0.0", "node-fetch": "^3.3.2", "node-machine-id": "^1.1.12", + "partial-json": "^0.1.7", "posthog-node": "^3.6.3", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", @@ -718,6 +720,7 @@ "vectordb": "^0.4.20", "vscode-languageclient": "^8.0.2", "ws": "^8.13.0", - "yarn": "^1.22.21" + "yarn": "^1.22.21", + "zod": "^3.24.1" } } From 74f9a23d58e6130a5adf739423fdae7e8caf90aa Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Tue, 4 Feb 2025 17:50:51 -0800 Subject: [PATCH 10/36] comment adjustments --- .../src/main/resources/continue_tutorial.java | 24 ++++++++--------- .../src/main/resources/continue_tutorial.ts | 26 +++++++++---------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/extensions/intellij/src/main/resources/continue_tutorial.java b/extensions/intellij/src/main/resources/continue_tutorial.java index 41ac854c0e..808f51021f 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.java +++ b/extensions/intellij/src/main/resources/continue_tutorial.java @@ -1,14 +1,14 @@ -/* _________ _____ _____ - __ ____/______ _______ __ /____(_)_______ ____ _______ - _ / _ __ \__ __ \_ __/__ / __ __ \_ / / /_ _ \ - / /___ / /_/ /_ / / // /_ _ / _ / / // /_/ / / __/ - \____/ \____/ /_/ /_/ \__/ /_/ /_/ /_/ \__,_/ \___/ +// _________ _____ _____ +// __ ____/______ _______ __ /____(_)_______ ____ _______ +// _ / _ __ \__ __ \_ __/__ / __ __ \_ / / /_ _ \ +// / /___ / /_/ /_ / / // /_ _ / _ / / // /_/ / / __/ +// \____/ \____/ /_/ /_/ \__/ /_/ /_/ /_/ \__,_/ \___/ +// +// Chat, Edit, and Autocomplete tutorial +// - Chat, Edit, and Autocomplete tutorial -*/ - -/* ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— */ +// ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— // Highlight the code below // Press [Cmd/Ctrl + J] to add to Chat @@ -26,7 +26,7 @@ public static int[] sortingAlgorithm(int[] x) { return x; } -/* ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— */ +// ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— // Highlight the code below // Press [Cmd/Ctrl + I] to Edit @@ -44,7 +44,7 @@ public static int[] sortingAlgorithm2(int[] x) { return x; } -/* ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— */ +// ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— // Place cursor after `sortingAlgorithm...` below and press [Enter] // Press [Tab] to accept the Autocomplete suggestion @@ -52,4 +52,4 @@ public static int[] sortingAlgorithm2(int[] x) { // Basic assertion for sortingAlgorithm... -/* —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— */ +// —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— diff --git a/extensions/intellij/src/main/resources/continue_tutorial.ts b/extensions/intellij/src/main/resources/continue_tutorial.ts index 301fc248c5..1f47142496 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.ts +++ b/extensions/intellij/src/main/resources/continue_tutorial.ts @@ -1,14 +1,13 @@ -/* _________ _____ _____ - __ ____/______ _______ __ /____(_)_______ ____ _______ - _ / _ __ \__ __ \_ __/__ / __ __ \_ / / /_ _ \ - / /___ / /_/ /_ / / // /_ _ / _ / / // /_/ / / __/ - \____/ \____/ /_/ /_/ \__/ /_/ /_/ /_/ \__,_/ \___/ +// _________ _____ _____ +// __ ____/______ _______ __ /____(_)_______ ____ _______ +// _ / _ __ \__ __ \_ __/__ / __ __ \_ / / /_ _ \ +// / /___ / /_/ /_ / / // /_ _ / _ / / // /_/ / / __/ +// \____/ \____/ /_/ /_/ \__/ /_/ /_/ /_/ \__,_/ \___/ +// +// Chat, Edit, and Autocomplete tutorial +// - Chat, Edit, and Autocomplete tutorial -*/ - - -/* ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— */ +// ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— // Highlight the code below // Press [Cmd/Ctrl + J] to add to Chat @@ -26,7 +25,7 @@ function sortingAlgorithm(x: number[]): number[] { return x; } -/* ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— */ +// ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— // Highlight the code below // Press [Cmd/Ctrl + I] to Edit @@ -44,12 +43,11 @@ function sortingAlgorithm2(x: number[]): number[] { return x; } -/* ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— */ +// ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— // Place cursor after `sortingAlgorithm...` below and press [Enter] // Press [Tab] to accept the Autocomplete suggestion // Basic assertion for sortingAlgorithm... - -/* —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— */ +// —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— From accd5d4b50d459bbe49d58fd052ffd269f932e71 Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 4 Feb 2025 19:17:42 -0800 Subject: [PATCH 11/36] catch all config loading errors --- binary/package-lock.json | 2 +- core/config/ProfileLifecycleManager.ts | 20 ++++++++++++++++++-- core/config/profile/doLoadConfig.ts | 2 +- core/package-lock.json | 8 ++++---- core/package.json | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/binary/package-lock.json b/binary/package-lock.json index 84b831ecf9..72c044f142 100644 --- a/binary/package-lock.json +++ b/binary/package-lock.json @@ -48,7 +48,7 @@ "@aws-sdk/client-sagemaker-runtime": "^3.621.0", "@aws-sdk/credential-providers": "^3.620.1", "@continuedev/config-types": "^1.0.13", - "@continuedev/config-yaml": "^1.0.23", + "@continuedev/config-yaml": "^1.0.24", "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", diff --git a/core/config/ProfileLifecycleManager.ts b/core/config/ProfileLifecycleManager.ts index fc18f34b04..9fc3dc9607 100644 --- a/core/config/ProfileLifecycleManager.ts +++ b/core/config/ProfileLifecycleManager.ts @@ -50,7 +50,9 @@ export class ProfileLifecycleManager { } // Clear saved config and reload - async reloadConfig(additionalContextProviders: IContextProvider[] = []): Promise> { + async reloadConfig( + additionalContextProviders: IContextProvider[] = [], + ): Promise> { this.savedConfigResult = undefined; this.savedBrowserConfigResult = undefined; this.pendingConfigPromise = undefined; @@ -73,7 +75,21 @@ export class ProfileLifecycleManager { // Set pending config promise this.pendingConfigPromise = new Promise(async (resolve, reject) => { - const result = await this.profileLoader.doLoadConfig(); + let result: ConfigResult; + try { + result = await this.profileLoader.doLoadConfig(); + } catch (e: any) { + result = { + errors: [ + { + fatal: true, + message: e.message, + }, + ], + config: undefined, + configLoadInterrupted: true, + }; + } if (result.config) { // Add registered context providers diff --git a/core/config/profile/doLoadConfig.ts b/core/config/profile/doLoadConfig.ts index 86f9759656..af8c59c970 100644 --- a/core/config/profile/doLoadConfig.ts +++ b/core/config/profile/doLoadConfig.ts @@ -21,9 +21,9 @@ import { getConfigJsonPath, getConfigYamlPath } from "../../util/paths"; import { Telemetry } from "../../util/posthog"; import { TTS } from "../../util/tts"; import { loadContinueConfigFromJson } from "../load"; +import { migrateJsonSharedConfig } from "../migrateSharedConfig"; import { loadContinueConfigFromYaml } from "../yaml/loadYaml"; import { PlatformConfigMetadata } from "./PlatformProfileLoader"; -import { migrateJsonSharedConfig } from "../migrateSharedConfig"; export default async function doLoadConfig( ide: IDE, diff --git a/core/package-lock.json b/core/package-lock.json index 7edab380e6..b0e6047491 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -13,7 +13,7 @@ "@aws-sdk/client-sagemaker-runtime": "^3.621.0", "@aws-sdk/credential-providers": "^3.620.1", "@continuedev/config-types": "^1.0.13", - "@continuedev/config-yaml": "^1.0.23", + "@continuedev/config-yaml": "^1.0.24", "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", @@ -3038,9 +3038,9 @@ } }, "node_modules/@continuedev/config-yaml": { - "version": "1.0.23", - "resolved": "https://registry.npmjs.org/@continuedev/config-yaml/-/config-yaml-1.0.23.tgz", - "integrity": "sha512-F2Hwc85iCwAHJuwJALOsmZIBeHdF+87mS0YT7dlC6QiE+zAhZKUHcLQ/nTt9bJuhyVyufpb9LApkp40UdGsaWw==", + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/@continuedev/config-yaml/-/config-yaml-1.0.24.tgz", + "integrity": "sha512-xA4tRUh9r9p3aHIXr9zl5GQd5VygEusIc7Zw7AAFCbbl6ahMB4CDcweT8+iz0UvxJ11PLYizFSygpvxu/Yl19Q==", "dependencies": { "@continuedev/config-types": "^1.0.14", "yaml": "^2.6.1", diff --git a/core/package.json b/core/package.json index 111fbe9024..cfb17e1c46 100644 --- a/core/package.json +++ b/core/package.json @@ -46,7 +46,7 @@ "@aws-sdk/client-sagemaker-runtime": "^3.621.0", "@aws-sdk/credential-providers": "^3.620.1", "@continuedev/config-types": "^1.0.13", - "@continuedev/config-yaml": "^1.0.23", + "@continuedev/config-yaml": "^1.0.24", "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", From b0ae81fa740a83d9e4dca336ee9a2aac9c0426a0 Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 4 Feb 2025 19:24:44 -0800 Subject: [PATCH 12/36] fix onboarding --- .../continueintellijextension/continue/IntelliJIde.kt | 1 + .../services/ContinueExtensionSettingsService.kt | 1 + .../com/github/continuedev/continueintellijextension/types.kt | 1 + 3 files changed, 3 insertions(+) diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/continue/IntelliJIde.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/continue/IntelliJIde.kt index f871fc69e0..4482aa5fec 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/continue/IntelliJIde.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/continue/IntelliJIde.kt @@ -94,6 +94,7 @@ class IntelliJIDE( userToken = settings.continueState.userToken ?: "", enableControlServerBeta = settings.continueState.enableContinueTeamsBeta, pauseCodebaseIndexOnStart = false, // TODO: Needs to be implemented + continueTestEnvironment = "none" ) } diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/services/ContinueExtensionSettingsService.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/services/ContinueExtensionSettingsService.kt index ce548e5f5f..7430f2bcb4 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/services/ContinueExtensionSettingsService.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/services/ContinueExtensionSettingsService.kt @@ -98,6 +98,7 @@ open class ContinueExtensionSettings : PersistentStateComponent Date: Tue, 4 Feb 2025 22:27:20 -0800 Subject: [PATCH 13/36] fix PATH bug in MCP startup --- core/context/mcp/index.ts | 6 +++- core/package-lock.json | 50 ++++++++++++++++++++++++++--- core/package.json | 2 +- extensions/vscode/package-lock.json | 2 +- gui/package-lock.json | 2 +- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/core/context/mcp/index.ts b/core/context/mcp/index.ts index 304c2a8c4b..b1a9609103 100644 --- a/core/context/mcp/index.ts +++ b/core/context/mcp/index.ts @@ -69,10 +69,14 @@ class MCPConnection { private constructTransport(options: MCPOptions): Transport { switch (options.transport.type) { case "stdio": + const env: Record = options.transport.env || {}; + if (process.env.PATH !== undefined) { + env.PATH = process.env.PATH; + } return new StdioClientTransport({ command: options.transport.command, args: options.transport.args, - env: options.transport.env, + env, }); case "websocket": return new WebSocketClientTransport(new URL(options.transport.url)); diff --git a/core/package-lock.json b/core/package-lock.json index 7edab380e6..8f8f6d40bc 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -17,7 +17,7 @@ "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", - "@modelcontextprotocol/sdk": "^1.0.0", + "@modelcontextprotocol/sdk": "^1.4.1", "@mozilla/readability": "^0.5.0", "@octokit/rest": "^20.0.2", "@typescript-eslint/eslint-plugin": "^7.8.0", @@ -4218,13 +4218,34 @@ ] }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.3.tgz", - "integrity": "sha512-2as3cX/VJ0YBHGmdv3GFyTpoM8q2gqE98zh3Vf1NwnsSY0h3mvoO07MUzfygCKkWsFjcZm4otIiqD6Xh7kiSBQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.4.1.tgz", + "integrity": "sha512-wS6YC4lkUZ9QpP+/7NBTlVNiEvsnyl0xF7rRusLF+RsG0xDPc/zWR7fEEyhKnnNutGsDAZh59l/AeoWGwIb1+g==", "dependencies": { "content-type": "^1.0.5", + "eventsource": "^3.0.2", "raw-body": "^3.0.0", - "zod": "^3.23.8" + "zod": "^3.23.8", + "zod-to-json-schema": "^3.24.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/zod": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/zod-to-json-schema": { + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz", + "integrity": "sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==", + "peerDependencies": { + "zod": "^3.24.1" } }, "node_modules/@mozilla/readability": { @@ -8313,6 +8334,25 @@ "node": ">=0.8.x" } }, + "node_modules/eventsource": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz", + "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==", + "dependencies": { + "eventsource-parser": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz", + "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", diff --git a/core/package.json b/core/package.json index 111fbe9024..10efa03f96 100644 --- a/core/package.json +++ b/core/package.json @@ -50,7 +50,7 @@ "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", - "@modelcontextprotocol/sdk": "^1.0.0", + "@modelcontextprotocol/sdk": "^1.4.1", "@mozilla/readability": "^0.5.0", "@octokit/rest": "^20.0.2", "@typescript-eslint/eslint-plugin": "^7.8.0", diff --git a/extensions/vscode/package-lock.json b/extensions/vscode/package-lock.json index 9c55ed3d78..78a61be2b0 100644 --- a/extensions/vscode/package-lock.json +++ b/extensions/vscode/package-lock.json @@ -110,7 +110,7 @@ "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", - "@modelcontextprotocol/sdk": "^1.0.0", + "@modelcontextprotocol/sdk": "^1.4.1", "@mozilla/readability": "^0.5.0", "@octokit/rest": "^20.0.2", "@typescript-eslint/eslint-plugin": "^7.8.0", diff --git a/gui/package-lock.json b/gui/package-lock.json index cca9792501..0984ae74d9 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -112,7 +112,7 @@ "@continuedev/fetch": "^1.0.4", "@continuedev/llm-info": "^1.0.2", "@continuedev/openai-adapters": "^1.0.10", - "@modelcontextprotocol/sdk": "^1.0.0", + "@modelcontextprotocol/sdk": "^1.4.1", "@mozilla/readability": "^0.5.0", "@octokit/rest": "^20.0.2", "@typescript-eslint/eslint-plugin": "^7.8.0", From 7749349f8996f5da186ba1a8b2910443121ea2fc Mon Sep 17 00:00:00 2001 From: vercelInfrAI Date: Wed, 5 Feb 2025 15:01:35 +0800 Subject: [PATCH 14/36] feat: replace logo and deepseek model base info --- core/llm/llms/Novita.ts | 2 ++ extensions/vscode/config_schema.json | 2 ++ gui/public/logos/novita.png | Bin 6726 -> 2713 bytes 3 files changed, 4 insertions(+) diff --git a/core/llm/llms/Novita.ts b/core/llm/llms/Novita.ts index 2f5c61b551..55b9448295 100644 --- a/core/llm/llms/Novita.ts +++ b/core/llm/llms/Novita.ts @@ -9,6 +9,8 @@ class Novita extends OpenAI { }; private static MODEL_IDS: { [name: string]: string } = { + "deepseek-r1": "deepseek/deepseek-r1", + "deepseek_v3": "deepseek/deepseek_v3", "llama3-8b": "meta-llama/llama-3-8b-instruct", "llama3-70b": "meta-llama/llama-3-70b-instruct", "llama3.1-8b": "meta-llama/llama-3.1-8b-instruct", diff --git a/extensions/vscode/config_schema.json b/extensions/vscode/config_schema.json index 2b12cf21e2..827662dd24 100644 --- a/extensions/vscode/config_schema.json +++ b/extensions/vscode/config_schema.json @@ -998,6 +998,8 @@ "anyOf": [ { "enum": [ + "deepseek-r1", + "deepseek_v3", "llama3-8b", "llama3-70b", "llama3.1-8b", diff --git a/gui/public/logos/novita.png b/gui/public/logos/novita.png index b744cd35cc7825bba5c201be63d76e3993a75ec9..30ccb507e23b1c0491e35514c3b9858c515529be 100644 GIT binary patch literal 2713 zcmbW2i91yLAIE1f#w?f_vtx|0WX-NDlV;2?Wy!uTk!7+ZOLn@U8zwO-en@3aH%pdK zqD5uMlH?i`H*&*`ex%ascjkBRUvSU!I?r?7pYQu~-k)=xbDnRWlcTLPoD2tnK+*>| zEEf<6TqHWB#DPjz(377akXWCSy&D^lATS`nAaO8QTnsEB28M`(CB?x|39u9ZL<|NI zgG-7bB*lGAj)!*G_0fwR#FuwsfLqO$4l-aKs5+ZO(Il_2-PM*b;wX% zvea&QDLr{9eFZ54MJYo?DI*HZm;y6Vf|*ibd#JFz$}lr!m^lp&V4(uHRDsh~;QLhJ zRsd><{b~q?I)bT=u-=7WX&~4dNE=P0ttOJAg*>2zJgAMd(?QznNIU3CJL*aw+AZy* zC+(~!?V>N^sxRYiDC1!$<7Fi4Z7l0!BI|1+>t`bCZ;A@ogF3ty6|@%>Y=$}lV2%ng zM~7OV!z|F@mS`>j9etFJj@XBZ+=q#>!bAh?#~j;_iD6)lGvs2Ka&Z9Ga`D!32`sr2 zEV)FsToN0bWP?q%!KT<^Q*E(nw%BwIF5>_$^8oJTLEJ9~ai{EXS@!sBdwh-q{P7mG7pcsfRPIfx@F4?S@+DXLk}vy_ulSL#`je{y29=A?=hu5fEcBFG1U9VsSl1*AI4Jq0ph5S;;4_~m7l~b4f2o>_YZO>%Q5o_=kV2UF#Oz-(s;M%3Yf08rZd;0JSvd?B0V z?0nty{v7I^F=7(q47TuS= z({@UGN_YLCRC87?Z8U4S-*Na4tz5j*BTtmB@RG70WE_g!z_AJ{3{KymVmI)t0!324 zJ1RdJQT=7D?4PTYHR2<8)JR=!3$?t*;Cwf{+Dz2cuDPI{8`c$y^JHwL_xh$@+$lidgxeaHcV;IK8Km>QMs8;#zPwoH5=$CxJvAT>ZTd3rrL|_2Z zCxEv08uLU+hwTHV%KZVjO_0mlxy@k=Ko`L>Ami>)A|1jCWF$bezrw4ZmW_KB)gy%C z?kJPWv7+Xzh84?_1RTrZtzq5YZ`R?hei+tpy>sLz!J(dZC87=!8vW$ z!YKZEudd?*B~4Ive(dnUJlfF}4*E162<$g zBeQP_W#0;DBQqAi0_oq{zu#HI*#YT4gqfA}Ob`3aI)V8+lCNxj@?U)2Ha*Dis~hKo zKf1<{zt1*XX@ps=Gftm;he-oEUakDMtMXo{2D9*%?yCa)$(a=kv(^O9h@59n9c1&r zPcHhJZCbDLwh|_-zt)G}NsIb+k%dle>=K+?S!?Z|`l7Qn{0lgHiir1a^N%=b)i)e@ z)oQHOvUl*NV9KJl-L_EgLQ>K3zNMPqi`Q28+8iQ_zd55mPdTa7n|5Q{!o}v5mFFpj zp^6SK{dc-Qz0;?bnVmDtouIv1=BscTE+6)OGl9je+;w^^0W%q^z)zP`%(8OsOzHB{ zpPQ)B_j$B3m^W6ic{3%DPuuScH z!#(u#varD=J7@HY7vB5X_2RUsuYCt)F{wHRx@{?t&l;;6J3CXHkH#7E&!9Npkn;;a zDJ_cuEpt|`s#%oxTE9_WgC@pSO^2uBr4Cee2R@323aGG&E?zO=UdtO3gH{}B^ zx=3(n%fXZ1sb;x2{xY=kZF!#sH}hNms)5}&6h2bSZ@F5jnpY#Gw$EFVq#e!t@p?s^)#p7C(h z&Vgqieeotm@9AESaN?6-zI3(tMGgDH6?uUXXSw|nZG>LAaVb~|bIvrQ%wMn5KD_XI zc8;qlBE)Urr5KFYTgM%@R7x~vQTW%ztJJDL%@%20-k-Z2 z^Wd0>YeWJmc(#92v4SrF`#5oy=NCD>XsEWE!=*p%7EpUArRtmVkvo@T`H_vOe#OtO zbT}%>6K>Dc4?NEMG5P+kaNACai>YmDm9naL3;%Ho`mgspQ6v5*h@ZIZ=D~{}6UhT? LM^-cQaMu3-W*{(N literal 6726 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 From a31c3ebc8334f931281cdb0a348150347c99d0e6 Mon Sep 17 00:00:00 2001 From: vercelInfrAI Date: Wed, 5 Feb 2025 15:31:16 +0800 Subject: [PATCH 15/36] feat: add deepseek models for novita ai --- gui/src/pages/AddNewModel/configs/models.ts | 54 +++++++++++++++++++ .../pages/AddNewModel/configs/providers.ts | 3 +- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/gui/src/pages/AddNewModel/configs/models.ts b/gui/src/pages/AddNewModel/configs/models.ts index 3bd4c262dc..607e466d9c 100644 --- a/gui/src/pages/AddNewModel/configs/models.ts +++ b/gui/src/pages/AddNewModel/configs/models.ts @@ -37,6 +37,60 @@ export interface ModelPackage { } export const models: { [key: string]: ModelPackage } = { + deepseekV3Chat: { + title: "deepseek v3", + description: "A model from deekseek for chat", + refUrl: "", + params: { + title: "deepseek_v3", + model: "deepseek/deepseek_v3", + contextLength: 2048, + }, + icon: "deepseek.png", + dimensions: [ + { + name: "Parameter Count", + description: "The number of parameters in the model", + options: { + "r1": { + model: "deepseek/deepseek_v3", + title: "deepseek_v3", + } + }, + }, + ], + providerOptions: [ + "novita" + ], + isOpenSource: true, + }, + deepseekR1Chat: { + title: "deepseek r1", + description: "A model from deekseek for chat", + refUrl: "", + params: { + title: "deepseek-r1", + model: "deepseek/deepseek-r1", + contextLength: 2048, + }, + icon: "deepseek.png", + dimensions: [ + { + name: "Parameter Count", + description: "The number of parameters in the model", + options: { + "r1": { + model: "deepseek/deepseek-r1", + title: "deepseek-r1", + } + }, + }, + ], + providerOptions: [ + "novita" + ], + isOpenSource: true, + }, llama318BChat: { title: "Llama 3.1 8B", description: "A model from Meta, fine-tuned for chat", diff --git a/gui/src/pages/AddNewModel/configs/providers.ts b/gui/src/pages/AddNewModel/configs/providers.ts index bf6fe735d4..604f1a108f 100644 --- a/gui/src/pages/AddNewModel/configs/providers.ts +++ b/gui/src/pages/AddNewModel/configs/providers.ts @@ -427,7 +427,8 @@ Select the \`GPT-4o\` model below to complete your provider configuration, but n }, ...completionParamsInputsConfigs, ], - packages: [models.llama318BChat, models.mistralChat].map((p) => { + packages: [models.llama318BChat, models.mistralChat, + models.deepseekR1Chat, models.deepseekV3Chat].map((p) => { p.params.contextLength = 4096; return p; }), From f7e4e34ac52511d15c60409ed50c2e3fb304af4b Mon Sep 17 00:00:00 2001 From: Piotr Czekaj Date: Wed, 5 Feb 2025 11:08:57 +0100 Subject: [PATCH 16/36] Fix contradictory instruction in .continuerules docs --- docs/docs/customize/deep-dives/rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/customize/deep-dives/rules.md b/docs/docs/customize/deep-dives/rules.md index f53135b50e..ae8347f296 100644 --- a/docs/docs/customize/deep-dives/rules.md +++ b/docs/docs/customize/deep-dives/rules.md @@ -12,7 +12,7 @@ You can create a project-specific system message by adding a `.continuerules` fi - If you want concise answers: ```title=.continuerules -Please provide concise answers. Do explain obvious concepts. You can assume that I am knowledgable about most programming topics. +Please provide concise answers. Don't explain obvious concepts. You can assume that I am knowledgable about most programming topics. ``` - If you want to ensure certain practices are followed, for example in React: From 3366ee2866afc60d8e37d0b1ae14c2df8cbfc8b1 Mon Sep 17 00:00:00 2001 From: Nate Date: Wed, 5 Feb 2025 09:54:11 -0800 Subject: [PATCH 17/36] bump version --- extensions/vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 8154011243..5ef76d3dc6 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -2,7 +2,7 @@ "name": "continue", "icon": "media/icon.png", "author": "Continue Dev, Inc", - "version": "0.9.260", + "version": "0.9.261", "repository": { "type": "git", "url": "https://github.com/continuedev/continue" From 0c2de5cb5fa744895436d2a70d1d8d90c58befca Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 10:38:38 -0800 Subject: [PATCH 18/36] update tutorial files --- .../ContinuePluginStartupActivity.kt | 8 +++++ .../src/main/resources/continue_tutorial.java | 19 +++++++++--- .../src/main/resources/continue_tutorial.py | 29 ++++++++++++++----- .../src/main/resources/continue_tutorial.ts | 23 +++++++++++---- extensions/vscode/src/util/tutorial.ts | 7 ++++- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/activities/ContinuePluginStartupActivity.kt b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/activities/ContinuePluginStartupActivity.kt index 72819421ac..bae7857a46 100644 --- a/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/activities/ContinuePluginStartupActivity.kt +++ b/extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/activities/ContinuePluginStartupActivity.kt @@ -47,7 +47,15 @@ fun showTutorial(project: Project) { throw IOException("Resource not found: $tutorialFileName") } var content = StreamUtil.readText(`is`, StandardCharsets.UTF_8) + + // All jetbrains will use J instead of L + content = content.replace("[Cmd + L]", "[Cmd + J]") + content = content.replace("[Cmd + Shift + L]", "[Cmd + Shift + J]") + if (!System.getProperty("os.name").lowercase().contains("mac")) { + content = content.replace("[Cmd + J]", "[Ctrl + J]") + content = content.replace("[Cmd + Shift + J]", "[Ctrl + Shift + J]") + content = content.replace("[Cmd + I]", "[Ctrl + I]") content = content.replace("⌘", "⌃") } val filepath = Paths.get(getContinueGlobalPath(), tutorialFileName).toString() diff --git a/extensions/intellij/src/main/resources/continue_tutorial.java b/extensions/intellij/src/main/resources/continue_tutorial.java index 808f51021f..ace69a67d4 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.java +++ b/extensions/intellij/src/main/resources/continue_tutorial.java @@ -7,11 +7,18 @@ // Chat, Edit, and Autocomplete tutorial // +// ———————————————————————————————————————————————— Setup ————————————————————————————————————————————————- + +// First, open the Continue sidebar by pressing [Cmd + L] or clicking the Continue icon. + +// See an example at https://docs.continue.dev/getting-started/install + +// Follow the instructions in the sidebar to setup models for Chat and Autocomplete. // ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— // Highlight the code below -// Press [Cmd/Ctrl + J] to add to Chat +// Press [Cmd + L] to add to Chat // Try asking Continue "what sorting algorithm is this?" public static int[] sortingAlgorithm(int[] x) { for (int i = 0; i < x.length; i++) { @@ -26,10 +33,13 @@ public static int[] sortingAlgorithm(int[] x) { return x; } +// [Cmd + L] always starts a new chat. Now, try the same thing using [Cmd + Shift + L]. +// This will add the code into the current chat + // ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— // Highlight the code below -// Press [Cmd/Ctrl + I] to Edit +// Press [Cmd + I] to Edit // Try asking Continue to "make this more readable" public static int[] sortingAlgorithm2(int[] x) { for (int i = 0; i < x.length; i++) { @@ -46,10 +56,11 @@ public static int[] sortingAlgorithm2(int[] x) { // ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— -// Place cursor after `sortingAlgorithm...` below and press [Enter] +// Place cursor after `sortingAlgorithm:` below and press [Enter] // Press [Tab] to accept the Autocomplete suggestion -// Basic assertion for sortingAlgorithm... +// Basic assertion for sortingAlgorithm: + // —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— diff --git a/extensions/intellij/src/main/resources/continue_tutorial.py b/extensions/intellij/src/main/resources/continue_tutorial.py index 16a297c16c..0b526993d0 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.py +++ b/extensions/intellij/src/main/resources/continue_tutorial.py @@ -7,11 +7,18 @@ Chat, Edit, and Autocomplete tutorial """ +# ———————————————————————————————————————————————— Setup ————————————————————————————————————————————————- -# ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— # +# First, open the Continue sidebar by pressing [Cmd + L] or clicking the Continue icon. + +# See an example at https://docs.continue.dev/getting-started/install + +# Follow the instructions in the sidebar to set up models for Chat and Autocomplete. + +# ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— ## Highlight the code below -## Press [Cmd/Ctrl + J] to add to Chat +## Press [Cmd + L] to add to Chat ## Try asking Continue "what sorting algorithm is this?" def sorting_algorithm(x): for i in range(len(x)): @@ -20,11 +27,13 @@ def sorting_algorithm(x): x[j], x[j + 1] = x[j + 1], x[j] return x +# [Cmd + L] always starts a new chat. Now, try the same thing using [Cmd + Shift + L]. +# This will add the code into the current chat -# ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— # +# ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— ## Highlight the code below -## Press [Cmd/Ctrl + I] to Edit +## Press [Cmd + I] to Edit ## Try asking Continue to "make this more readable" def sorting_algorithm(x): for i in range(len(x)): @@ -33,12 +42,16 @@ def sorting_algorithm(x): x[j], x[j + 1] = x[j + 1], x[j] return x -# ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— # +# ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— -## Place cursor after `sorting_algorithm...` below and press [Enter] +## Place cursor after `sorting_algorithm:` below and press [Enter] ## Press [Tab] to accept the Autocomplete suggestion -# Basic assertion for sorting_algorithm... +# Basic assertion for sorting_algorithm: + + + +# —————————————————————————————————————————————- Learn More -—————————————————————————————————————————————— -# —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— # +# Visit the Continue Docs at https://docs.continue.dev/getting-started/overview diff --git a/extensions/intellij/src/main/resources/continue_tutorial.ts b/extensions/intellij/src/main/resources/continue_tutorial.ts index 1f47142496..9d6271e57d 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.ts +++ b/extensions/intellij/src/main/resources/continue_tutorial.ts @@ -7,10 +7,18 @@ // Chat, Edit, and Autocomplete tutorial // +// ———————————————————————————————————————————————— Setup ————————————————————————————————————————————————- + +// First, open the Continue sidebar by pressing [Cmd + L] or clicking the Continue icon. + +// See an example at https://docs.continue.dev/getting-started/install + +// Follow the instructions in the sidebar to set up models for Chat and Autocomplete. + // ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— // Highlight the code below -// Press [Cmd/Ctrl + J] to add to Chat +// Press [Cmd + L] to add to Chat // Try asking Continue "what sorting algorithm is this?" function sortingAlgorithm(x: number[]): number[] { for (let i = 0; i < x.length; i++) { @@ -25,10 +33,13 @@ function sortingAlgorithm(x: number[]): number[] { return x; } +// [Cmd + L] always starts a new chat. Now, try the same thing using [Cmd + Shift + L]. +// This will add the code into the current chat + // ————————————————————————————————————————————————— Edit ————————————————————————————————————————————————— // Highlight the code below -// Press [Cmd/Ctrl + I] to Edit +// Press [Cmd + I] to Edit // Try asking Continue to "make this more readable" function sortingAlgorithm2(x: number[]): number[] { for (let i = 0; i < x.length; i++) { @@ -45,9 +56,11 @@ function sortingAlgorithm2(x: number[]): number[] { // ————————————————————————————————————————————— Autocomplete —————————————————————————————————————————————— -// Place cursor after `sortingAlgorithm...` below and press [Enter] +// Place cursor after `sortingAlgorithm:` below and press [Enter] // Press [Tab] to accept the Autocomplete suggestion -// Basic assertion for sortingAlgorithm... +// Basic assertion for sortingAlgorithm: + +// —————————————————————————————————————————————- Learn More -—————————————————————————————————————————————— -// —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— +// Visit the Continue Docs at https://docs.continue.dev/getting-started/overview diff --git a/extensions/vscode/src/util/tutorial.ts b/extensions/vscode/src/util/tutorial.ts index 45a86a6757..6557b57904 100644 --- a/extensions/vscode/src/util/tutorial.ts +++ b/extensions/vscode/src/util/tutorial.ts @@ -16,7 +16,12 @@ export async function showTutorial(ide: IDE) { // Ensure keyboard shortcuts match OS if (process.platform !== "darwin") { let tutorialContent = await ide.readFile(tutorialUri.toString()); - tutorialContent = tutorialContent.replace("⌘", "^").replace("Cmd", "Ctrl"); + tutorialContent = tutorialContent + .replaceAll("[Cmd + L]", "[Ctrl + L]") + .replaceAll("[Cmd + Shift + L]", "[Ctrl + Shift + L]") + .replaceAll("[Cmd + I]", "[Ctrl + I]") + .replaceAll("⌘", "^"); + await ide.writeFile(tutorialUri.toString(), tutorialContent); } From ed690c72576de1eee0dc4e4e78b74ab1b4cb6bcd Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 10:39:52 -0800 Subject: [PATCH 19/36] tutorial file unify --- extensions/intellij/src/main/resources/continue_tutorial.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/intellij/src/main/resources/continue_tutorial.java b/extensions/intellij/src/main/resources/continue_tutorial.java index ace69a67d4..a0cb9fa5d3 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.java +++ b/extensions/intellij/src/main/resources/continue_tutorial.java @@ -63,4 +63,6 @@ public static int[] sortingAlgorithm2(int[] x) { -// —————————————————— Learn more at https://docs.continue.dev/getting-started/overview ——————————————————— +// —————————————————————————————————————————————- Learn More -—————————————————————————————————————————————— + +// Visit the Continue Docs at https://docs.continue.dev/getting-started/overview From 0728b17cdb5b9433ffa8e031cb6aa570afa55d8d Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 11:38:46 -0800 Subject: [PATCH 20/36] tutorial copy updates --- extensions/intellij/src/main/resources/continue_tutorial.java | 2 +- extensions/intellij/src/main/resources/continue_tutorial.py | 2 +- extensions/intellij/src/main/resources/continue_tutorial.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/intellij/src/main/resources/continue_tutorial.java b/extensions/intellij/src/main/resources/continue_tutorial.java index a0cb9fa5d3..e566b14ce6 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.java +++ b/extensions/intellij/src/main/resources/continue_tutorial.java @@ -13,7 +13,7 @@ // See an example at https://docs.continue.dev/getting-started/install -// Follow the instructions in the sidebar to setup models for Chat and Autocomplete. +// Follow the instructions in the sidebar to set up a Chat/Edit modela and an Autocomplete model. // ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— diff --git a/extensions/intellij/src/main/resources/continue_tutorial.py b/extensions/intellij/src/main/resources/continue_tutorial.py index 0b526993d0..4670772dfa 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.py +++ b/extensions/intellij/src/main/resources/continue_tutorial.py @@ -13,7 +13,7 @@ # See an example at https://docs.continue.dev/getting-started/install -# Follow the instructions in the sidebar to set up models for Chat and Autocomplete. +# Follow the instructions in the sidebar to set up a Chat/Edit modela and an Autocomplete model. # ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— diff --git a/extensions/intellij/src/main/resources/continue_tutorial.ts b/extensions/intellij/src/main/resources/continue_tutorial.ts index 9d6271e57d..4cde323ca6 100644 --- a/extensions/intellij/src/main/resources/continue_tutorial.ts +++ b/extensions/intellij/src/main/resources/continue_tutorial.ts @@ -13,7 +13,7 @@ // See an example at https://docs.continue.dev/getting-started/install -// Follow the instructions in the sidebar to set up models for Chat and Autocomplete. +// Follow the instructions in the sidebar to set up a Chat/Edit modela and an Autocomplete model. // ————————————————————————————————————————————————— Chat ————————————————————————————————————————————————— From 4f088a2d0ba7b85715f9ee4c191d724cce9b9f58 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 11:46:11 -0800 Subject: [PATCH 21/36] padding between consecutive codeblocks --- gui/src/components/markdown/StepContainerPreActionButtons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/src/components/markdown/StepContainerPreActionButtons.tsx b/gui/src/components/markdown/StepContainerPreActionButtons.tsx index 641e17c133..5cb33d9397 100644 --- a/gui/src/components/markdown/StepContainerPreActionButtons.tsx +++ b/gui/src/components/markdown/StepContainerPreActionButtons.tsx @@ -84,7 +84,7 @@ export default function StepContainerPreActionButtons({ tabIndex={-1} onMouseEnter={() => setHovering(true)} onMouseLeave={() => setHovering(false)} - className="bg-vsc-editor-background border-vsc-input-border relative rounded-md border-[1px] border-solid" + className="bg-vsc-editor-background border-vsc-input-border relative my-2.5 rounded-md border-[1px] border-solid" >
{children}
{hovering && !isStreaming && ( From bcf2ac9ebf68f11e3705b96c6d9575e7b8d74216 Mon Sep 17 00:00:00 2001 From: Nate Date: Wed, 5 Feb 2025 13:32:35 -0800 Subject: [PATCH 22/36] revert package.json dep changes --- extensions/vscode/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index a2dafa82dc..35d360a678 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -703,7 +703,6 @@ "ncp": "^2.0.0", "node-fetch": "^3.3.2", "node-machine-id": "^1.1.12", - "partial-json": "^0.1.7", "posthog-node": "^3.6.3", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", @@ -720,7 +719,6 @@ "vectordb": "^0.4.20", "vscode-languageclient": "^8.0.2", "ws": "^8.13.0", - "yarn": "^1.22.21", - "zod": "^3.24.1" + "yarn": "^1.22.21" } } From b8098c8ff159076e3338f2dbbf43e641041f6220 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 14:02:33 -0800 Subject: [PATCH 23/36] osr context menu --- gui/src/components/Layout.tsx | 2 + gui/src/components/OSRContextMenu.tsx | 100 ++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 gui/src/components/OSRContextMenu.tsx diff --git a/gui/src/components/Layout.tsx b/gui/src/components/Layout.tsx index 747c2ddab1..94a9fb616a 100644 --- a/gui/src/components/Layout.tsx +++ b/gui/src/components/Layout.tsx @@ -23,6 +23,7 @@ import { AuthProvider } from "../context/Auth"; import { exitEditMode } from "../redux/thunks"; import { loadLastSession, saveCurrentSession } from "../redux/thunks/session"; import { incrementFreeTrialCount } from "../util/freeTrial"; +import OSRContextMenu from "./OSRContextMenu"; const LayoutTopDiv = styled(CustomScrollbarDiv)` height: 100%; @@ -261,6 +262,7 @@ const Layout = () => { return ( +
{ + const ideMessenger = useContext(IdeMessengerContext); + + const [position, setPosition] = useState<{ + top?: number; + left?: number; + bottom?: number; + right?: number; + } | null>(null); + const menuRef = React.useRef(null); + + const isOSREnabled = useIsOSREnabled(); + useEffect(() => { + function leaveWindowHandler(event: MouseEvent) { + setPosition(null); + } + function contextMenuHandler(event: MouseEvent) { + event.preventDefault(); + } + function rightClickHandler(event: MouseEvent) { + if (!menuRef.current?.contains(event.target as Node)) { + setPosition(null); + } + if (event.button === 2) { + event.preventDefault(); + + // always open towards inside of window from click + const toRight = event.clientX > window.innerWidth / 2; + const toBottom = event.clientY > window.innerHeight / 2; + if (toRight) { + if (toBottom) { + setPosition({ + bottom: window.innerHeight - event.clientY, + right: window.innerWidth - event.clientX, + }); + } else { + setPosition({ + top: event.clientY, + right: window.innerWidth - event.clientX, + }); + } + } else { + if (toBottom) { + setPosition({ + bottom: window.innerHeight - event.clientY, + left: event.clientX, + }); + } else { + setPosition({ + top: event.clientY, + left: event.clientX, + }); + } + } + } + } + + if (isOSREnabled) { + document.addEventListener("mouseleave", leaveWindowHandler); + document.addEventListener("contextmenu", contextMenuHandler); + document.addEventListener("mousedown", rightClickHandler); + } + + return () => { + document.removeEventListener("mouseleave", leaveWindowHandler); + document.removeEventListener("contextmenu", contextMenuHandler); + document.removeEventListener("mousedown", rightClickHandler); + }; + }, [isOSREnabled, menuRef]); + + if (!position) { + return null; + } + return ( +
+
{ + e.stopPropagation(); + ideMessenger.post("toggleDevTools", undefined); + }} + > + Toggle Dev Tools +
+
+ ); +}; + +export default OSRContextMenu; From 008afdaf0a8a995d0976b6e5e50c1454e5fff518 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 17:17:07 -0800 Subject: [PATCH 24/36] add copy cut paste --- gui/src/components/OSRContextMenu.tsx | 156 +++++++++++++++++++++++--- 1 file changed, 138 insertions(+), 18 deletions(-) diff --git a/gui/src/components/OSRContextMenu.tsx b/gui/src/components/OSRContextMenu.tsx index 063e3de250..a8dd530377 100644 --- a/gui/src/components/OSRContextMenu.tsx +++ b/gui/src/components/OSRContextMenu.tsx @@ -1,34 +1,112 @@ -import React, { useContext, useEffect, useState } from "react"; +import React, { useContext, useEffect, useRef, useState } from "react"; import useIsOSREnabled from "../hooks/useIsOSREnabled"; import { IdeMessengerContext } from "../context/IdeMessenger"; +interface Position { + top?: number; + left?: number; + bottom?: number; + right?: number; +} + const OSRContextMenu = () => { const ideMessenger = useContext(IdeMessengerContext); - const [position, setPosition] = useState<{ - top?: number; - left?: number; - bottom?: number; - right?: number; - } | null>(null); + const [position, setPosition] = useState(null); + const [canCopy, setCanCopy] = useState(false); + const [canCut, setCanCut] = useState(false); + const [canPaste, setCanPaste] = useState(false); + const menuRef = React.useRef(null); + const selectedTextRef = useRef(null); + const selectedRangeRef = useRef(null); + + function onMenuItemClick( + event: React.MouseEvent, + ) { + event.preventDefault(); + + // restore selection + if (selectedRangeRef.current) { + const selection = window.getSelection(); + selection?.removeAllRanges(); + selection?.addRange(selectedRangeRef.current); + } + + // Hide menu + setPosition(null); + } const isOSREnabled = useIsOSREnabled(); useEffect(() => { - function leaveWindowHandler(event: MouseEvent) { + function leaveWindowHandler() { setPosition(null); } function contextMenuHandler(event: MouseEvent) { event.preventDefault(); } - function rightClickHandler(event: MouseEvent) { + function clickHandler(event: MouseEvent) { + // If clicked outside of menu, close menu if (!menuRef.current?.contains(event.target as Node)) { setPosition(null); } + if (event.button === 2) { + // Prevent default context menu event.preventDefault(); - // always open towards inside of window from click + selectedRangeRef.current = null; + selectedTextRef.current = null; + + const selection = window.getSelection(); + let isClickWithinSelection = false; + if (selection && selection.rangeCount > 0) { + const range = selection.getRangeAt(0); + const selectedText = range.toString(); + selectedRangeRef.current = range.cloneRange(); + + if (selectedText.length > 0) { + if (selectedText) { + selectedTextRef.current = selectedText; + const rects = range.getClientRects(); + for (let i = 0; i < rects.length; i++) { + const rect = rects[i]; + if ( + event.clientX >= rect.left && + event.clientX <= rect.right && + event.clientY >= rect.top && + event.clientY <= rect.bottom + ) { + isClickWithinSelection = true; + break; + } + } + } + } + } + + // Check if right clicked on editable content (allows paste/cut) + let isEditable = false; + if ( + event.target && + "isContentEditable" in event.target && + typeof event.target.isContentEditable === "boolean" + ) { + isEditable = event.target.isContentEditable; + } + + setCanCopy(!!selectedTextRef.current && isClickWithinSelection); + setCanCut( + !!(isEditable && selectedTextRef.current && isClickWithinSelection), + ); + + // TODO only can paste if there is text in clipboard? + setCanPaste(isEditable); + // navigator.clipboard.readText().then((text) => { + // setCanPaste(text || null); + // }); + + // Open towards inside of window from click const toRight = event.clientX > window.innerWidth / 2; const toBottom = event.clientY > window.innerHeight / 2; if (toRight) { @@ -59,39 +137,81 @@ const OSRContextMenu = () => { } } + setPosition(null); if (isOSREnabled) { document.addEventListener("mouseleave", leaveWindowHandler); document.addEventListener("contextmenu", contextMenuHandler); - document.addEventListener("mousedown", rightClickHandler); + document.addEventListener("mousedown", clickHandler); } return () => { document.removeEventListener("mouseleave", leaveWindowHandler); document.removeEventListener("contextmenu", contextMenuHandler); - document.removeEventListener("mousedown", rightClickHandler); + document.removeEventListener("mousedown", clickHandler); }; - }, [isOSREnabled, menuRef]); + }, [isOSREnabled]); if (!position) { return null; } return (
+ {canCopy && ( +
{ + onMenuItemClick(e); + document.execCommand("copy"); + }} + > + Copy +
+ )} + {canCut && ( +
{ + onMenuItemClick(e); + document.execCommand("cut"); + }} + > + Cut +
+ )} + {/* PASTING is currently broken, can't get the clipboard text */} + {/* {canPaste && ( +
{ + onMenuItemClick(e); + const clipboardText = await navigator.clipboard.readText(); + // const out = await navigator.clipboard.read(); + if (clipboardText) { + selectedRangeRef.current?.deleteContents(); + selectedRangeRef.current?.insertNode( + document.createTextNode(clipboardText), + ); + } + }} + > + Paste +
+ )} */}
{ - e.stopPropagation(); + onMenuItemClick(e); ideMessenger.post("toggleDevTools", undefined); }} > - Toggle Dev Tools + Open Dev Tools
); From c0e728ad644355ef7a1a1b8598fa7770f4052b8c Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 17:27:06 -0800 Subject: [PATCH 25/36] don't show for mac --- gui/src/components/OSRContextMenu.tsx | 8 +++++++- gui/src/components/mainInput/handleMetaKeyIssues.ts | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/gui/src/components/OSRContextMenu.tsx b/gui/src/components/OSRContextMenu.tsx index a8dd530377..5fcfafefe9 100644 --- a/gui/src/components/OSRContextMenu.tsx +++ b/gui/src/components/OSRContextMenu.tsx @@ -1,6 +1,7 @@ import React, { useContext, useEffect, useRef, useState } from "react"; import useIsOSREnabled from "../hooks/useIsOSREnabled"; import { IdeMessengerContext } from "../context/IdeMessenger"; +import { getPlatform } from "../util"; interface Position { top?: number; @@ -11,6 +12,7 @@ interface Position { const OSRContextMenu = () => { const ideMessenger = useContext(IdeMessengerContext); + const platform = useRef(getPlatform()); const [position, setPosition] = useState(null); const [canCopy, setCanCopy] = useState(false); @@ -39,6 +41,10 @@ const OSRContextMenu = () => { const isOSREnabled = useIsOSREnabled(); useEffect(() => { + if (platform.current === "mac") { + return; + } + function leaveWindowHandler() { setPosition(null); } @@ -151,7 +157,7 @@ const OSRContextMenu = () => { }; }, [isOSREnabled]); - if (!position) { + if (platform.current === "mac" || !isOSREnabled || !position) { return null; } return ( diff --git a/gui/src/components/mainInput/handleMetaKeyIssues.ts b/gui/src/components/mainInput/handleMetaKeyIssues.ts index 14bf3f7929..1adf5593a8 100644 --- a/gui/src/components/mainInput/handleMetaKeyIssues.ts +++ b/gui/src/components/mainInput/handleMetaKeyIssues.ts @@ -3,7 +3,6 @@ import { KeyboardEvent } from "react"; import { getPlatform, isWebEnvironment } from "../../util"; const isWebEnv = isWebEnvironment(); -const platform = getPlatform(); /** * This handles various keypress issues when OSR is enabled @@ -14,6 +13,7 @@ export const handleJetBrainsOSRMetaKeyIssues = ( ) => { const selection = window.getSelection(); const alter = e.shiftKey ? "extend" : "move"; + const platform = getPlatform(); const handlers: Record void> = { Backspace: () => handleJetBrainsMetaBackspace(editor), @@ -108,6 +108,7 @@ export const handleJetBrainsMetaBackspace = (editor: Editor) => { } // For Linux/Windows, only delete the word to the left of the cursor + const platform = getPlatform(); if (platform !== "mac") { deleteSingleWord(editor); break; From d840d48b7900a50797d515375feaf6b193abdef5 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 17:30:52 -0800 Subject: [PATCH 26/36] fix platform logic for custom context menu --- gui/src/components/OSRContextMenu.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/gui/src/components/OSRContextMenu.tsx b/gui/src/components/OSRContextMenu.tsx index 5fcfafefe9..f6cf6e33c0 100644 --- a/gui/src/components/OSRContextMenu.tsx +++ b/gui/src/components/OSRContextMenu.tsx @@ -12,6 +12,7 @@ interface Position { const OSRContextMenu = () => { const ideMessenger = useContext(IdeMessengerContext); + const isOSREnabled = useIsOSREnabled(); const platform = useRef(getPlatform()); const [position, setPosition] = useState(null); @@ -39,12 +40,7 @@ const OSRContextMenu = () => { setPosition(null); } - const isOSREnabled = useIsOSREnabled(); useEffect(() => { - if (platform.current === "mac") { - return; - } - function leaveWindowHandler() { setPosition(null); } @@ -144,16 +140,16 @@ const OSRContextMenu = () => { } setPosition(null); - if (isOSREnabled) { + if (isOSREnabled && platform.current !== "mac") { + document.addEventListener("mousedown", clickHandler); document.addEventListener("mouseleave", leaveWindowHandler); document.addEventListener("contextmenu", contextMenuHandler); - document.addEventListener("mousedown", clickHandler); } return () => { + document.removeEventListener("mousedown", clickHandler); document.removeEventListener("mouseleave", leaveWindowHandler); document.removeEventListener("contextmenu", contextMenuHandler); - document.removeEventListener("mousedown", clickHandler); }; }, [isOSREnabled]); From 0e70ff083ea4cdad70e56b303b6e740fc0f816b8 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 17:38:09 -0800 Subject: [PATCH 27/36] remove default chat and autocomplete models --- core/config/default.ts | 20 ++----------------- .../components/BestExperienceConfigForm.tsx | 4 ---- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/core/config/default.ts b/core/config/default.ts index 8662be678d..23e709603f 100644 --- a/core/config/default.ts +++ b/core/config/default.ts @@ -5,20 +5,6 @@ import { SlashCommandDescription, } from "../"; -export const DEFAULT_CHAT_MODEL_CONFIG: ModelDescription = { - model: "claude-3-5-sonnet-latest", - provider: "anthropic", - apiKey: "", - title: "Claude 3.5 Sonnet", -}; - -export const DEFAULT_AUTOCOMPLETE_MODEL_CONFIG: ModelDescription = { - title: "Codestral", - provider: "mistral", - model: "codestral-latest", - apiKey: "", -}; - export const FREE_TRIAL_MODELS: ModelDescription[] = [ { title: "Claude 3.5 Sonnet (Free Trial)", @@ -93,15 +79,13 @@ export const defaultSlashCommandsJetBrains = [ ]; export const defaultConfig: SerializedContinueConfig = { - models: [DEFAULT_CHAT_MODEL_CONFIG], - tabAutocompleteModel: DEFAULT_AUTOCOMPLETE_MODEL_CONFIG, + models: [], contextProviders: defaultContextProvidersVsCode, slashCommands: defaultSlashCommandsVscode, }; export const defaultConfigJetBrains: SerializedContinueConfig = { - models: [DEFAULT_CHAT_MODEL_CONFIG], - tabAutocompleteModel: DEFAULT_AUTOCOMPLETE_MODEL_CONFIG, + models: [], contextProviders: defaultContextProvidersJetBrains, slashCommands: defaultSlashCommandsJetBrains, }; diff --git a/gui/src/components/OnboardingCard/components/BestExperienceConfigForm.tsx b/gui/src/components/OnboardingCard/components/BestExperienceConfigForm.tsx index 86e7cd693a..98f71cce2b 100644 --- a/gui/src/components/OnboardingCard/components/BestExperienceConfigForm.tsx +++ b/gui/src/components/OnboardingCard/components/BestExperienceConfigForm.tsx @@ -1,5 +1,4 @@ import { CubeIcon } from "@heroicons/react/24/outline"; -import { DEFAULT_CHAT_MODEL_CONFIG } from "core/config/default"; import { FormEventHandler, useContext, useState } from "react"; import { useDispatch } from "react-redux"; import { Button, Input, InputSubtext, lightGray } from "../.."; @@ -57,9 +56,6 @@ function BestExperienceConfigForm({ apiKey: autocompleteApiKey, }; - ideMessenger.post("config/deleteModel", { - title: DEFAULT_CHAT_MODEL_CONFIG.title, - }); ideMessenger.post("config/addModel", { model: chatModelConfig }); ideMessenger.post("config/addModel", { model: repoMapConfig, From dac8bae2ba3541fd976249e28d53fd5b3a53b08a Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 17:52:37 -0800 Subject: [PATCH 28/36] hide onboarding close X's if no models in config --- gui/src/components/OnboardingCard/OnboardingCard.tsx | 4 +++- .../OnboardingCard/platform/PlatformOnboardingCard.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gui/src/components/OnboardingCard/OnboardingCard.tsx b/gui/src/components/OnboardingCard/OnboardingCard.tsx index eebbfb2bc9..f48e2939d0 100644 --- a/gui/src/components/OnboardingCard/OnboardingCard.tsx +++ b/gui/src/components/OnboardingCard/OnboardingCard.tsx @@ -5,6 +5,7 @@ import styled from "styled-components"; import { CloseButton, defaultBorderRadius, vscInputBackground } from "../"; import { getLocalStorage, setLocalStorage } from "../../util/localStorage"; import { useOnboardingCard } from "./hooks/useOnboardingCard"; +import { useAppSelector } from "../../redux/hooks"; const StyledCard = styled.div` margin: auto; @@ -26,6 +27,7 @@ interface OnboardingCardProps { export function OnboardingCard({ isDialog }: OnboardingCardProps) { const onboardingCard = useOnboardingCard(); + const config = useAppSelector((store) => store.config.config); function renderTabContent() { switch (onboardingCard.activeTab) { @@ -53,7 +55,7 @@ export function OnboardingCard({ isDialog }: OnboardingCardProps) { activeTab={onboardingCard.activeTab || "Best"} onTabClick={onboardingCard.setActiveTab} /> - {!isDialog && ( + {!isDialog && !!config.models.length && ( onboardingCard.close()}> diff --git a/gui/src/components/OnboardingCard/platform/PlatformOnboardingCard.tsx b/gui/src/components/OnboardingCard/platform/PlatformOnboardingCard.tsx index ede9295b3b..51e9514970 100644 --- a/gui/src/components/OnboardingCard/platform/PlatformOnboardingCard.tsx +++ b/gui/src/components/OnboardingCard/platform/PlatformOnboardingCard.tsx @@ -8,6 +8,7 @@ import { TabTitle } from "../components/OnboardingCardTabs"; import { useOnboardingCard } from "../hooks"; import OnboardingLocalTab from "../tabs/OnboardingLocalTab"; import MainTab from "./tabs/main"; +import { useAppSelector } from "../../../redux/hooks"; const StyledCard = styled.div` margin: auto; @@ -29,6 +30,7 @@ interface OnboardingCardProps { export function PlatformOnboardingCard({ isDialog }: OnboardingCardProps) { const onboardingCard = useOnboardingCard(); + const config = useAppSelector((store) => store.config.config); if (getLocalStorage("onboardingStatus") === undefined) { setLocalStorage("onboardingStatus", "Started"); @@ -38,7 +40,7 @@ export function PlatformOnboardingCard({ isDialog }: OnboardingCardProps) { return ( - {!isDialog && ( + {!isDialog && !!config.models.length && ( onboardingCard.close()}> From 85fbf451ffc0d5465112de8494c2220f6018d4d8 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 18:51:59 -0800 Subject: [PATCH 29/36] handle git diff errors and logic --- core/autocomplete/snippets/getAllSnippets.ts | 7 ++++++- .../v1/slashCommandFromPromptFile.ts | 17 +++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/core/autocomplete/snippets/getAllSnippets.ts b/core/autocomplete/snippets/getAllSnippets.ts index 198bf16c65..fc6538b415 100644 --- a/core/autocomplete/snippets/getAllSnippets.ts +++ b/core/autocomplete/snippets/getAllSnippets.ts @@ -90,7 +90,12 @@ const getClipboardSnippets = async ( const getDiffSnippets = async ( ide: IDE, ): Promise => { - const diff = await ide.getDiff(true); + let diff: string[] = []; + try { + diff = await ide.getDiff(true); + } catch (e) { + console.error("Error getting diff for autocomplete", e); + } return diff.map((item) => { return { diff --git a/core/promptFiles/v1/slashCommandFromPromptFile.ts b/core/promptFiles/v1/slashCommandFromPromptFile.ts index d89ee10825..b0dc0f8811 100644 --- a/core/promptFiles/v1/slashCommandFromPromptFile.ts +++ b/core/promptFiles/v1/slashCommandFromPromptFile.ts @@ -25,15 +25,20 @@ async function renderPromptV1( ) { const helpers = getContextProviderHelpers(context); - // A few context providers that don't need to be in config.json to work in .prompt files - const diff = await context.ide.getDiff(true); - const currentFile = await context.ide.getCurrentFile(); const inputData: Record = { - diff: diff.join("\n"), input: userInput, }; - if (currentFile) { - inputData.currentFile = currentFile.path; + + // A few context providers that don't need to be in config.json to work in .prompt files + if (helpers?.find((helper) => helper[0] === "diff")) { + const diff = await context.ide.getDiff(true); + inputData.diff = diff.join("\n"); + } + if (helpers?.find((helper) => helper[0] === "currentFile")) { + const currentFile = await context.ide.getCurrentFile(); + if (currentFile) { + inputData.currentFile = currentFile.path; + } } return renderTemplatedString( From f2c6c9f4cb4ffedb0b8468f35546b2d654ec034f Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Wed, 5 Feb 2025 18:58:04 -0800 Subject: [PATCH 30/36] check for HTTP at beginning of error message --- gui/src/pages/gui/StreamError.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/src/pages/gui/StreamError.tsx b/gui/src/pages/gui/StreamError.tsx index ca3bc04bca..2a8465c301 100644 --- a/gui/src/pages/gui/StreamError.tsx +++ b/gui/src/pages/gui/StreamError.tsx @@ -51,7 +51,8 @@ const StreamErrorDialog = ({ error }: StreamErrorProps) => { typeof error["message"] === "string" ) { message = error["message"]; - const status = message?.split(" ")[0]; + const parts = message?.split(" ") ?? []; + const status = parts[0] === "HTTP" ? parts[1] : parts[0]; if (status) { const code = Number(status); if (!Number.isNaN(statusCode)) { From 9fafa83ba19aead93947219e1294f20da7a33d42 Mon Sep 17 00:00:00 2001 From: Ru Chern Chong Date: Thu, 6 Feb 2025 11:51:31 +0800 Subject: [PATCH 31/36] Add gemini-2.0-flash to schema --- extensions/vscode/config_schema.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/vscode/config_schema.json b/extensions/vscode/config_schema.json index 827662dd24..d9dab076b3 100644 --- a/extensions/vscode/config_schema.json +++ b/extensions/vscode/config_schema.json @@ -936,7 +936,8 @@ "gemini-1.5-flash-latest", "gemini-1.5-flash", "gemini-1.5-flash-8b", - "gemini-2.0-flash-exp" + "gemini-2.0-flash-exp", + "gemini-2.0-flash" ] } } From d18518228b09dbd9689a06908817682a497ed9e2 Mon Sep 17 00:00:00 2001 From: prakashsharma91 Date: Thu, 6 Feb 2025 17:37:00 +0530 Subject: [PATCH 32/36] Correct or add chat model icons --- gui/public/logos/siliconflow.png | Bin 0 -> 29089 bytes gui/src/pages/AddNewModel/configs/providers.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 gui/public/logos/siliconflow.png diff --git a/gui/public/logos/siliconflow.png b/gui/public/logos/siliconflow.png new file mode 100644 index 0000000000000000000000000000000000000000..f32fc6ebf84f0a60fabd3e0a42f27bded426931f GIT binary patch literal 29089 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 Date: Thu, 6 Feb 2025 12:25:06 -0800 Subject: [PATCH 33/36] fix templateMessages null logic --- core/llm/autodetect.ts | 7 +++++-- core/llm/index.ts | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/llm/autodetect.ts b/core/llm/autodetect.ts index 8232f82887..ed1901641e 100644 --- a/core/llm/autodetect.ts +++ b/core/llm/autodetect.ts @@ -1,4 +1,4 @@ -import { ModelCapability, TemplateType } from "../index.js"; +import { ChatMessage, ModelCapability, TemplateType } from "../index.js"; import { anthropicTemplateMessages, @@ -257,7 +257,10 @@ function autodetectTemplateFunction( const templateType = explicitTemplate ?? autodetectTemplateType(model); if (templateType) { - const mapping: Record = { + const mapping: Record< + TemplateType, + null | ((msg: ChatMessage[]) => string) + > = { llama2: llama2TemplateMessages, alpaca: templateAlpacaMessages, phi2: phi2TemplateMessages, diff --git a/core/llm/index.ts b/core/llm/index.ts index da18254074..4989f14faa 100644 --- a/core/llm/index.ts +++ b/core/llm/index.ts @@ -191,7 +191,8 @@ export abstract class BaseLLM implements ILLM { options.model, this.providerName, options.template, - ); + ) ?? + undefined; this.writeLog = options.writeLog; this.llmRequestHook = options.llmRequestHook; this.apiKey = options.apiKey; @@ -957,7 +958,9 @@ export abstract class BaseLLM implements ILLM { this.providerName, autodetectTemplateType(this.model), ); - return templateMessages(rendered); + if (templateMessages) { + return templateMessages(rendered); + } } return rendered; } From 9140c1ea81f06f9e0756d4226b9d6bb87e3858c5 Mon Sep 17 00:00:00 2001 From: Adam Shedivy Date: Thu, 6 Feb 2025 16:47:48 -0600 Subject: [PATCH 34/36] Refactor reloadConfig method to use class property for additional context providers --- core/config/ConfigHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/config/ConfigHandler.ts b/core/config/ConfigHandler.ts index 4ad045d30f..4638613b9c 100644 --- a/core/config/ConfigHandler.ts +++ b/core/config/ConfigHandler.ts @@ -365,11 +365,11 @@ export class ConfigHandler { this.updateListeners.push(listener); } - async reloadConfig(additionalContextProviders: IContextProvider[] = []) { + async reloadConfig() { // TODO: this isn't right, there are two different senses in which you want to "reload" const { config, errors, configLoadInterrupted } = - await this.currentProfile.reloadConfig(additionalContextProviders); + await this.currentProfile.reloadConfig(this.additionalContextProviders); if (config) { this.inactiveProfiles.forEach((profile) => profile.clearConfig()); @@ -419,6 +419,6 @@ export class ConfigHandler { registerCustomContextProvider(contextProvider: IContextProvider) { this.additionalContextProviders.push(contextProvider); - void this.reloadConfig(this.additionalContextProviders); + void this.reloadConfig(); } } From f41cdd58d096ced9a8d6e76c9011187231a1cb7d Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Fri, 7 Feb 2025 07:22:14 -0800 Subject: [PATCH 35/36] Update preview.yaml --- .github/workflows/preview.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/preview.yaml b/.github/workflows/preview.yaml index bd5f4b7acb..b35e7d203e 100644 --- a/.github/workflows/preview.yaml +++ b/.github/workflows/preview.yaml @@ -4,6 +4,13 @@ on: release: types: [prereleased] + workflow_dispatch: + inputs: + publish_build: + description: "Whether or not to publish the built extension to the VS Code marketplace" + required: true + default: false + jobs: check_release_name: runs-on: ubuntu-latest From d3d5e470e9436188d008753c0d3959708b3f6ae9 Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Fri, 7 Feb 2025 09:41:38 -0800 Subject: [PATCH 36/36] Update preview.yaml --- .github/workflows/preview.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview.yaml b/.github/workflows/preview.yaml index b35e7d203e..945f8d84bf 100644 --- a/.github/workflows/preview.yaml +++ b/.github/workflows/preview.yaml @@ -28,7 +28,7 @@ jobs: build: needs: check_release_name - if: needs.check_release_name.outputs.should_run == 'true' + if: needs.check_release_name.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch' strategy: matrix: include: @@ -204,6 +204,7 @@ jobs: runs-on: ubuntu-latest needs: - build + if: github.event.inputs.publish_build == 'true' permissions: contents: write steps: