Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Process thinking blocks with Anthropic provider and write to the Output. #4425

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1e97988
Add replaceSystemMessage LLM option and update relevant functionality…
ferenci84 Jan 20, 2025
b058b60
Add replaceSystemMessage configuration option to config_schema.json
ferenci84 Jan 20, 2025
d92e046
Merge branch 'refs/heads/autocomplete_context_fix' into my_testing
ferenci84 Feb 1, 2025
ac07ef4
Merge branch 'refs/heads/replace_system_message_option' into my_testing
ferenci84 Feb 1, 2025
9cbf808
Merge branch 'refs/heads/autocomplete_context_fix' into my_testing
ferenci84 Feb 2, 2025
cc344b7
Merge branch 'refs/heads/autocomplete_context_fix' into my_testing
ferenci84 Feb 4, 2025
3e63618
Merge branch 'refs/heads/fix_recently_edited_tracker' into my_testing
ferenci84 Feb 4, 2025
3ee6c3b
update completion logic to handle midline insertions more accurately …
ferenci84 Feb 5, 2025
fd39744
Merge branch 'refs/heads/autocomplete_context_fix' into my_testing
ferenci84 Feb 6, 2025
be2c9cb
Create processSingleLineCompletion pure function with unit tests
ferenci84 Feb 7, 2025
4cc1cdd
fix formatting issues
ferenci84 Feb 7, 2025
f135102
Merge branch 'refs/heads/main' into completion_provider_replacement_d…
ferenci84 Feb 7, 2025
cd663de
Merge branch 'refs/heads/completion_provider_replacement_diffpattern'…
ferenci84 Feb 8, 2025
8770999
Merge branch 'refs/heads/tabs_feature_2' into my_testing
ferenci84 Feb 9, 2025
5fe26fd
Merge remote-tracking branch 'origin/main' into my_testing
ferenci84 Feb 9, 2025
70afddc
Merge branch 'refs/heads/diff_cache' into my_testing
ferenci84 Feb 14, 2025
75ad4e3
increase cache size in lsp.ts, update diff retrieval in ideUtils.ts
ferenci84 Feb 15, 2025
19b6f53
Merge branch 'refs/heads/main' into my_testing
ferenci84 Feb 15, 2025
24fcdc5
Merge branch 'refs/heads/diff_cache' into my_testing
ferenci84 Feb 15, 2025
560c3de
Add package to tasks.json
ferenci84 Feb 15, 2025
375da44
update TabBar styling and session handling logic
ferenci84 Feb 15, 2025
bd3d09c
Merge branch 'refs/heads/package_task' into my_testing
ferenci84 Feb 15, 2025
93fcd0e
Merge tag 'refs/tags/v0.9.269-vscode' into my_testing
ferenci84 Feb 21, 2025
bd33042
Merge branch 'refs/heads/main' into my_testing
ferenci84 Feb 28, 2025
547db22
add `ThinkingChatMessage` interface and handle thinking chunks in `Ba…
ferenci84 Mar 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions core/autocomplete/util/completionTestUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
processTestCase,
type CompletionTestCase,
} from "./completionTestUtils";

describe("processTestCase utility", () => {
it("processes simple console.log completion", () => {
const testCase: CompletionTestCase = {
original: "console.log(|cur||till|)",
completion: "\"foo,\", bar",
};

expect(processTestCase(testCase)).toEqual({
input: {
lastLineOfCompletionText: "\"foo,\", bar",
currentText: ")",
cursorPosition: "console.log(".length,
},
expectedResult: {
completionText: "\"foo,\", bar",
},
});
});

it("processes simple console.log completion with overwriting", () => {
const testCase: CompletionTestCase = {
original: "console.log(|cur|)|till|",
completion: "\"foo,\", bar);",
};

expect(processTestCase(testCase)).toEqual({
input: {
lastLineOfCompletionText: "\"foo,\", bar);",
currentText: ")",
cursorPosition: "console.log(".length,
},
expectedResult: {
completionText: "\"foo,\", bar);",
range: {
start: "console.log(".length,
end: "console.log()".length,
},
},
});
});

it("partially applying completion", () => {
const testCase: CompletionTestCase = {
original: "|cur||till|fetch(\"https://example.com\");",
completion: "await fetch(\"https://example.com\");",
appliedCompletion: "await ",
};

expect(processTestCase(testCase)).toEqual({
input: {
lastLineOfCompletionText: "await fetch(\"https://example.com\");",
currentText: "fetch(\"https://example.com\");",
cursorPosition: 0,
},
expectedResult: {
completionText: "await ",
},
});
});
});
63 changes: 63 additions & 0 deletions core/autocomplete/util/completionTestUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
export interface CompletionTestCase {
original: string; // Text with |cur| and |till| markers
completion: string; // Text to insert/overwrite
appliedCompletion?: string | null;
cursorMarker?: string;
tillMarker?: string;
}

export interface ProcessedTestCase {
input: {
lastLineOfCompletionText: string;
currentText: string;
cursorPosition: number;
};
expectedResult: {
completionText: string;
range?: {
start: number;
end: number;
};
};
}

export function processTestCase({
original,
completion,
appliedCompletion = null,
cursorMarker = "|cur|",
tillMarker = "|till|",
}: CompletionTestCase): ProcessedTestCase {
// Validate cursor marker
if (!original.includes(cursorMarker)) {
throw new Error("Cursor marker not found in original text");
}

const cursorPos = original.indexOf(cursorMarker);
original = original.replace(cursorMarker, "");

let tillPos = original.indexOf(tillMarker);
if (tillPos < 0) {
tillPos = cursorPos;
} else {
original = original.replace(tillMarker, "")
}

// Calculate currentText based on what's between cursor and till marker
const currentText = original.substring(cursorPos);

return {
input: {
lastLineOfCompletionText: completion,
currentText,
cursorPosition: cursorPos,
},
expectedResult: {
completionText: appliedCompletion || completion,
range: cursorPos === tillPos ? undefined : {
start: cursorPos,
end: tillPos,
},
},
};
}
97 changes: 97 additions & 0 deletions core/autocomplete/util/processSingleLineCompletion.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { processTestCase } from "./completionTestUtils";
import { processSingleLineCompletion } from "./processSingleLineCompletion";

describe("processSingleLineCompletion", () => {

it("should handle simple end of line completion", () => {
const testCase = processTestCase({
original: "console.log(|cur|",
completion: "\"Hello, world!\")",
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

it("should handle midline insert repeating the end of line", () => {
const testCase = processTestCase({
original: "console.log(|cur|);|till|",
completion: "\"Hello, world!\");",
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

it("should handle midline insert repeating the end of line plus adding a semicolon", () => {
const testCase = processTestCase({
original: "console.log(|cur|)|till|",
completion: "\"Hello, world!\");",
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

it("should handle simple midline insert", () => {
const testCase = processTestCase({
original: "console.log(|cur|)",
completion: "\"Hello, world!\"",
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

it("should handle complex dif with addition in the beginning", () => {
const testCase = processTestCase({
original: "console.log(|cur||till|, \"param1\", )", // TODO
completion: "\"Hello world!\", \"param1\", param1);",
appliedCompletion: "\"Hello world!\""
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

it("should handle simple insertion even with random equality", () => {
const testCase = processTestCase({
original: "print(f\"Foobar length: |cur||till|\")",
completion: "{len(foobar)}",
});

const result = processSingleLineCompletion(
testCase.input.lastLineOfCompletionText,
testCase.input.currentText,
testCase.input.cursorPosition
);

expect(result).toEqual(testCase.expectedResult);
});

});
92 changes: 92 additions & 0 deletions core/autocomplete/util/processSingleLineCompletion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as Diff from "diff";

interface SingleLineCompletionResult {
completionText: string;
range?: {
start: number;
end: number;
};
}


interface DiffType {
count?: number;
added?: boolean;
removed?: boolean;
value: string;
}


function diffPatternMatches(
diffs: DiffType[],
pattern: DiffPartType[],
): boolean {
if (diffs.length !== pattern.length) {
return false;
}

for (let i = 0; i < diffs.length; i++) {
const diff = diffs[i];
const diffPartType: DiffPartType =
!diff.added && !diff.removed ? "=" : diff.added ? "+" : "-";

if (diffPartType !== pattern[i]) {
return false;
}
}

return true;
}

type DiffPartType = "+" | "-" | "=";

export function processSingleLineCompletion(
lastLineOfCompletionText: string,
currentText: string,
cursorPosition: number
): SingleLineCompletionResult | undefined {
const diffs: DiffType[] = Diff.diffWords(currentText, lastLineOfCompletionText);

if (diffPatternMatches(diffs, ["+"])) {
// Just insert, we're already at the end of the line
return {
completionText: lastLineOfCompletionText,
};
}

if (
diffPatternMatches(diffs, ["+", "="]) ||
diffPatternMatches(diffs, ["+", "=", "+"])
) {
// The model repeated the text after the cursor to the end of the line
return {
completionText: lastLineOfCompletionText,
range: {
start: cursorPosition,
end: currentText.length + cursorPosition,
},
};
}

if (
diffPatternMatches(diffs, ["+", "-"]) ||
diffPatternMatches(diffs, ["-", "+"])
) {
// We are midline and the model just inserted without repeating to the end of the line
return {
completionText: lastLineOfCompletionText,
};
}

// For any other diff pattern, just use the first added part if available
if (diffs[0]?.added) {
return {
completionText: diffs[0].value,
};
}

// Default case: treat as simple insertion
return {
completionText: lastLineOfCompletionText,
};
}
Loading
Loading