follow xml pattern
This commit is contained in:
@@ -45,19 +45,19 @@ export function activate(context: vscode.ExtensionContext) {
|
|||||||
state === vscode.TreeItemCheckboxState.Checked
|
state === vscode.TreeItemCheckboxState.Checked
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update XML edits button text if that setting changed
|
// Update formatting instructions button text if that setting changed
|
||||||
if (item.settingKey === 'xmlEditsEnabled') {
|
if (item.settingKey === 'includeFormattingInstructions') {
|
||||||
xmlEditsButton.text = prompterTreeProvider.isXmlEditsEnabled() ?
|
xmlEditsButton.text = prompterTreeProvider.isXmlEditsEnabled() ?
|
||||||
"$(check) XML Edits" : "$(diff-added) XML Edits";
|
"$(check) Formatting Instructions" : "$(diff-added) Formatting Instructions";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create XML edits toggle button
|
// Create formatting instructions toggle button
|
||||||
const xmlEditsButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
const xmlEditsButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||||
xmlEditsButton.text = "$(diff-added) XML Edits";
|
xmlEditsButton.text = "$(diff-added) Formatting Instructions";
|
||||||
xmlEditsButton.tooltip = "Toggle XML Edits mode";
|
xmlEditsButton.tooltip = "Toggle formatting instructions mode";
|
||||||
xmlEditsButton.command = 'prompter.toggleXmlEdits';
|
xmlEditsButton.command = 'prompter.toggleXmlEdits';
|
||||||
xmlEditsButton.show();
|
xmlEditsButton.show();
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
// Settings interface for the Prompter extension
|
// Settings interface for the Prompter extension
|
||||||
export interface PrompterSettings {
|
export interface PrompterSettings {
|
||||||
xmlEditsEnabled: boolean;
|
includeFormattingInstructions: boolean;
|
||||||
includeLineNumbers: boolean;
|
|
||||||
includeComments: boolean;
|
|
||||||
tokenCalculationEnabled: boolean;
|
tokenCalculationEnabled: boolean;
|
||||||
|
includeFileMap: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default settings values
|
// Default settings values
|
||||||
export const DEFAULT_SETTINGS: PrompterSettings = {
|
export const DEFAULT_SETTINGS: PrompterSettings = {
|
||||||
xmlEditsEnabled: false,
|
includeFormattingInstructions: false,
|
||||||
includeLineNumbers: false,
|
tokenCalculationEnabled: true,
|
||||||
includeComments: true,
|
includeFileMap: true
|
||||||
tokenCalculationEnabled: true
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -129,10 +129,9 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
|
|||||||
// Get settings items for the tree view
|
// Get settings items for the tree view
|
||||||
private getSettingsItems(): SettingTreeItem[] {
|
private getSettingsItems(): SettingTreeItem[] {
|
||||||
return [
|
return [
|
||||||
new SettingTreeItem('XML Edits', 'xmlEditsEnabled', this.settings.xmlEditsEnabled),
|
new SettingTreeItem('Include Formatting Instructions', 'includeFormattingInstructions', this.settings.includeFormattingInstructions),
|
||||||
new SettingTreeItem('Include Line Numbers', 'includeLineNumbers', this.settings.includeLineNumbers),
|
new SettingTreeItem('Token Calculation', 'tokenCalculationEnabled', this.settings.tokenCalculationEnabled),
|
||||||
new SettingTreeItem('Include Comments', 'includeComments', this.settings.includeComments),
|
new SettingTreeItem('Include File Map', 'includeFileMap', this.settings.includeFileMap)
|
||||||
new SettingTreeItem('Token Calculation', 'tokenCalculationEnabled', this.settings.tokenCalculationEnabled)
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,15 +146,15 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
|
|||||||
return this.showingSettings;
|
return this.showingSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle XML edits setting
|
// Toggle formatting instructions setting
|
||||||
toggleXmlEdits(): void {
|
toggleXmlEdits(): void {
|
||||||
this.settings.xmlEditsEnabled = !this.settings.xmlEditsEnabled;
|
this.settings.includeFormattingInstructions = !this.settings.includeFormattingInstructions;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if XML edits are enabled
|
// Check if formatting instructions are enabled
|
||||||
isXmlEditsEnabled(): boolean {
|
isXmlEditsEnabled(): boolean {
|
||||||
return this.settings.xmlEditsEnabled;
|
return this.settings.includeFormattingInstructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all settings
|
// Get all settings
|
||||||
|
|||||||
@@ -31,12 +31,8 @@ export class PromptGenerator {
|
|||||||
fileContents.set(filePath, { content, tokens });
|
fileContents.set(filePath, { content, tokens });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the prompt based on settings
|
// Always generate XML prompt
|
||||||
if (settings.xmlEditsEnabled) {
|
return this.generateXMLPrompt(fileContents, settings);
|
||||||
return this.generateXMLPrompt(fileContents, settings);
|
|
||||||
} else {
|
|
||||||
return this.generatePlainPrompt(fileContents, settings);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,16 +51,7 @@ export class PromptGenerator {
|
|||||||
|
|
||||||
// Add the file to the prompt
|
// Add the file to the prompt
|
||||||
promptText += `File: ${fileName}\n`;
|
promptText += `File: ${fileName}\n`;
|
||||||
|
promptText += `${content}\n`;
|
||||||
// Add line numbers if enabled
|
|
||||||
if (settings.includeLineNumbers) {
|
|
||||||
const lines = content.split('\n');
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
|
||||||
promptText += `${i + 1}: ${lines[i]}\n`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
promptText += `${content}\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
promptText += '\n';
|
promptText += '\n';
|
||||||
}
|
}
|
||||||
@@ -78,58 +65,156 @@ export class PromptGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an XML formatted prompt
|
* Generate an XML formatted prompt following the new schema format
|
||||||
* @param files Map of file paths to content and token counts
|
* @param files Map of file paths to content and token counts
|
||||||
* @param settings Settings to apply
|
* @param settings Settings to apply
|
||||||
* @returns XML formatted prompt
|
* @returns XML formatted prompt
|
||||||
*/
|
*/
|
||||||
private static generateXMLPrompt(files: Map<string, { content: string; tokens: number }>, settings: PrompterSettings): string {
|
private static generateXMLPrompt(files: Map<string, { content: string; tokens: number }>, settings: PrompterSettings): string {
|
||||||
const xmlParts = ['<?xml version="1.0" encoding="UTF-8"?>', '<prompt>'];
|
const xmlParts: string[] = [];
|
||||||
|
|
||||||
// Add files section
|
// Include XML formatting instructions if enabled
|
||||||
xmlParts.push(' <files>');
|
if (settings.includeFormattingInstructions) {
|
||||||
|
try {
|
||||||
|
// Get the workspace root path
|
||||||
|
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || '';
|
||||||
|
const formattingInstructionsPath = path.join(workspaceRoot, '..', 'project_management', 'xml_formatting_instructions.xml');
|
||||||
|
|
||||||
|
if (fs.existsSync(formattingInstructionsPath)) {
|
||||||
|
const instructions = fs.readFileSync(formattingInstructionsPath, 'utf8');
|
||||||
|
xmlParts.push(instructions);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading XML formatting instructions:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate file map section if enabled in settings
|
||||||
|
if (settings.includeFileMap) {
|
||||||
|
xmlParts.push('<file_map>');
|
||||||
|
|
||||||
|
// Get the workspace root path
|
||||||
|
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || '';
|
||||||
|
xmlParts.push(workspaceRoot);
|
||||||
|
|
||||||
|
// Create a tree representation of the files
|
||||||
|
const fileTree = this.generateFileTree(files, workspaceRoot);
|
||||||
|
xmlParts.push(fileTree);
|
||||||
|
xmlParts.push('</file_map>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate file contents section
|
||||||
|
xmlParts.push('<file_contents>');
|
||||||
|
|
||||||
|
// Add each file with its content
|
||||||
for (const [filePath, { content, tokens }] of files) {
|
for (const [filePath, { content, tokens }] of files) {
|
||||||
const extension = path.extname(filePath);
|
const extension = path.extname(filePath);
|
||||||
let language = extension.substring(1); // Remove the dot
|
let language = extension.substring(1); // Remove the dot
|
||||||
|
|
||||||
// Handle special cases
|
// Handle special cases for language detection
|
||||||
if (extension === '.js' || extension === '.jsx') {
|
if (extension === '.js' || extension === '.jsx') {
|
||||||
language = 'javascript';
|
language = 'javascript';
|
||||||
} else if (extension === '.ts' || extension === '.tsx') {
|
} else if (extension === '.ts' || extension === '.tsx') {
|
||||||
language = 'typescript';
|
language = 'typescript';
|
||||||
|
} else if (extension === '.md') {
|
||||||
|
language = 'md';
|
||||||
|
} else if (extension === '.py') {
|
||||||
|
language = 'python';
|
||||||
|
} else if (extension === '.html') {
|
||||||
|
language = 'html';
|
||||||
|
} else if (extension === '.css') {
|
||||||
|
language = 'css';
|
||||||
|
} else if (extension === '.json') {
|
||||||
|
language = 'json';
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlParts.push(' <file>');
|
// Use content as is
|
||||||
xmlParts.push(` <path>${path.basename(filePath)}</path>`);
|
const formattedContent = content;
|
||||||
xmlParts.push(` <type>${language}</type>`);
|
|
||||||
xmlParts.push(` <tokens>${tokens}</tokens>`);
|
|
||||||
|
|
||||||
// Format content based on settings
|
// Get the workspace root path if not already defined
|
||||||
let formattedContent = content;
|
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri?.fsPath || '';
|
||||||
if (settings.includeLineNumbers) {
|
|
||||||
const lines = content.split('\n');
|
|
||||||
formattedContent = lines.map((line, i) => `${i + 1}: ${line}`).join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlParts.push(` <content><![CDATA[${formattedContent}]]></content>`);
|
// Add file entry
|
||||||
xmlParts.push(' </file>');
|
xmlParts.push(`File: ${this.getRelativePath(filePath, workspaceRoot)}`);
|
||||||
|
xmlParts.push(`\`\`\`${language}`);
|
||||||
|
xmlParts.push(formattedContent);
|
||||||
|
xmlParts.push('\`\`\`');
|
||||||
}
|
}
|
||||||
xmlParts.push(' </files>');
|
|
||||||
|
|
||||||
// Add options based on settings
|
xmlParts.push('</file_contents>');
|
||||||
xmlParts.push(' <options>');
|
|
||||||
if (settings.includeLineNumbers) {
|
// Calculate tokens for toast notification but don't include in XML
|
||||||
xmlParts.push(' <include_line_numbers>true</include_line_numbers>');
|
|
||||||
}
|
|
||||||
if (!settings.includeComments) {
|
|
||||||
xmlParts.push(' <exclude_comments>true</exclude_comments>');
|
|
||||||
}
|
|
||||||
if (settings.tokenCalculationEnabled) {
|
if (settings.tokenCalculationEnabled) {
|
||||||
xmlParts.push(` <total_tokens>${Array.from(files.values()).reduce((sum, { tokens }) => sum + tokens, 0)}</total_tokens>`);
|
const totalTokens = Array.from(files.values()).reduce((sum, { tokens }) => sum + tokens, 0);
|
||||||
|
// We'll show this in a toast notification but not include it in the XML
|
||||||
|
vscode.window.showInformationMessage(`Total tokens: ${totalTokens}`);
|
||||||
}
|
}
|
||||||
xmlParts.push(' </options>');
|
|
||||||
|
|
||||||
xmlParts.push('</prompt>');
|
|
||||||
return xmlParts.join('\n');
|
return xmlParts.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a tree representation of files
|
||||||
|
* @param files Map of file paths
|
||||||
|
* @param rootPath The workspace root path
|
||||||
|
* @returns String representation of the file tree
|
||||||
|
*/
|
||||||
|
private static generateFileTree(files: Map<string, any>, rootPath: string): string {
|
||||||
|
// Create a simple tree representation
|
||||||
|
const treeLines: string[] = [];
|
||||||
|
|
||||||
|
// Group files by directory
|
||||||
|
const dirMap = new Map<string, string[]>();
|
||||||
|
|
||||||
|
for (const filePath of files.keys()) {
|
||||||
|
const relativePath = this.getRelativePath(filePath, rootPath);
|
||||||
|
const dir = path.dirname(relativePath);
|
||||||
|
|
||||||
|
if (!dirMap.has(dir)) {
|
||||||
|
dirMap.set(dir, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
dirMap.get(dir)?.push(path.basename(filePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort directories
|
||||||
|
const sortedDirs = Array.from(dirMap.keys()).sort();
|
||||||
|
|
||||||
|
// Build the tree
|
||||||
|
for (let i = 0; i < sortedDirs.length; i++) {
|
||||||
|
const dir = sortedDirs[i];
|
||||||
|
const isLast = i === sortedDirs.length - 1;
|
||||||
|
const prefix = isLast ? '└── ' : '├── ';
|
||||||
|
|
||||||
|
// Skip root directory
|
||||||
|
if (dir !== '.') {
|
||||||
|
treeLines.push(`${prefix}${dir}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add files
|
||||||
|
const files = dirMap.get(dir)?.sort() || [];
|
||||||
|
for (let j = 0; j < files.length; j++) {
|
||||||
|
const file = files[j];
|
||||||
|
const isLastFile = j === files.length - 1;
|
||||||
|
const filePrefix = dir === '.' ? (isLastFile ? '└── ' : '├── ') : ' ' + (isLastFile ? '└── ' : '├── ');
|
||||||
|
treeLines.push(`${filePrefix}${file}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return treeLines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the path relative to the workspace root
|
||||||
|
* @param filePath Absolute file path
|
||||||
|
* @param rootPath Workspace root path
|
||||||
|
* @returns Relative path
|
||||||
|
*/
|
||||||
|
private static getRelativePath(filePath: string, rootPath: string): string {
|
||||||
|
if (filePath.startsWith(rootPath)) {
|
||||||
|
const relativePath = filePath.substring(rootPath.length);
|
||||||
|
return relativePath.startsWith('/') ? relativePath.substring(1) : relativePath;
|
||||||
|
}
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user