Skip to content

Commit 841818d

Browse files
committed
Merge branch 'main' of https://github.com/continuedev/continue into adarsh/enhancement/deduplication
2 parents 6b166db + cb71da7 commit 841818d

File tree

181 files changed

+6001
-3206
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+6001
-3206
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
globs: gui/**/*
3+
description: Ensures consistent URL opening behavior in GUI components using the
4+
IDE messenger pattern
5+
alwaysApply: false
6+
---
7+
8+
# GUI Link Opening
9+
10+
When adding functionality to open external links in GUI components, use `ideMessenger.post("openUrl", url)` where `ideMessenger` is obtained from `useContext(IdeMessengerContext)`

.github/workflows/pr_checks.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ jobs:
435435
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
436436
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
437437
AZURE_FOUNDRY_API_KEY: ${{ secrets.AZURE_FOUNDRY_API_KEY }}
438+
AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
439+
AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
438440

439441
package-tests:
440442
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ Icon?
146146

147147
*.notes.md
148148
notes.md
149+
*.notes.md
149150

150151
manual-testing-sandbox/.idea/**
151152
manual-testing-sandbox/.continue/**
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { vi } from "vitest";
2+
3+
export const fetchwithRequestOptions = vi.fn(
4+
async (url, options, requestOptions) => {
5+
console.log("Mocked fetch called with:", url, options, requestOptions);
6+
return {
7+
ok: true,
8+
status: 200,
9+
statusText: "OK",
10+
};
11+
},
12+
);
13+
14+
export const streamSse = vi.fn(function* () {
15+
yield "";
16+
});

core/autocomplete/CompletionProvider.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,12 @@ export class CompletionProvider {
114114
this.loggingService.markDisplayed(completionId, outcome);
115115
}
116116

117-
private async _getAutocompleteOptions() {
117+
private async _getAutocompleteOptions(llm: ILLM) {
118118
const { config } = await this.configHandler.loadConfig();
119119
const options = {
120120
...DEFAULT_AUTOCOMPLETE_OPTS,
121121
...config?.tabAutocompleteOptions,
122+
...llm.autocompleteOptions,
122123
};
123124
return options;
124125
}
@@ -136,15 +137,16 @@ export class CompletionProvider {
136137
token = controller.signal;
137138
}
138139
const startTime = Date.now();
139-
const options = await this._getAutocompleteOptions();
140140

141-
// Debounce
142-
if (await this.debouncer.delayAndShouldDebounce(options.debounceDelay)) {
141+
const llm = await this._prepareLlm();
142+
if (!llm) {
143143
return undefined;
144144
}
145145

146-
const llm = await this._prepareLlm();
147-
if (!llm) {
146+
const options = await this._getAutocompleteOptions(llm);
147+
148+
// Debounce
149+
if (await this.debouncer.delayAndShouldDebounce(options.debounceDelay)) {
148150
return undefined;
149151
}
150152

core/autocomplete/prefiltering/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import ignore from "ignore";
22

33
import { IDE } from "../..";
4+
import {
5+
getGlobalContinueIgArray,
6+
getWorkspaceContinueIgArray,
7+
} from "../../indexing/ignore";
48
import { getConfigJsonPath } from "../../util/paths";
59
import { findUriInDirs } from "../../util/uri";
610
import { HelperVars } from "../util/HelperVars";
@@ -50,7 +54,12 @@ export async function shouldPrefilter(
5054
}
5155

5256
// Check whether autocomplete is disabled for this file
53-
const disableInFiles = [...(helper.options.disableInFiles ?? []), "*.prompt"];
57+
const disableInFiles = [
58+
...(helper.options.disableInFiles ?? []),
59+
"*.prompt",
60+
...getGlobalContinueIgArray(),
61+
...(await getWorkspaceContinueIgArray(ide)),
62+
];
5463
if (await isDisabledForFile(helper.filepath, disableInFiles, ide)) {
5564
return true;
5665
}

core/autocomplete/snippets/getAllSnippets.ts

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -113,38 +113,55 @@ const getSnippetsFromRecentlyOpenedFiles = async (
113113
return [];
114114
}
115115

116-
const snippets: AutocompleteCodeSnippet[] = [];
117-
118116
try {
119117
const currentFileUri = `${helper.filepath}`;
120118

121-
// converts cache file URIs to autocomplete snippets
122-
for (const [fileUri, _] of openedFilesLruCache.entriesDescending()) {
123-
if (fileUri === currentFileUri) {
124-
continue;
125-
}
126-
127-
try {
128-
const fileContent = await ide.readFile(fileUri);
129-
130-
if (!fileContent || fileContent.trim() === "") {
131-
continue;
132-
}
133-
134-
snippets.push({
135-
filepath: fileUri,
136-
content: fileContent,
137-
type: AutocompleteSnippetType.Code,
138-
});
139-
} catch (e) {
140-
console.error(`Failed to read file ${fileUri}:`, e);
141-
}
142-
}
119+
// Get all file URIs excluding the current file
120+
const fileUrisToRead = [...openedFilesLruCache.entriesDescending()]
121+
.filter(([fileUri, _]) => fileUri !== currentFileUri)
122+
.map(([fileUri, _]) => fileUri);
123+
124+
// Create an array of promises that each read a file with timeout
125+
const fileReadPromises = fileUrisToRead.map((fileUri) => {
126+
// Create a promise that resolves to a snippet or null
127+
const readPromise = new Promise<AutocompleteCodeSnippet | null>(
128+
(resolve) => {
129+
ide
130+
.readFile(fileUri)
131+
.then((fileContent) => {
132+
if (!fileContent || fileContent.trim() === "") {
133+
resolve(null);
134+
return;
135+
}
136+
137+
resolve({
138+
filepath: fileUri,
139+
content: fileContent,
140+
type: AutocompleteSnippetType.Code,
141+
});
142+
})
143+
.catch((e) => {
144+
console.error(`Failed to read file ${fileUri}:`, e);
145+
resolve(null);
146+
});
147+
},
148+
);
149+
// Cut off at 80ms via racing promises
150+
return Promise.race([
151+
readPromise,
152+
new Promise<null>((resolve) => setTimeout(() => resolve(null), 80)),
153+
]);
154+
});
155+
156+
// Execute all file reads in parallel
157+
const results = await Promise.all(fileReadPromises);
158+
159+
// Filter out null results
160+
return results.filter(Boolean) as AutocompleteCodeSnippet[];
143161
} catch (e) {
144162
console.error("Error processing opened files cache:", e);
163+
return [];
145164
}
146-
147-
return snippets;
148165
};
149166

150167
export const getAllSnippets = async ({

0 commit comments

Comments
 (0)