Skip to content

Commit 826806e

Browse files
authored
Merge pull request #549 from devchat-ai/optimize_code_completion_240605
Refactor code for performance optimization and bug fixes
2 parents a0deb37 + dccc6bb commit 826806e

File tree

6 files changed

+48
-44
lines changed

6 files changed

+48
-44
lines changed

gui

src/contributes/codecomplete/chunkFilter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ export class LLMStreamComplete {
277277

278278
// whether lines are repeated some block before
279279
async removeRepeatBlock(lines: string[]): Promise< string[] > {
280-
if (lines.length === 0) {
281-
return [];
280+
if (lines.length <= 1) {
281+
return lines;
282282
}
283283

284284
// find first match line in before 50 lines

src/contributes/codecomplete/llm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ export async function * devchatComplete(prompt: string) : AsyncGenerator<CodeCom
206206
model: model,
207207
prompt: prompt,
208208
stream: true,
209-
stop: ["<|endoftext|>", "<|EOT|>", "<file_sep>", "```", "/", "\n\n"],
209+
stop: ["<|endoftext|>", "<|EOT|>", "<file_sep>", "```", "//", "\n\n"],
210210
temperature: 0.2
211211
};
212212

src/contributes/codecomplete/llm/countTokens.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,17 @@ function countTokens(
4242
// defaults to llama2 because the tokenizer tends to produce more tokens
4343
modelName: string = "llama2",
4444
): number {
45-
const encoding = encodingForModel(modelName);
46-
if (Array.isArray(content)) {
47-
return content.reduce((acc, part) => {
48-
return acc + part.type === "imageUrl"
49-
? countImageTokens(part)
50-
: encoding.encode(part.text ?? "", "all", []).length;
51-
}, 0);
52-
} else {
53-
return encoding.encode(content, "all", []).length;
54-
}
45+
return content.length;
46+
// const encoding = encodingForModel(modelName);
47+
// if (Array.isArray(content)) {
48+
// return content.reduce((acc, part) => {
49+
// return acc + part.type === "imageUrl"
50+
// ? countImageTokens(part)
51+
// : encoding.encode(part.text ?? "", "all", []).length;
52+
// }, 0);
53+
// } else {
54+
// return encoding.encode(content, "all", []).length;
55+
// }
5556
}
5657

5758
function flattenMessages(msgs: ChatMessage[]): ChatMessage[] {

src/contributes/codecomplete/promptCreator.ts

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import { findIdentifiersInAstNodeRange } from './ast/findIdentifiers';
2727
import { DevChatConfig } from '../../util/config';
2828

2929

30-
const CONTEXT_LIMITED_SIZE: number = 6000;
3130
const CONTEXT_SIMILAR_LIMITED_SIZE: number = 400;
3231

3332
const variableCache: MemoryCacheManager = new MemoryCacheManager(4);
@@ -40,7 +39,7 @@ export async function currentFileContext(
4039
curColumn: number
4140
) : Promise< { prefix: string, suffix: string } > {
4241
const contentTokens = countTokens(contents);
43-
if (contentTokens < CONTEXT_LIMITED_SIZE*0.35) {
42+
if (contentTokens < DevChatConfig.getInstance().get("complete_context_limit", 3000)*0.5) {
4443
return curfilePrompt(filepath, contents, curRow, curColumn);
4544
}
4645

@@ -51,7 +50,7 @@ export async function currentFileContext(
5150

5251
const functionRanges = await findFunctionRanges(filepath, ast.rootNode);
5352
return await collapseCodeBlock(functionRanges, filepath, contents, curRow, curColumn);
54-
}
53+
}
5554

5655

5756
export async function collapseCodeBlock(functions: FunctionRange[], filepath: string, contents: string, curRow: number, curColumn: number) {
@@ -186,7 +185,7 @@ async function curfilePrompt(filePath: string, fileContent: string, line: number
186185
}
187186

188187
const lineTokenCount = countTokens(lineText);
189-
if (prefixTokenCount + lineTokenCount > CONTEXT_LIMITED_SIZE*0.7*0.35) {
188+
if (prefixTokenCount + lineTokenCount > DevChatConfig.getInstance().get("complete_context_limit", 3000)*0.7*0.35) {
190189
break;
191190
}
192191

@@ -195,7 +194,7 @@ async function curfilePrompt(filePath: string, fileContent: string, line: number
195194
}
196195

197196
// 从光标所在行下一行开始,向下构建后缀
198-
const suffixMaxToken = CONTEXT_LIMITED_SIZE*0.35 - prefixTokenCount;
197+
const suffixMaxToken = DevChatConfig.getInstance().get("complete_context_limit", 3000)*0.35 - prefixTokenCount;
199198
for (let i = line; i < lines.length; i++) {
200199
let lineText = lines[i] + '\n';
201200
if (i === line) {
@@ -551,17 +550,10 @@ export async function createPrompt(filePath: string, fileContent: string, line:
551550

552551
let { prefix, suffix } = await currentFileContext(filePath, fileContent, line, column);
553552

554-
let tokenCount = countTokens(prefix);
555-
556-
const suffixTokenCount = countTokens(suffix);
557-
if (tokenCount + suffixTokenCount < CONTEXT_LIMITED_SIZE) {
558-
tokenCount += suffixTokenCount;
559-
} else {
560-
suffix = "";
561-
}
553+
let tokenCount = countTokens(prefix) + countTokens(suffix);
562554

563555
let taskDescriptionContextWithCommentPrefix = "";
564-
if (tokenCount < CONTEXT_LIMITED_SIZE) {
556+
if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
565557
const taskDescriptionContext = await createTaskDescriptionContext();
566558
if (taskDescriptionContext) {
567559
taskDescriptionContext.split("\n").forEach(line => {
@@ -572,17 +564,17 @@ export async function createPrompt(filePath: string, fileContent: string, line:
572564
}
573565

574566
const taskDescriptionContextToken = countTokens(taskDescriptionContextWithCommentPrefix);
575-
if (tokenCount + taskDescriptionContextToken < CONTEXT_LIMITED_SIZE) {
567+
if (tokenCount + taskDescriptionContextToken < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
576568
tokenCount += taskDescriptionContextToken;
577569
} else {
578570
taskDescriptionContextWithCommentPrefix = "";
579571
}
580572
}
581573

582574
// let gitDiffContext = GitDiffWatcher.getInstance().getGitDiffResult();
583-
// if (tokenCount < CONTEXT_LIMITED_SIZE && gitDiffContext.length > 0) {
575+
// if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000) && gitDiffContext.length > 0) {
584576
// const gitDiffContextToken = countTokens(gitDiffContext);
585-
// if (tokenCount + gitDiffContextToken < CONTEXT_LIMITED_SIZE) {
577+
// if (tokenCount + gitDiffContextToken < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
586578
// tokenCount += gitDiffContextToken;
587579
// gitDiffContext = "<git_diff_start>" + gitDiffContext + "<git_diff_end>\n\n\n\n";
588580
// } else {
@@ -592,11 +584,11 @@ export async function createPrompt(filePath: string, fileContent: string, line:
592584
let gitDiffContext = "";
593585

594586
let callDefContext = "";
595-
if (tokenCount < CONTEXT_LIMITED_SIZE) {
587+
if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
596588
const callCodeBlocks = await createContextCallDefine(filePath, fileContent, posoffset);
597589
for (const callCodeBlock of callCodeBlocks) {
598590
const callBlockToken = countTokens(callCodeBlock.codeblock);
599-
if (tokenCount + callBlockToken > CONTEXT_LIMITED_SIZE) {
591+
if (tokenCount + callBlockToken > DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
600592
break;
601593
}
602594

@@ -607,18 +599,18 @@ export async function createPrompt(filePath: string, fileContent: string, line:
607599
}
608600

609601
let similarBlockContext = "";
610-
if (tokenCount < CONTEXT_LIMITED_SIZE) {
602+
if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
611603
let similarTokens = 0;
612604
const similarContexts: {file: string, text: string}[] = await findSimilarCodeBlock(filePath, fileContent, line, column);
613605

614606
for (const similarContext of similarContexts) {
615607
const blockToken = countTokens(similarContext.text);
616-
if (tokenCount + blockToken > CONTEXT_LIMITED_SIZE) {
608+
if (tokenCount + blockToken > DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
617609
continue;
618610
}
619611
similarTokens += blockToken;
620-
if (similarTokens > CONTEXT_SIMILAR_LIMITED_SIZE) {
621-
continue;
612+
if (similarTokens > CONTEXT_SIMILAR_LIMITED_SIZE) {
613+
continue;
622614
}
623615

624616
tokenCount += blockToken;
@@ -628,11 +620,11 @@ export async function createPrompt(filePath: string, fileContent: string, line:
628620
}
629621

630622
let symbolContext = "";
631-
if (tokenCount < CONTEXT_LIMITED_SIZE) {
623+
if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
632624
const symbolDefines: { filepath: string, node: Parser.SyntaxNode, codeblock: string }[] = await symbolDefinesContext(filePath, fileContent, line, column);
633625
for (const symbolDefine of symbolDefines ) {
634626
const countSymboleToken = countTokens(symbolDefine.codeblock);
635-
if (tokenCount + countSymboleToken > CONTEXT_LIMITED_SIZE) {
627+
if (tokenCount + countSymboleToken > DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
636628
break;
637629
}
638630

@@ -644,11 +636,11 @@ export async function createPrompt(filePath: string, fileContent: string, line:
644636
}
645637

646638
let recentEditContext = "";
647-
if (tokenCount < CONTEXT_LIMITED_SIZE) {
639+
if (tokenCount < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
648640
recentEditContext = await createRecentEditContext(recentEdits, filePath);
649641

650642
const countRecentToken = countTokens(recentEditContext);
651-
if (tokenCount + countRecentToken < CONTEXT_LIMITED_SIZE) {
643+
if (tokenCount + countRecentToken < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
652644
tokenCount += countRecentToken;
653645
} else {
654646
recentEditContext = "";
@@ -660,7 +652,7 @@ export async function createPrompt(filePath: string, fileContent: string, line:
660652
const neighborFiles = await findNeighborFileContext(filePath, fileContent, line, column);
661653
if (neighborFiles.length > 0) {
662654
const countFileToken = countTokens(neighborFiles[0].text);
663-
if (tokenCount + countFileToken < CONTEXT_LIMITED_SIZE) {
655+
if (tokenCount + countFileToken < DevChatConfig.getInstance().get("complete_context_limit", 3000)) {
664656
tokenCount += countFileToken;
665657
neighborFileContext += `${commentPrefix}<filename>neighbor files:\n\n ${neighborFiles[0].file}\n\n`;
666658
neighborFileContext += `${neighborFiles[0].text}\n\n\n\n`;

src/util/config.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class DevChatConfig {
5454
}
5555
}
5656

57-
public get(key: string | string[]): any {
57+
public get(key: string | string[], defaultValue: any = undefined): any {
5858
// check if the config file has been modified
5959
const currentModifyTime = fs.statSync(this.configFilePath).mtimeMs;
6060
if (currentModifyTime > this.lastModifyTime) {
@@ -68,7 +68,18 @@ export class DevChatConfig {
6868
} else {
6969
keys = key;
7070
}
71-
return keys.reduce((prev, curr) => prev ? prev[curr] : undefined, this.data);
71+
72+
let value = this.data;
73+
for (const k of keys) {
74+
if (value && typeof value === 'object' && k in value) {
75+
value = value[k];
76+
} else {
77+
// If the key is not found or value is not an object, return the default value
78+
return defaultValue || undefined;
79+
}
80+
}
81+
82+
return value;
7283
}
7384

7485
public set(key: string | string[], value: any): void {

0 commit comments

Comments
 (0)