Sfoglia il codice sorgente

Merge pull request #2843 from Kilo-Org/mark/generate-prompts-once

Generate autocomplete prompts once
Mark IJbema 4 mesi fa
parent
commit
558d0ffddc

+ 1 - 2
src/services/ghost/GhostProvider.ts

@@ -253,8 +253,7 @@ export class GhostProvider {
 		this.isRequestCancelled = false
 
 		const context = await this.ghostContext.generate(initialContext)
-		const systemPrompt = this.strategy.getSystemPrompt(context)
-		const userPrompt = this.strategy.getSuggestionPrompt(context)
+		const { systemPrompt, userPrompt } = this.strategy.getPrompts(context)
 		if (this.isRequestCancelled) {
 			return
 		}

+ 6 - 20
src/services/ghost/GhostStrategy.ts

@@ -14,30 +14,16 @@ export class GhostStrategy {
 	}
 
 	/**
-	 * Get the system prompt based on context using the new strategy system
-	 * Overloaded to support both new context-based and legacy string-only calls
-	 */
-	getSystemPrompt(context: GhostSuggestionContext): string {
-		const { systemPrompt, strategy } = this.strategyManager.buildPrompt(context)
-		if (this.debug) {
-			console.log(`[GhostStrategy] Using strategy: ${strategy.name}`)
-		}
-		return systemPrompt
-	}
-
-	/**
-	 * Get the user prompt based on context using the new strategy system
+	 * Get both system and user prompts based on context
 	 * @param context The suggestion context
-	 * @returns The user prompt
+	 * @returns Object containing systemPrompt and userPrompt
 	 */
-	getSuggestionPrompt(context: GhostSuggestionContext): string {
-		const { userPrompt, strategy } = this.strategyManager.buildPrompt(context)
-
+	getPrompts(context: GhostSuggestionContext): { systemPrompt: string; userPrompt: string } {
+		const { systemPrompt, userPrompt, strategy } = this.strategyManager.buildPrompt(context)
 		if (this.debug) {
-			console.log(`[GhostStrategy] Generated prompt with strategy: ${strategy.name}`)
+			console.log(`[GhostStrategy] Using strategy: ${strategy.name}`)
 		}
-
-		return userPrompt
+		return { systemPrompt, userPrompt }
 	}
 
 	/**

+ 2 - 3
src/services/ghost/__tests__/GhostModelPerformance.spec.ts

@@ -25,10 +25,9 @@ describe("GhostModelPerformance", () => {
 			document: document,
 		}
 
-		const systemPrompt = strategy.getSystemPrompt(context)
-		const suggestionPrompt = strategy.getSuggestionPrompt(context)
+		const { systemPrompt, userPrompt } = strategy.getPrompts(context)
 
-		return { systemPrompt, suggestionPrompt }
+		return { systemPrompt, suggestionPrompt: userPrompt }
 	}
 
 	const performTest = async (apiHandler: ApiHandler, prompt: { systemPrompt: string; suggestionPrompt: string }) => {

+ 4 - 4
src/services/ghost/__tests__/GhostRecentOperations.spec.ts

@@ -116,11 +116,11 @@ describe("GhostRecentOperations", () => {
 		expect(enrichedContext.recentOperations?.length).toBeGreaterThan(0)
 
 		// Generate prompt
-		const prompt = strategy.getSuggestionPrompt(enrichedContext)
+		const { userPrompt } = strategy.getPrompts(enrichedContext)
 
 		// Verify that the prompt includes the recent operations section
 		// The new strategy system uses "## Recent Typing" format
-		expect(prompt).toContain("## Recent Typing")
+		expect(userPrompt).toContain("## Recent Typing")
 	})
 
 	it("should not include recent operations in the prompt when not available", async () => {
@@ -133,11 +133,11 @@ describe("GhostRecentOperations", () => {
 		const enrichedContext = await context.generate(suggestionContext)
 
 		// Generate prompt
-		const prompt = strategy.getSuggestionPrompt(enrichedContext)
+		const { userPrompt } = strategy.getPrompts(enrichedContext)
 
 		// Verify that the prompt does not include recent operations section
 		// The current document content will still be in the prompt, so we should only check
 		// that the "**Recent Changes (Diff):**" section is not present
-		expect(prompt.includes("**Recent Changes (Diff):**")).toBe(false)
+		expect(userPrompt.includes("**Recent Changes (Diff):**")).toBe(false)
 	})
 })

+ 20 - 6
src/services/ghost/__tests__/GhostStrategy.spec.ts

@@ -232,25 +232,39 @@ describe("GhostStrategy", () => {
 	})
 
 	describe("prompt generation", () => {
-		it("should generate system prompt", () => {
+		it("should generate both prompts efficiently with getPrompts", () => {
+			const context: GhostSuggestionContext = {
+				document: mockDocument,
+				userInput: "Add a comment",
+				range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
+			}
+
+			const { systemPrompt, userPrompt } = strategy.getPrompts(context)
+			expect(systemPrompt).toContain("CRITICAL OUTPUT FORMAT")
+			expect(systemPrompt).toContain("XML-formatted changes")
+			expect(userPrompt).toContain("Add a comment")
+			expect(userPrompt).toContain("<<<AUTOCOMPLETE_HERE>>>")
+		})
+
+		it("should generate system prompt via getPrompts", () => {
 			const context: GhostSuggestionContext = {
 				document: mockDocument,
 			}
-			const systemPrompt = strategy.getSystemPrompt(context)
+			const { systemPrompt } = strategy.getPrompts(context)
 			expect(systemPrompt).toContain("CRITICAL OUTPUT FORMAT")
 			expect(systemPrompt).toContain("XML-formatted changes")
 		})
 
-		it("should generate suggestion prompt with context", () => {
+		it("should generate suggestion prompt with context via getPrompts", () => {
 			const context: GhostSuggestionContext = {
 				document: mockDocument,
 				userInput: "Add a comment",
 				range: new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 0)),
 			}
 
-			const suggestionPrompt = strategy.getSuggestionPrompt(context)
-			expect(suggestionPrompt).toContain("Add a comment")
-			expect(suggestionPrompt).toContain("<<<AUTOCOMPLETE_HERE>>>")
+			const { userPrompt } = strategy.getPrompts(context)
+			expect(userPrompt).toContain("Add a comment")
+			expect(userPrompt).toContain("<<<AUTOCOMPLETE_HERE>>>")
 		})
 	})
 })

+ 9 - 35
src/services/ghost/__tests__/GhostStrategy.test.ts

@@ -13,8 +13,8 @@ describe("GhostStrategy", () => {
 		strategy = new GhostStrategy()
 	})
 
-	describe("getSystemPrompt", () => {
-		it("should use PromptStrategyManager to generate system prompt", () => {
+	describe("getPrompts", () => {
+		it("should use PromptStrategyManager to generate prompts", () => {
 			const mockDocument = {
 				languageId: "typescript",
 				getText: () => "const x = 1;",
@@ -27,10 +27,10 @@ describe("GhostStrategy", () => {
 				userInput: "Complete this function",
 			}
 
-			const prompt = strategy.getSystemPrompt(context)
+			const { systemPrompt } = strategy.getPrompts(context)
 
 			// Should contain base instructions from strategy system
-			expect(prompt).toContain("CRITICAL OUTPUT FORMAT")
+			expect(systemPrompt).toContain("CRITICAL OUTPUT FORMAT")
 		})
 
 		it("should select UserRequestStrategy when user input is provided", () => {
@@ -47,8 +47,7 @@ describe("GhostStrategy", () => {
 				userInput: "Add a function to calculate sum",
 			}
 
-			const systemPrompt = strategy.getSystemPrompt(context)
-			const userPrompt = strategy.getSuggestionPrompt(context)
+			const { systemPrompt, userPrompt } = strategy.getPrompts(context)
 
 			// UserRequestStrategy should be selected
 			expect(systemPrompt).toContain("Execute User's Explicit Request")
@@ -80,35 +79,13 @@ describe("GhostStrategy", () => {
 				],
 			}
 
-			const systemPrompt = strategy.getSystemPrompt(context)
+			const { systemPrompt } = strategy.getPrompts(context)
 
 			// ErrorFixStrategy should be selected
 			expect(systemPrompt).toContain("Fix Compilation Errors and Warnings")
 		})
 	})
 
-	describe("getSuggestionPrompt", () => {
-		it("should delegate to PromptStrategyManager", () => {
-			const mockDocument = {
-				languageId: "typescript",
-				getText: () => "const x = 1;",
-				lineAt: (line: number) => ({ text: "const x = 1;" }),
-				uri: { toString: () => "file:///test.ts" },
-				offsetAt: (position: vscode.Position) => 13,
-			} as vscode.TextDocument
-
-			const context: GhostSuggestionContext = {
-				document: mockDocument,
-			}
-
-			const prompt = strategy.getSuggestionPrompt(context)
-
-			// Should return a structured prompt
-			expect(prompt).toBeDefined()
-			expect(prompt.length).toBeGreaterThan(0)
-		})
-	})
-
 	describe("Integration", () => {
 		it("should work with both system and user prompts", () => {
 			const mockDocument = {
@@ -124,8 +101,7 @@ describe("GhostStrategy", () => {
 				userInput: "Complete this function",
 			}
 
-			const systemPrompt = strategy.getSystemPrompt(context)
-			const userPrompt = strategy.getSuggestionPrompt(context)
+			const { systemPrompt, userPrompt } = strategy.getPrompts(context)
 
 			// System prompt should contain format instructions
 			expect(systemPrompt).toContain("CRITICAL OUTPUT FORMAT")
@@ -220,8 +196,7 @@ describe("GhostStrategy", () => {
 				document: mockDocument,
 			}
 
-			const systemPrompt = strategy.getSystemPrompt(context)
-			const userPrompt = strategy.getSuggestionPrompt(context)
+			const { systemPrompt, userPrompt } = strategy.getPrompts(context)
 
 			expect(systemPrompt).toBeDefined()
 			expect(systemPrompt.length).toBeGreaterThan(0)
@@ -279,8 +254,7 @@ describe("GhostStrategy", () => {
 			]
 
 			contexts.forEach((context) => {
-				const systemPrompt = strategy.getSystemPrompt(context as GhostSuggestionContext)
-				const userPrompt = strategy.getSuggestionPrompt(context as GhostSuggestionContext)
+				const { systemPrompt, userPrompt } = strategy.getPrompts(context as GhostSuggestionContext)
 
 				expect(systemPrompt).toBeDefined()
 				expect(systemPrompt.length).toBeGreaterThan(0)