Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 13 additions & 49 deletions src/test-llm-autocompletion/ghost-provider-tester.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,9 @@
import { LLMClient } from "./llm-client.js"
import { HoleFiller, parseGhostResponse } from "../services/ghost/classic-auto-complete/HoleFiller.js"
import { FimPromptBuilder } from "../services/ghost/classic-auto-complete/FillInTheMiddle.js"
import { AutocompleteInput } from "../services/ghost/types.js"
import * as vscode from "vscode"
import crypto from "crypto"
import { extractPrefixSuffix, contextToAutocompleteInput, GhostContextProvider } from "../services/ghost/types.js"
import { createContext } from "./utils.js"

// Mock context provider for standalone testing
function createMockContextProvider(prefix: string, suffix: string, filepath: string) {
return {
getProcessedSnippets: async () => ({
filepathUri: `file://${filepath}`,
helper: {
filepath: `file://${filepath}`,
lang: { name: "typescript", singleLineComment: "//" },
prunedPrefix: prefix,
prunedSuffix: suffix,
},
snippetsWithUris: [],
workspaceDirs: [],
}),
} as any
}

/**
* Check if a model supports FIM (Fill-In-Middle) completions.
* This mirrors the logic in KilocodeOpenrouterHandler.supportsFim()
*/
function modelSupportsFim(modelId: string): boolean {
return modelId.includes("codestral")
}
import { createMockContextProvider, modelSupportsFim } from "./mock-context-provider.js"

export class GhostProviderTester {
private llmClient: LLMClient
Expand All @@ -45,25 +19,15 @@ export class GhostProviderTester {
testCaseName: string = "test",
): Promise<{ prefix: string; completion: string; suffix: string }> {
const context = createContext(code, testCaseName)

const position = context.range?.start ?? new vscode.Position(0, 0)
const offset = context.document.offsetAt(position)
const text = context.document.getText()
const prefix = text.substring(0, offset)
const suffix = text.substring(offset)
const { prefix, suffix } = extractPrefixSuffix(
context.document,
context.range?.start ?? context.document.positionAt(0),
)
const autocompleteInput = contextToAutocompleteInput(context)
const languageId = context.document.languageId || "javascript"
const filepath = context.document.uri.fsPath

// Common setup
const mockContextProvider = createMockContextProvider(prefix, suffix, filepath)
const autocompleteInput: AutocompleteInput = {
isUntitledFile: false,
completionId: crypto.randomUUID(),
filepath,
pos: { line: position.line, character: position.character },
recentlyVisitedRanges: [],
recentlyEditedRanges: [],
}
// Create mock context provider
const mockContextProvider = createMockContextProvider(prefix, suffix, autocompleteInput.filepath)

// Auto-detect strategy based on model capabilities
const supportsFim = modelSupportsFim(this.model)
Expand All @@ -75,8 +39,8 @@ export class GhostProviderTester {
}

private async getFimCompletion(
contextProvider: ReturnType<typeof createMockContextProvider>,
autocompleteInput: AutocompleteInput,
contextProvider: GhostContextProvider,
autocompleteInput: ReturnType<typeof contextToAutocompleteInput>,
): Promise<string> {
const fimPromptBuilder = new FimPromptBuilder(contextProvider)
const prompt = await fimPromptBuilder.getFimPrompts(autocompleteInput, this.model)
Expand All @@ -85,8 +49,8 @@ export class GhostProviderTester {
}

private async getHoleFillerCompletion(
contextProvider: ReturnType<typeof createMockContextProvider>,
autocompleteInput: AutocompleteInput,
contextProvider: GhostContextProvider,
autocompleteInput: ReturnType<typeof contextToAutocompleteInput>,
languageId: string,
prefix: string,
suffix: string,
Expand Down
33 changes: 33 additions & 0 deletions src/test-llm-autocompletion/mock-context-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { GhostContextProvider } from "../services/ghost/types.js"

/**
* Check if a model supports FIM (Fill-In-Middle) completions.
* This mirrors the logic in KilocodeOpenrouterHandler.supportsFim()
*/
export function modelSupportsFim(modelId: string): boolean {
return modelId.includes("codestral")
}

/**
* Create a mock GhostContextProvider for standalone testing.
* This provider simulates the context retrieval without requiring VSCode services.
*/
export function createMockContextProvider(prefix: string, suffix: string, filepath: string): GhostContextProvider {
return {
ide: {
readFile: async () => prefix + suffix,
getWorkspaceDirs: async () => [],
getClipboardContent: async () => ({ text: "", copiedAt: new Date().toISOString() }),
},
contextService: {
initializeForFile: async () => {},
getRootPathSnippets: async () => [],
getSnippetsFromImportDefinitions: async () => [],
getStaticContextSnippets: async () => [],
},
model: {
supportsFim: () => modelSupportsFim(process.env.LLM_MODEL || "mistralai/codestral-2508"),
getModelName: () => process.env.LLM_MODEL || "mistralai/codestral-2508",
},
} as unknown as GhostContextProvider
}