|
1 | 1 | import { GhostSuggestionContext, extractPrefix } from "../types" |
2 | 2 | import { CURSOR_MARKER } from "../ghostConstants" |
3 | | -import { formatDocumentWithCursor, getBaseSystemInstructions } from "./StrategyHelpers" |
4 | 3 | import { isCommentLine, extractComment, cleanComment } from "./CommentHelpers" |
| 4 | +import type { TextDocument, Range } from "vscode" |
| 5 | + |
| 6 | +export function getBaseSystemInstructions(): string { |
| 7 | + return `CRITICAL OUTPUT FORMAT: |
| 8 | +You must respond with XML-formatted changes ONLY. No explanations or text outside XML tags. |
| 9 | +
|
| 10 | +Format: <change><search><![CDATA[exact_code]]></search><replace><![CDATA[new_code]]></replace></change> |
| 11 | +
|
| 12 | +MANDATORY XML STRUCTURE RULES: |
| 13 | +- Every <change> tag MUST have a closing </change> tag |
| 14 | +- Every <search> tag MUST have a closing </search> tag |
| 15 | +- Every <replace> tag MUST have a closing </replace> tag |
| 16 | +- Every <![CDATA[ MUST have a closing ]]> |
| 17 | +- XML tags should be properly formatted and nested |
| 18 | +- Multiple <change> blocks allowed for different modifications |
| 19 | +
|
| 20 | +CHANGE ORDERING PRIORITY: |
| 21 | +- CRITICAL: Order all <change> blocks by proximity to the cursor marker (<<<AUTOCOMPLETE_HERE>>>) |
| 22 | +- Put changes closest to the cursor marker FIRST in your response |
| 23 | +- This allows immediate display of the most relevant suggestions to the user |
| 24 | +- Changes further from the cursor should come later in the response |
| 25 | +- Measure proximity by line distance from the cursor marker position |
| 26 | +
|
| 27 | +CONTENT MATCHING RULES: |
| 28 | +- Search content must match EXACTLY (including whitespace, indentation, and line breaks) |
| 29 | +- Use CDATA wrappers for all code content |
| 30 | +- Preserve all line breaks and formatting within CDATA sections |
| 31 | +- Never generate overlapping changes |
| 32 | +- The <search> block must contain exact text that exists in the code |
| 33 | +- If you can't find exact match, don't generate that change |
| 34 | +
|
| 35 | +EXAMPLE: |
| 36 | +<change><search><![CDATA[function example() { |
| 37 | + // old code |
| 38 | +}]]></search><replace><![CDATA[function example() { |
| 39 | + // new code |
| 40 | +}]]></replace></change> |
| 41 | +
|
| 42 | +-- |
| 43 | +
|
| 44 | +` |
| 45 | +} |
| 46 | + |
| 47 | +export function addCursorMarker(document: TextDocument, range?: Range): string { |
| 48 | + if (!range) return document.getText() |
| 49 | + |
| 50 | + const fullText = document.getText() |
| 51 | + const cursorOffset = document.offsetAt(range.start) |
| 52 | + const beforeCursor = fullText.substring(0, cursorOffset) |
| 53 | + const afterCursor = fullText.substring(cursorOffset) |
| 54 | + |
| 55 | + return `${beforeCursor}${CURSOR_MARKER}${afterCursor}` |
| 56 | +} |
| 57 | + |
| 58 | +export function formatDocumentWithCursor(document: TextDocument, range?: Range, languageId?: string): string { |
| 59 | + const lang = languageId || document.languageId |
| 60 | + const codeWithCursor = addCursorMarker(document, range) |
| 61 | + |
| 62 | + return `\`\`\`${lang} |
| 63 | +${codeWithCursor} |
| 64 | +\`\`\`` |
| 65 | +} |
5 | 66 |
|
6 | 67 | export class AutoTriggerStrategy { |
7 | 68 | shouldTreatAsComment(prefix: string, languageId: string): boolean { |
|
0 commit comments