Skip to content

Commit

Permalink
Replace khoj-edit code blocks with XML tags for more reliable parsing
Browse files Browse the repository at this point in the history
- Update chat_view.ts to use <khoj-edit> XML tags instead of code blocks when copying/pasting edit content
- Modify interact_with_files.ts to use XML-based edit block parsing and transformation
- Update edit instructions and examples to reflect the new XML format
- Improve parsing reliability and consistency for edit block handling
  • Loading branch information
hjamet committed Mar 3, 2025
1 parent 4e1ebd8 commit fbc3f63
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/interface/obsidian/src/chat_view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ export class KhojChatView extends KhojPaneView {
let markdownMessage = message;
const khojEditRegex = /<details class="khoj-edit-accordion">[\s\S]*?<pre><code class="language-khoj-edit">([\s\S]*?)<\/code><\/pre>[\s\S]*?<\/details>/g;
markdownMessage = markdownMessage.replace(khojEditRegex, (_, content) => {
return `\`\`\`khoj-edit\n${content}\`\`\``;
return `<khoj-edit>\n${content}\n</khoj-edit>`;
});
navigator.clipboard.writeText(markdownMessage).then(() => {
setIcon(copyButton, "check");
Expand All @@ -863,7 +863,7 @@ export class KhojChatView extends KhojPaneView {
let markdownMessage = message;
const khojEditRegex = /<details class="khoj-edit-accordion">[\s\S]*?<pre><code class="language-khoj-edit">([\s\S]*?)<\/code><\/pre>[\s\S]*?<\/details>/g;
markdownMessage = markdownMessage.replace(khojEditRegex, (_, content) => {
return `\`\`\`khoj-edit\n${content}\`\`\``;
return `<khoj-edit>\n${content}\n</khoj-edit>`;
});
pasteTextAtCursor(markdownMessage);
});
Expand Down
39 changes: 21 additions & 18 deletions src/interface/obsidian/src/interact_with_files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class FileInteractions {
if (fileAccessMode === 'write') {
openFilesContent += `[EDIT INSTRUCTIONS] I can help you edit your notes using targeted modifications. I'll use multiple edit blocks to make precise changes rather than rewriting entire sections.
\`\`\`khoj-edit
<khoj-edit>
{
"note": "Brief one-line explanation of what this edit does",
"location": {
Expand All @@ -76,12 +76,13 @@ export class FileInteractions {
"content": "<complete new content, including end marker if you want to keep it>",
"file": "target-filename" // Required: specify which open file to edit (without .md extension)
}
\`\`\`
</khoj-edit>
⚠️ Important:
- The end marker text is included in the edited section and will be deleted. If you want to keep it, make sure to include it in your "content"
- The "file" parameter is required and must match an open file name (without .md extension)
- Use \" for quotes and \`\`\` for backticks in your content to ensure proper parsing
- Use \" for quotes in your content to ensure proper parsing
- The XML format <khoj-edit>...</khoj-edit> ensures more reliable parsing compared to code blocks
📝 Example note:
Expand All @@ -106,7 +107,7 @@ Next steps:
Examples of targeted edits:
1. Using just a few words to identify long text (notice how "campaign launch" is kept in content):
\`\`\`khoj-edit
<khoj-edit>
{
"note": "Add deadline and specificity to the marketing team follow-up",
"location": {
Expand All @@ -116,10 +117,10 @@ Examples of targeted edits:
"content": "- Schedule follow-up with marketing team by Wednesday to discuss Q1 campaign launch",
"file": "Meeting Notes"
}
\`\`\`
</khoj-edit>
2. Multiple targeted changes with escaped characters:
\`\`\`khoj-edit
<khoj-edit>
{
"note": "Add HIGH priority flag with code reference to Q4 metrics review",
"location": {
Expand All @@ -129,8 +130,8 @@ Examples of targeted edits:
"content": "- [HIGH] Review Q4 metrics (see \"metrics.ts\" and \`calculateQ4Metrics()\`)",
"file": "Meeting Notes"
}
\`\`\`
\`\`\`khoj-edit
</khoj-edit>
<khoj-edit>
{
"note": "Add resource allocation to project timeline task",
"location": {
Expand All @@ -140,10 +141,10 @@ Examples of targeted edits:
"content": "- Update project timeline and add resource allocation for Q1 2024",
"file": "Meeting Notes"
}
\`\`\`
</khoj-edit>
3. Adding new content between sections:
\`\`\`khoj-edit
<khoj-edit>
{
"note": "Insert Discussion Points section between Action Items and Next Steps",
"location": {
Expand All @@ -153,10 +154,10 @@ Examples of targeted edits:
"content": "Action items from today:\\n- Review Q4 metrics\\n- Schedule follow-up\\n- Update timeline\\n\\nDiscussion Points:\\n- Budget review\\n- Team feedback\\n\\nNext steps:",
"file": "Meeting Notes"
}
\`\`\`
</khoj-edit>
4. Completely replacing a file content (preserving frontmatter):
\`\`\`khoj-edit
<khoj-edit>
{
"note": "Replace entire file content while keeping frontmatter metadata",
"location": {
Expand All @@ -166,7 +167,7 @@ Examples of targeted edits:
"content": "# Project Overview\\n\\n## Goals\\n- Increase user engagement by 25%\\n- Launch mobile app by Q3\\n- Expand to 3 new markets\\n\\n## Timeline\\n1. Q1: Research & Planning\\n2. Q2: Development\\n3. Q3: Testing & Launch\\n4. Q4: Market Expansion",
"file": "Meeting Notes"
}
\`\`\`
</khoj-edit>
💡 Key points:
- note: Brief one-line explanation of what the edit does
Expand All @@ -178,7 +179,8 @@ Examples of targeted edits:
- Changes apply to first matching location in the specified file
- Use <file-start> and <file-end> markers to replace entire file content while preserving frontmatter
- Frontmatter metadata (between --- markers at top of file) cannot be modified
- Remember to escape special characters: use \" for quotes and \`\`\` for backticks in content
- Remember to escape special characters: use \" for quotes in content
- Always use the XML format <khoj-edit>...</khoj-edit> instead of code blocks
[END OF EDIT INSTRUCTIONS]\n\n`;
}
Expand Down Expand Up @@ -381,12 +383,13 @@ Examples of targeted edits:
/**
* Parses all edit blocks from a message
*
* @param message - The message containing khoj-edit blocks
* @param message - The message containing khoj-edit blocks in XML format
* @returns Array of EditBlock objects
*/
public parseEditBlocks(message: string): EditBlock[] {
const editBlocks: EditBlock[] = [];
const editBlockRegex = /```khoj-edit\s*([\s\S]*?)```/g;
// Updated regex to match XML format <khoj-edit>...</khoj-edit>
const editBlockRegex = /<khoj-edit>([\s\S]*?)<\/khoj-edit>/g;
let hasError = false;

let match;
Expand Down Expand Up @@ -635,7 +638,7 @@ Examples of targeted edits:
/**
* Transforms khoj-edit blocks in a message to HTML for display
*
* @param message - The message containing khoj-edit blocks
* @param message - The message containing khoj-edit blocks in XML format
* @returns The transformed message with HTML for edit blocks
*/
public transformKhojEditBlocks(message: string): string {
Expand All @@ -644,7 +647,7 @@ Examples of targeted edits:
.map(leaf => (leaf.view as any)?.file)
.filter(file => file && file.extension === 'md');

return message.replace(/```khoj-edit\s*([\s\S]*?)```/g, (match, content) => {
return message.replace(/<khoj-edit>([\s\S]*?)<\/khoj-edit>/g, (match, content) => {
const { editData, cleanContent, error } = this.parseKhojEditBlock(content);

// Escape content for HTML display
Expand Down

0 comments on commit fbc3f63

Please sign in to comment.