mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 01:51:21 +08:00
test(vscode): extract parseAutocompleteResponse and add COMPLETION tag tests
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
FillInAtCursorSuggestion,
|
||||
ChatCompletionResult,
|
||||
} from "../types"
|
||||
import { parseAutocompleteResponse as _parseAutocompleteResponse } from "./hole-filler-utils"
|
||||
import { getProcessedSnippets } from "./getProcessedSnippets"
|
||||
import { formatSnippets } from "../continuedev/core/autocomplete/templating/formatting"
|
||||
import { AutocompleteModel, ApiStreamChunk } from "../AutocompleteModel"
|
||||
@@ -20,24 +21,7 @@ export function parseAutocompleteResponse(
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
): FillInAtCursorSuggestion {
|
||||
let fimText: string = ""
|
||||
|
||||
// Match content strictly between <COMPLETION> and </COMPLETION> tags
|
||||
const completionMatch = fullResponse.match(/<COMPLETION>([\s\S]*?)<\/COMPLETION>/i)
|
||||
|
||||
if (completionMatch) {
|
||||
// Extract the captured group (content between tags)
|
||||
fimText = completionMatch[1] || ""
|
||||
}
|
||||
// Remove any accidentally captured tag remnants
|
||||
fimText = fimText.replace(/<\/?COMPLETION>/gi, "")
|
||||
|
||||
// Return FillInAtCursorSuggestion with the text (empty string if nothing found)
|
||||
return {
|
||||
text: fimText,
|
||||
prefix,
|
||||
suffix,
|
||||
}
|
||||
return _parseAutocompleteResponse(fullResponse, prefix, suffix)
|
||||
}
|
||||
|
||||
export class HoleFiller {
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import type { FillInAtCursorSuggestion } from "../types"
|
||||
|
||||
/**
|
||||
* Parse a chat completion response and extract the text between <COMPLETION> tags.
|
||||
* Returns a FillInAtCursorSuggestion with the extracted text, or empty string if not found.
|
||||
*/
|
||||
export function parseAutocompleteResponse(
|
||||
fullResponse: string,
|
||||
prefix: string,
|
||||
suffix: string,
|
||||
): FillInAtCursorSuggestion {
|
||||
let fimText = ""
|
||||
const completionMatch = fullResponse.match(/<COMPLETION>([\s\S]*?)<\/COMPLETION>/i)
|
||||
if (completionMatch) {
|
||||
fimText = completionMatch[1] || ""
|
||||
}
|
||||
fimText = fimText.replace(/<\/?COMPLETION>/gi, "")
|
||||
return { text: fimText, prefix, suffix }
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { describe, it, expect } from "bun:test"
|
||||
import { parseAutocompleteResponse } from "../../src/services/autocomplete/classic-auto-complete/hole-filler-utils"
|
||||
|
||||
describe("parseAutocompleteResponse", () => {
|
||||
const prefix = "function foo() {\n "
|
||||
const suffix = "\n}"
|
||||
|
||||
it("extracts content between COMPLETION tags", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION>return 42;</COMPLETION>", prefix, suffix)
|
||||
expect(result.text).toBe("return 42;")
|
||||
expect(result.prefix).toBe(prefix)
|
||||
expect(result.suffix).toBe(suffix)
|
||||
})
|
||||
|
||||
it("returns empty text when no COMPLETION tags", () => {
|
||||
const result = parseAutocompleteResponse("return 42;", prefix, suffix)
|
||||
expect(result.text).toBe("")
|
||||
})
|
||||
|
||||
it("handles multiline completion content", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION>const x = 1;\nreturn x;</COMPLETION>", prefix, suffix)
|
||||
expect(result.text).toBe("const x = 1;\nreturn x;")
|
||||
})
|
||||
|
||||
it("handles case-insensitive tags", () => {
|
||||
const result = parseAutocompleteResponse("<completion>return x;</completion>", prefix, suffix)
|
||||
expect(result.text).toBe("return x;")
|
||||
})
|
||||
|
||||
it("handles empty COMPLETION tags", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION></COMPLETION>", prefix, suffix)
|
||||
expect(result.text).toBe("")
|
||||
})
|
||||
|
||||
it("handles whitespace-only content in tags", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION> </COMPLETION>", prefix, suffix)
|
||||
expect(result.text).toBe(" ")
|
||||
})
|
||||
|
||||
it("handles response with prose before and after tags", () => {
|
||||
const response = "Here is your completion:\n<COMPLETION>return value;</COMPLETION>\nHope that helps!"
|
||||
const result = parseAutocompleteResponse(response, prefix, suffix)
|
||||
expect(result.text).toBe("return value;")
|
||||
})
|
||||
|
||||
it("removes accidentally captured tag remnants", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION><COMPLETION>inner</COMPLETION></COMPLETION>", prefix, suffix)
|
||||
expect(result.text).toBe("inner")
|
||||
})
|
||||
|
||||
it("returns empty text for empty response", () => {
|
||||
const result = parseAutocompleteResponse("", prefix, suffix)
|
||||
expect(result.text).toBe("")
|
||||
})
|
||||
|
||||
it("preserves prefix and suffix in result", () => {
|
||||
const result = parseAutocompleteResponse("<COMPLETION>x</COMPLETION>", "pre", "suf")
|
||||
expect(result.prefix).toBe("pre")
|
||||
expect(result.suffix).toBe("suf")
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user