mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
refactor(vscode): drop chat-completion fallback in chat textarea autocomplete
Both supported autocomplete models (Codestral, Mercury) expose FIM, and AutocompleteModel.supportsFim() unconditionally returns true. The non-FIM branch in ChatTextAreaAutocomplete together with the getChatSystemPrompt / getChatUserPrompt helpers was never reached. Also removes the accompanying orphaned spec that imported paths that no longer exist (core/config/ProviderSettingsManager, api/transform/stream).
This commit is contained in:
+3
-45
@@ -98,22 +98,9 @@ export class ChatTextAreaAutocomplete {
|
||||
let response = ""
|
||||
|
||||
try {
|
||||
// Use FIM if supported, otherwise fall back to chat-based completion
|
||||
if (this.model.supportsFim()) {
|
||||
await this.model.generateFimResponse(prefix, suffix, (chunk) => {
|
||||
response += chunk
|
||||
})
|
||||
} else {
|
||||
// Fall back to chat-based completion for models without FIM support
|
||||
const systemPrompt = this.getChatSystemPrompt()
|
||||
const userPrompt = this.getChatUserPrompt(prefix)
|
||||
|
||||
await this.model.generateResponse(systemPrompt, userPrompt, (chunk) => {
|
||||
if (chunk.type === "text") {
|
||||
response += chunk.text
|
||||
}
|
||||
})
|
||||
}
|
||||
await this.model.generateFimResponse(prefix, suffix, (chunk) => {
|
||||
response += chunk
|
||||
})
|
||||
|
||||
const latencyMs = Date.now() - startTime
|
||||
|
||||
@@ -153,35 +140,6 @@ export class ChatTextAreaAutocomplete {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get system prompt for chat-based completion
|
||||
*/
|
||||
private getChatSystemPrompt(): string {
|
||||
return `You are an intelligent chat completion assistant. Your task is to complete the user's message naturally based on the provided context.
|
||||
|
||||
## RULES
|
||||
- Provide a natural, conversational completion
|
||||
- Be concise - typically 1-15 words
|
||||
- Match the user's tone and style
|
||||
- Use context from visible code if relevant
|
||||
- NEVER repeat what the user already typed
|
||||
- NEVER start with comments (//, /*, #)
|
||||
- If the user is in the middle of typing a word (e.g., "hel"), include the COMPLETE word in your response (e.g., "hello world" not just "lo world")
|
||||
- This allows proper prefix matching to remove the overlap correctly
|
||||
- Return ONLY the completion text, no explanations or formatting`
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user prompt for chat-based completion
|
||||
*/
|
||||
private getChatUserPrompt(prefix: string): string {
|
||||
return `${prefix}
|
||||
|
||||
TASK: Complete the user's message naturally.
|
||||
- If the user is mid-word (e.g., typed "hel"), return the COMPLETE word (e.g., "hello world") so prefix matching can work correctly
|
||||
- Return ONLY the completion text (what comes next), no explanations.`
|
||||
}
|
||||
|
||||
private async buildPrefix(userText: string, visibleCodeContext?: VisibleCodeContext): Promise<string> {
|
||||
return buildChatPrefix(userText, visibleCodeContext?.editors)
|
||||
}
|
||||
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
import { ChatTextAreaAutocomplete } from "../ChatTextAreaAutocomplete"
|
||||
import { ProviderSettingsManager } from "../../../../core/config/ProviderSettingsManager"
|
||||
import { AutocompleteModel } from "../../AutocompleteModel"
|
||||
import { ApiStreamChunk } from "../../../../api/transform/stream"
|
||||
|
||||
describe("ChatTextAreaAutocomplete", () => {
|
||||
let autocomplete: ChatTextAreaAutocomplete
|
||||
let mockProviderSettingsManager: ProviderSettingsManager
|
||||
|
||||
beforeEach(() => {
|
||||
mockProviderSettingsManager = {} as ProviderSettingsManager
|
||||
autocomplete = new ChatTextAreaAutocomplete(mockProviderSettingsManager)
|
||||
})
|
||||
|
||||
describe("getCompletion", () => {
|
||||
it("should work with non-FIM models using chat-based completion", async () => {
|
||||
// Setup: Model without FIM support (like Mistral)
|
||||
const mockModel = new AutocompleteModel()
|
||||
|
||||
vi.spyOn(mockModel, "hasValidCredentials").mockReturnValue(true)
|
||||
vi.spyOn(mockModel, "supportsFim").mockReturnValue(false)
|
||||
vi.spyOn(mockModel, "generateResponse").mockImplementation(async (systemPrompt, userPrompt, onChunk) => {
|
||||
// Simulate streaming chat response
|
||||
const chunks: ApiStreamChunk[] = [{ type: "text", text: "write a function" }]
|
||||
for (const chunk of chunks) {
|
||||
onChunk(chunk)
|
||||
}
|
||||
return {
|
||||
cost: 0,
|
||||
inputTokens: 15,
|
||||
outputTokens: 8,
|
||||
cacheWriteTokens: 0,
|
||||
cacheReadTokens: 0,
|
||||
}
|
||||
})
|
||||
|
||||
// @ts-expect-error - accessing private property for test
|
||||
autocomplete.model = mockModel
|
||||
|
||||
const result = await autocomplete.getCompletion("How to ")
|
||||
|
||||
expect(mockModel.generateResponse).toHaveBeenCalled()
|
||||
expect(result.suggestion).toBe("write a function")
|
||||
})
|
||||
})
|
||||
|
||||
describe("cleanSuggestion", () => {
|
||||
it("should filter code patterns (comments, preprocessor)", () => {
|
||||
// Comments - filtered by the regex check in cleanSuggestion
|
||||
expect(autocomplete.cleanSuggestion("// comment", "")).toBe("")
|
||||
expect(autocomplete.cleanSuggestion("/* comment", "")).toBe("")
|
||||
expect(autocomplete.cleanSuggestion("* something", "")).toBe("")
|
||||
|
||||
// Code patterns
|
||||
expect(autocomplete.cleanSuggestion("#include", "")).toBe("")
|
||||
expect(autocomplete.cleanSuggestion("# Header", "")).toBe("")
|
||||
})
|
||||
|
||||
it("should filter empty content", () => {
|
||||
// Empty content is filtered by postprocessAutocompleteSuggestion
|
||||
expect(autocomplete.cleanSuggestion("", "")).toBe("")
|
||||
})
|
||||
|
||||
it("should accept natural language suggestions", () => {
|
||||
expect(autocomplete.cleanSuggestion("Hello world", "")).toBe("Hello world")
|
||||
expect(autocomplete.cleanSuggestion("Can you help me", "")).toBe("Can you help me")
|
||||
expect(autocomplete.cleanSuggestion("test123", "")).toBe("test123")
|
||||
expect(autocomplete.cleanSuggestion("What's up?", "")).toBe("What's up?")
|
||||
})
|
||||
|
||||
it("should accept symbols in middle of text", () => {
|
||||
expect(autocomplete.cleanSuggestion("Text with # in middle", "")).toBe("Text with # in middle")
|
||||
expect(autocomplete.cleanSuggestion("Hello // but not a comment", "")).toBe("Hello // but not a comment")
|
||||
})
|
||||
|
||||
it("should truncate at first newline", () => {
|
||||
expect(autocomplete.cleanSuggestion("First line\nSecond line", "")).toBe("First line")
|
||||
})
|
||||
|
||||
it("should remove prefix overlap", () => {
|
||||
expect(autocomplete.cleanSuggestion("Hello world", "Hello ")).toBe("world")
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user