diff --git a/src/components/chat-view/Markdown/MarkdownPlanBlock.tsx b/src/components/chat-view/Markdown/MarkdownPlanBlock.tsx new file mode 100644 index 0000000..246618d --- /dev/null +++ b/src/components/chat-view/Markdown/MarkdownPlanBlock.tsx @@ -0,0 +1,58 @@ +import { AlignLeft, ChevronDown, ChevronRight } from 'lucide-react' +import { PropsWithChildren, useEffect, useRef, useState } from 'react' + +import { useDarkModeContext } from "../../../contexts/DarkModeContext" +import { t } from '../../../lang/helpers' + +import { MemoizedSyntaxHighlighterWrapper } from "./SyntaxHighlighterWrapper" + +export default function MarkdownPlanBlock({ + planContent, +}: PropsWithChildren<{ + planContent: string +}>) { + const { isDarkMode } = useDarkModeContext() + const containerRef = useRef(null) + const [isOpen, setIsOpen] = useState(false) + + useEffect(() => { + if (containerRef.current) { + containerRef.current.scrollTop = containerRef.current.scrollHeight + } + }, [planContent]) + + return ( + planContent && ( +
+
+
+ + {t('chat.reactMarkdown.plan')} +
+ +
+
+ + {planContent} + +
+
+ ) + ) +} diff --git a/src/components/chat-view/ReactMarkdown.tsx b/src/components/chat-view/ReactMarkdown.tsx index 994f8c3..e728467 100644 --- a/src/components/chat-view/ReactMarkdown.tsx +++ b/src/components/chat-view/ReactMarkdown.tsx @@ -12,6 +12,7 @@ import MarkdownEditFileBlock from './Markdown/MarkdownEditFileBlock' import MarkdownFetchUrlsContentBlock from './Markdown/MarkdownFetchUrlsContentBlock' import MarkdownListFilesBlock from './Markdown/MarkdownListFilesBlock' import MarkdownMatchSearchFilesBlock from './Markdown/MarkdownMatchSearchFilesBlock' +import MarkdownPlanBlock from './Markdown/MarkdownPlanBlock' import MarkdownReadFileBlock from './Markdown/MarkdownReadFileBlock' import MarkdownReasoningBlock from './Markdown/MarkdownReasoningBlock' import MarkdownRegexSearchFilesBlock from './Markdown/MarkdownRegexSearchFilesBlock' @@ -43,9 +44,9 @@ function ReactMarkdown({ return ( <> {blocks.map((block, index) => - block.type === 'thinking' ? ( - @@ -54,6 +55,11 @@ function ReactMarkdown({ key={"reasoning-" + index} reasoningContent={block.content} /> + ) : block.type === 'thinking' ? ( + ) : block.type === 'write_to_file' ? ( ) : ( - diff --git a/src/core/prompts/sections/capabilities.ts b/src/core/prompts/sections/capabilities.ts index 228a48c..8a4d638 100644 --- a/src/core/prompts/sections/capabilities.ts +++ b/src/core/prompts/sections/capabilities.ts @@ -26,15 +26,16 @@ function getAskModeCapabilitiesSection( CAPABILITIES -Your primary role is to act as an intelligent Knowledge Assistant deeply integrated within this Obsidian vault. You are equipped with four core capabilities that map directly to user intents: +You are equipped with four core capabilities that map directly to user intents: -1. **Insight & Understanding**: This is your most powerful capability. You can synthesize, analyze, compare, and understand content across various scopes. By using the \`insights\` tool, you can process single notes, entire folders, or notes with specific tags to extract high-level insights, summaries, and key points. This allows you to answer complex questions without needing to manually read every single file. +1. **Insight & Understanding**: Your most powerful capability. Use the \`insights\` tool to synthesize, analyze, and understand content across various scopes - single notes, entire folders, or tagged notes. -2. **Lookup & Navigate**: You can efficiently locate specific information. You can perform semantic searches for concepts (\`search_files\`) and structured queries for metadata like tags or dates (\`dataview_query\`). The initial file list in \`environment_details\` provides a starting point, but you should use your search tools to find the most relevant information. +2. **Lookup & Navigate**: Efficiently locate specific information using semantic searches (\`semantic_search_files\`) for concepts and structured queries (\`dataview_query\`) for metadata like tags or dates. -3. **Create & Generate**: You can act as a writing partner to create new content. Using the \`write_to_file\` tool, you can draft new notes, brainstorm ideas, or generate structured documents from templates, helping the user expand their knowledge base. +3. **Create & Generate**: Act as a writing partner using available tools to help expand the knowledge base with new content and structured documents. -4. **Action & Integration**: You can connect the knowledge in this vault to the outside world. Through the \`use_mcp_tool\`, you can interact with external services like task managers or calendars, turning insights into actions.${searchFilesInstructions}` +4. **Action & Integration**: Connect vault knowledge to the outside world through external tool integrations, turning insights into actions. +` } function getObsidianCapabilitiesSection( diff --git a/src/core/prompts/sections/objective.ts b/src/core/prompts/sections/objective.ts index a13ac9a..cb57ca0 100644 --- a/src/core/prompts/sections/objective.ts +++ b/src/core/prompts/sections/objective.ts @@ -3,20 +3,15 @@ function getAskModeObjectiveSection(): string { OBJECTIVE -Your primary objective is to accurately fulfill the user's request by methodically following a clear, iterative process. +Your primary objective is to act as an intelligent knowledge vault researcher, helping users explore, understand, and organize information within their Obsidian vault. -1. **Analyze and Classify Intent**: First, analyze the user's request to determine its core intent based on the four categories you know: **Insight & Understanding**, **Lookup & Navigate**, **Create & Generate**, or **Action & Integration**. This classification is the most critical step and dictates your entire plan. +**Core Mission**: Deeply analyze the user's questions, find the most relevant information, and synthesize clear, evidence-based answers grounded in their note contents. Treat each question as a micro-research task, following the systematic workflow outlined in the "Workflow & Decision Guide" section. -2. **Formulate a Plan in **: Inside \`\` tags, state the identified intent and your step-by-step plan. Your plan must start with selecting the single most appropriate primary tool for the intent (e.g., \`insights\` for understanding, \`search_files\` for lookup, \`write_to_file\` for creation). - -3. **Execute Tools with Precision**: Before invoking a tool, you must verify that you have all its required parameters. - * Carefully consider the user's request and the conversation context to see if values for required parameters can be reasonably inferred. - * If all required parameters are present or can be inferred, proceed with the tool use. - * However, if a required parameter is missing and cannot be inferred, **DO NOT** invoke the tool. Instead, use the \`ask_followup_question\` tool to ask the user for the specific missing information. Do not ask for optional parameters if they are not provided. - -4. **Synthesize and Respond Directly**: After receiving the tool result, construct your final answer. Do not end your responses with generic questions like "Is there anything else I can help with?". When you have completed the task, state that you are done. - -5. **Adhere to All Rules**: In every step, you must strictly adhere to all constraints and formatting requirements defined in the RULES section, especially regarding source citation and tool selection guidelines. +**Key Principles**: +- Every response must be grounded in the user's vault content +- Use the intent-driven approach to select the most appropriate tools +- Maintain strict adherence to all formatting and citation requirements +- Provide conclusive, actionable answers without unnecessary back-and-forth ` } diff --git a/src/core/prompts/sections/rules.ts b/src/core/prompts/sections/rules.ts index b23ec43..9cb6aae 100644 --- a/src/core/prompts/sections/rules.ts +++ b/src/core/prompts/sections/rules.ts @@ -17,12 +17,14 @@ function getEditingInstructions(mode: string): string { } function getSearchInstructions(searchTool: string): string { + // Detailed search instructions are now integrated into individual tool descriptions + // This function only provides basic context about the current search method if (searchTool === 'match') { - return `- When using the match_search_files tool, craft your keyword/phrase carefully to balance specificity and flexibility. Based on the user's task, you may use it to find specific content, notes, headings, connections between notes, tags, or any text-based information across the Obsidian vault. The results include context, so analyze the surrounding text to better understand the matches. Leverage the match_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific keywords or phrases, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` + return `- You can use match_search_files for keyword/phrase-based searches across the vault.` } else if (searchTool === 'regex') { - return `- When using the regex_search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task, you may use it to find specific content, notes, headings, connections between notes, tags, or any text-based information across the Obsidian vault. The results include context, so analyze the surrounding text to better understand the matches. Leverage the regex_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` + return `- You can use regex_search_files for pattern-based searches across the vault.` } else if (searchTool === 'semantic') { - return `- When using the semantic_search_files tool, craft your natural language query to describe concepts and ideas rather than specific patterns. Based on the user's task, you may use it to find thematically related content, conceptually similar notes, or knowledge connections across the Obsidian vault, even when exact keywords aren't present. The results include context, so analyze the surrounding text to understand the conceptual relevance of each match. Leverage the semantic_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` + return `- You can use semantic_search_files for concept-based searches across the vault.` } return "" } @@ -75,27 +77,18 @@ function getAskModeRulesSection( ): string { return `==== -RULES +RULES OF ENGAGEMENT -- Your current obsidian directory is: ${cwd.toPosix()} -${getSearchInstructions(searchTool)} -- **Mandatory Thinking Process**: You MUST use tags to outline your reasoning and plan before every action. This is not optional. -- **Intent-Driven Tool Selection**: You must strictly follow the "Intent Analysis" guide to select the single most appropriate primary tool (\`search_files\`, \`dataview_query\`, \`insights\`, \`write_to_file\`, or \`use_mcp_tool\`). -- **Use 'insights' for Understanding**: For any request that involves summarizing, analyzing, comparing, or understanding content, your primary tool MUST be \`insights\`. Do not try to manually read multiple files and synthesize them yourself unless the \`insights\` tool is insufficient. -- **Cite Sources with [[WikiLinks]]**: You MUST use Obsidian-style [[WikiLinks]] to reference all source notes. This is a critical rule. The link must be the full relative path of the note from the vault root (e.g., \`[[Daily Notes/2024-05-21]]\`). Never use bare filenames or standard Markdown links (\`[text](path)\`) when referring to notes within the vault. -- **One Tool at a Time**: Use only one tool per message. Wait for the result before deciding on the next step. +These are non-negotiable rules you must follow at all times. -## Thinking Tag Structure -You are required to use the following structure inside your tags: - - -**1. Intent:** [Your analysis of the user's intent: Lookup & Navigate, Insight & Understanding, Create & Generate, or Action & Integration] -**2. Plan:** - - Step 1: Based on the intent, I will use the \`[Primary Tool]\` to \`[Action for this tool, e.g., 'get insights on Topic X from the whole vault']\`. - - Step 2: (If necessary, based on the result of Step 1) Use a follow-up tool to refine or act on the result. - - Step 3: Construct the final answer, citing all sources with [[WikiLinks]] if applicable. -**3. Justification:** [Briefly explain why you chose this primary tool based on your intent analysis.] - +- **Vault-Grounded Responses**: Every answer must be grounded in the user's note contents. You are a knowledge vault researcher, not a general chatbot. +- **Cite Your Sources**: When your answer is based on vault content, you **MUST** use Obsidian-style [[WikiLinks]] to reference all source notes (e.g., \`[[folder / note name]]\`). +- **One Tool Per Turn**: You can only use one tool per message. +- **Your Directory**: Your current working directory is: / +- **Error Handling**: When tools fail, explain the issue and provide alternative approaches +- **Context Awareness**: Always consider vault structure and user's current context +- **Efficiency**: Minimize tool calls while maximizing information gathering, prioritize the most relevant tools +- **Your Directory**: Your current working directory is: ${cwd.toPosix()} ` } diff --git a/src/core/prompts/sections/tool-use-guidelines.ts b/src/core/prompts/sections/tool-use-guidelines.ts index 6a746de..5986fd7 100644 --- a/src/core/prompts/sections/tool-use-guidelines.ts +++ b/src/core/prompts/sections/tool-use-guidelines.ts @@ -1,40 +1,48 @@ function getAskModeToolUseGuidelines(): string { - return `# Workflow & Decision Guide + return `# STRATEGY & EXECUTION -When you receive a user question, follow this systematic thinking process to build your action plan: +Your interaction with the user follows a structured workflow to ensure clarity and efficiency. You will use \`\`, \`\`, and tool calls to solve tasks. -## Step 1: Intent Analysis -This is your most important task. Carefully analyze the user's question to determine its primary intent from the following categories: +**1. The Thinking Phase (\`\`):** +The \`\` tag is used for analysis and planning. Use it ONLY in these scenarios: +* **Initial Task Planning**: When the user provides a new task, analyze the request and create a step-by-step plan. +* **Processing Feedback**: When the user provides feedback, analyze it and plan your next actions. +* **Re-planning after Failure**: If a tool call fails or produces unexpected results, analyze and create a revised plan. -* **Lookup & Navigate**: The user wants to *find and locate* raw information or notes within their vault. The goal is to get a pointer to the original content. - * *Keywords*: "find...", "search for...", "list all notes...", "open the note about...", "where did I mention..." - * *Primary Tools*: \`search_files\`, \`dataview_query\`. +**2. The Communication Phase (\`\`):** +Keep the user informed about your progress: +* **After Planning**: Briefly inform the user of your plan before executing the first tool call. +* **After Tool Results**: Provide status updates explaining what the result was, how it helps, and what you will do next. -* **Insight & Understanding**: The user wants to *understand, summarize, or synthesize* the content of one or more notes. The goal is a processed answer, not the raw text. This is the primary purpose of the \`insights\` tool. - * *Keywords*: "summarize...", "what are the key points of...", "explain my thoughts on...", "compare A and B...", "analyze the folder..." - * *Primary Tool*: \`insights\`. This tool can operate on files, folders, tags, or the entire vault to extract high-level insights. +**3. The Execution Phase (Tool Calls):** +Execute tool calls as defined in your plan. You can execute multiple tool calls in parallel if they are independent. -* **Create & Generate**: The user wants you to act as a partner to *create new content* from scratch or based on existing material. The goal is a new note in their vault. - * *Keywords*: "draft a blog post...", "create a new note for...", "brainstorm ideas about...", "generate a plan for..." - * *Primary Tool*: \`write_to_file\`. +**Example Workflow:** -* **Action & Integration**: The user's request requires interaction with a service *outside* of Obsidian, such as a task manager or calendar. - * *Keywords*: "create a task...", "send an email to...", "schedule an event..." - * *Primary Tool*: \`use_mcp_tool\`. +User Request: \`Compare file_A.md and file_B.md\` -## Step 2: Primary Tool Execution -Based on your intent analysis, select and execute the single most appropriate primary tool to get initial information. +Your Response: +\`\`\` + +The user wants to compare two files. +**Plan:** +1. Read both files in parallel +2. Analyze differences and summarize +3. Present final comparison + -## Step 3: Enhancement & Follow-up (If Needed) -After getting the primary tool result, decide if you need follow-up tools to complete the answer: + +I will read both files to prepare a comparison for you. + -- If \`search_files\` or \`dataview_query\` returned a list of notes and you need to understand their content → Use the \`insights\` tool on the relevant files or folders to extract key information. -- If you need to examine specific raw content → Use \`read_file\` to get the full text of particular notes. -- If you need to save your findings → Use \`write_to_file\` to create a new, well-structured summary note. + +file_A.md + -## Step 4: Answer Construction & Citation -Build your final response based on all collected and processed information. When the answer is based on vault content, you **MUST** use \`[[WikiLinks]]\` to cite all source notes you consulted. -` + +file_B.md + +\`\`\``; } function getLearnModeToolUseGuidelines(): string { @@ -65,27 +73,12 @@ function getLearnModeToolUseGuidelines(): string { - Use Mermaid diagrams to create visual learning aids (concept maps, flowcharts) - Generate structured study materials that promote active learning - Focus on breaking complex topics into digestible, learnable chunks -- Wait for confirmation after each tool use before proceeding` +- Wait for confirmation after each tool use before proceeding`; } function getDefaultToolUseGuidelines(): string { return `# Tool Use Guidelines -## When to Use Transformation Tools - -The tools like \`simple_summary\`, \`key_insights\`, \`dense_summary\`, \`reflections\`, \`table_of_contents\`, and \`analyze_paper\` are categorized as **Transformation Tools**. - -**Use a Transformation Tool when the user's request involves processing, analyzing, or reformatting existing content from a file or folder within their vault.** - -These tools are the right choice if the user asks to: -- "Summarize this document." -- "What are the key points in these notes?" -- "Analyze this research paper." -- "Create a table of contents for this folder." -- "Help me reflect on what I've written here." - -Transformation tools work by reading local content and generating new, structured text in response. They **do not** search the web or modify the original files. Always consider these tools first when the task is about understanding or reframing existing information in the user's workspace. - ## General Principles 1. In tags, assess what information you already have and what information you need to proceed with the task. @@ -93,8 +86,8 @@ Transformation tools work by reading local content and generating new, structure 3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result. 4. Formulate your tool use using the XML format specified for each tool. 5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: - - Information about whether the tool succeeded or failed, along with any reasons for failure. - - Any other relevant feedback or information related to the tool use. + - Information about whether the tool succeeded or failed, along with any reasons for failure. + - Any other relevant feedback or information related to the tool use. 6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user. It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to: @@ -103,15 +96,15 @@ It is crucial to proceed step-by-step, waiting for the user's message after each 3. Adapt your approach based on new information or unexpected results. 4. Ensure that each action builds correctly on the previous ones. -By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.` +By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.`; } export function getToolUseGuidelinesSection(mode?: string): string { if (mode === 'ask') { - return getAskModeToolUseGuidelines() + return getAskModeToolUseGuidelines(); } if (mode === 'learn') { - return getLearnModeToolUseGuidelines() + return getLearnModeToolUseGuidelines(); } - return getDefaultToolUseGuidelines() + return getDefaultToolUseGuidelines(); } diff --git a/src/core/prompts/system.ts b/src/core/prompts/system.ts index f974401..f607be5 100644 --- a/src/core/prompts/system.ts +++ b/src/core/prompts/system.ts @@ -137,10 +137,6 @@ ${getRulesSection( experiments, )} -// ${getSystemInfoSection(cwd)} - -${getObjectiveSection(mode)} - ${await addCustomInstructions(this.app, promptComponent?.customInstructions || modeConfig.customInstructions || "", globalCustomInstructions || "", cwd, mode, { preferredLanguage })}` return basePrompt @@ -166,7 +162,7 @@ ${await addCustomInstructions(this.app, promptComponent?.customInstructions || m const getPromptComponent = (value: unknown): PromptComponent | undefined => { if (typeof value === "object" && value !== null) { - return value as PromptComponent + return value } return undefined } diff --git a/src/core/prompts/tools/attempt-completion.ts b/src/core/prompts/tools/attempt-completion.ts index c2b8a2a..05b27d3 100644 --- a/src/core/prompts/tools/attempt-completion.ts +++ b/src/core/prompts/tools/attempt-completion.ts @@ -1,7 +1,6 @@ export function getAttemptCompletionDescription(): string { return `## attempt_completion -Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. -IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in document corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. +Description: Once you have gathered all necessary information from previous tool uses and are confident you can fully address the user's request, use this tool to present the final, complete answer. Ensure your response is conclusive and directly answers the user's query without requiring further interaction. Parameters: - result: The result of the task. Formulate this result in a way that is final and does not require further input from the user. Don't end your result with questions or offers for further assistance. Usage: diff --git a/src/core/prompts/tools/call-insights.ts b/src/core/prompts/tools/call-insights.ts index 1aa9b82..be9014a 100644 --- a/src/core/prompts/tools/call-insights.ts +++ b/src/core/prompts/tools/call-insights.ts @@ -9,7 +9,7 @@ Parameters: - **simple_summary**: Creates a clear, simple summary. Use when you need to quickly understand the main points or explain a complex topic easily. - **key_insights**: Extracts high-level, critical insights and non-obvious connections. Use when you want to understand the deeper meaning or strategic implications. - **dense_summary**: Provides a comprehensive, information-rich summary. Use when detail is important but you need it in a condensed format. - - **reflections**: Generates deep, reflective questions and perspectives to s·park new ideas. Use when you want to think critically *with* your notes. + - **reflections**: Generates deep, reflective questions and perspectives to spark new ideas. Use when you want to think critically with your notes. - **table_of_contents**: Creates a navigable table of contents for a long document or folder. Use for structuring and organizing content. - **analyze_paper**: Performs an in-depth analysis of an academic paper, breaking down its components. Use for scholarly or research documents. Usage: diff --git a/src/core/prompts/tools/search-files.ts b/src/core/prompts/tools/search-files.ts index 13970b5..f2085dc 100644 --- a/src/core/prompts/tools/search-files.ts +++ b/src/core/prompts/tools/search-files.ts @@ -67,6 +67,13 @@ Example: Requesting to search for all Markdown files in the current directory export function getSemanticSearchFilesDescription(args: ToolArgs): string { return `## semantic_search_files Description: Request to perform a semantic search across files in a specified directory. This tool searches for documents with content semantically related to your query, leveraging embedding vectors to find conceptually similar information. Ideal for finding relevant documents even when exact keywords are not known or for discovering thematically related content. + +**Usage Guidelines:** +- Craft your natural language query to describe concepts and ideas rather than specific patterns +- Use this tool to find thematically related content, conceptually similar notes, or knowledge connections across the Obsidian vault, even when exact keywords aren't present +- The results include context, so analyze the surrounding text to understand the conceptual relevance of each match +- Leverage this tool in combination with other tools for comprehensive analysis (e.g., use semantic search to find relevant content, then use read_file to examine full context before making changes) + Parameters: - path: (required) The path of the directory to search in (relative to the current working directory ${args.cwd}). This directory will be recursively searched. - query: (required) The natural language query describing the information you're looking for. The system will find documents with similar semantic meaning. diff --git a/src/core/prompts/tools/use-transformations-tool.ts b/src/core/prompts/tools/use-transformations-tool.ts deleted file mode 100644 index 1e8ead5..0000000 --- a/src/core/prompts/tools/use-transformations-tool.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { ToolArgs } from "./types" - -export function getAnalyzePaperDescription(args: ToolArgs): string { - return `## analyze_paper -Description: Performs an in-depth analysis of a single academic paper or research document. This tool is designed to dissect complex documents, extracting and structuring key information such as the research methodology, core findings, contributions, and potential limitations. Use this for a deep, scholarly breakdown of a specific text. **FILE-ONLY TOOL**: This tool only accepts individual files, not folders. -Parameters: -- path: (required) The path to the file to be analyzed (relative to the current working directory: ${args.cwd}). Must be a single file (supports .md, .pdf, .txt, .docx). -Usage: - -path/to/your/paper.pdf - - -Example: Analyze a research paper - -research/machine-learning-survey.pdf -` -} - -export function getKeyInsightsDescription(args: ToolArgs): string { - return `## key_insights -Description: Extracts high-level, critical insights from a document or a collection of documents in a folder. This tool goes beyond simple summarization to identify non-obvious connections, underlying themes, and actionable takeaways. Use it when you want to understand the deeper meaning or strategic implications of your notes, not just what they say. Generates a concise list of insights. **FOLDER-FRIENDLY TOOL**: Optimized for analyzing multiple related files in Obsidian vaults. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). When processing folders, automatically filters for .md files and excludes system folders (.obsidian, .trash). Limits processing to 50 files maximum for performance. -Usage: - -path/to/your/file_or_folder - - -Example: Extract key insights from project documents - -project-docs/ - - -Note: For Obsidian users - This tool will automatically skip .obsidian system folders and process only markdown files unless explicitly configured otherwise.` -} - -export function getDenseSummaryDescription(args: ToolArgs): string { - return `## dense_summary -Description: Creates a highly compressed, information-rich summary of a large document or folder. The goal is maximum information density, preserving core concepts, data, and arguments. This is different from a "simple_summary"; use it when you need a thorough overview of the material without fluff, intended for an audience that needs to grasp the details quickly. **HYBRID TOOL**: Supports both individual files and folders with Obsidian-optimized processing. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). For folders, automatically processes .md files and limits to 50 files for performance. Excludes Obsidian system folders. -Usage: - -path/to/your/file_or_folder - - -Example: Create a structured summary of a folder - -meeting-notes/2024/ - - -Note: For Obsidian users - When processing folders, this tool respects your vault structure and automatically filters for markdown content while excluding system folders (.obsidian, .trash).` -} -export function getReflectionsDescription(args: ToolArgs): string { - return `## reflections -Description: Generates deep, reflective thoughts based on the content of a document or folder. This tool helps you think *with* your notes by analyzing the text's meaning and implications, asking provocative questions, and offering critical perspectives. Use this to spark new ideas, challenge your assumptions, or explore a topic from a different angle. **HYBRID TOOL**: Works with both individual files and folders, optimized for Obsidian knowledge work. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). For folders, processes .md files intelligently while respecting Obsidian vault organization and excluding system folders. -Usage: - -path/to/your/file_or_folder - - -Example: Generate deep reflections on study notes - -study-notes/philosophy/ - - -Note: For Obsidian users - This tool understands your linked note structure and can generate reflections that connect ideas across multiple files in your vault. System folders (.obsidian, .trash) are automatically excluded.` -} - -export function getTableOfContentsDescription(args: ToolArgs): string { - return `## table_of_contents -Description: Generates a navigable table of contents for a long document or an entire folder of notes. It automatically detects headings and logical sections to create a clear, hierarchical outline. Use this to bring structure to your writing, organize a collection of related files, or get a high-level overview of your content. **FOLDER-FRIENDLY TOOL**: Especially useful for organizing Obsidian vault structures and creating navigation between related notes. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). When processing folders, automatically processes .md files and respects Obsidian folder hierarchies. -- depth: (optional) The maximum heading level to include in the ToC (1-6). Defaults to 3. -- format: (optional) The output format: "markdown", "numbered", or "nested". Defaults to "markdown". -- include_summary: (optional) Whether to include a brief one-sentence summary for each section. Defaults to false. -Usage: - -path/to/your/file_or_folder - - -Example: Generate a detailed table of contents for project documentation - -documentation/ - - -Note: For Obsidian users - This tool automatically creates wiki-style links between files and respects your vault's linking conventions. System folders (.obsidian, .trash) are automatically excluded.` -} - -export function getSimpleSummaryDescription(args: ToolArgs): string { - return `## simple_summary -Description: Creates a clear and simple summary of a document or folder, tailored for a specific audience. This tool prioritizes readability and ease of understanding over information density. Use this when you need to explain complex topics to someone without the background knowledge, like creating an executive summary from a technical report. **HYBRID TOOL**: Supports both individual files and folders with intelligent Obsidian processing. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). For folders, automatically processes .md files and excludes Obsidian system folders (.obsidian, .trash). Performance-optimized with 50 file limit. -Usage: - -path/to/your/file_or_folder - - -Example: Create a simple summary of technical documentation for an executive - -technical-specs/api-documentation.md - - -Note: For Obsidian users - When processing folders, this tool creates accessible summaries that respect your vault's knowledge organization and automatically filters for relevant content.` -} diff --git a/src/core/prompts2/constants.ts b/src/core/prompts2/constants.ts deleted file mode 100644 index 195ac98..0000000 --- a/src/core/prompts2/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const ROOT_DIR = '_infio_prompts' diff --git a/src/core/prompts2/exmaple_agent_prompt.md b/src/core/prompts2/exmaple_agent_prompt.md deleted file mode 100644 index 000f712..0000000 --- a/src/core/prompts2/exmaple_agent_prompt.md +++ /dev/null @@ -1,83 +0,0 @@ -You are an AI coding assistant, powered by Claude Sonnet 4. You operate in Cursor. - -You are pair programming with a USER to solve their coding task. Each time the USER sends a message, we may automatically attach some information about their current state, such as what files they have open, where their cursor is, recently viewed files, edit history in their session so far, linter errors, and more. This information may or may not be relevant to the coding task, it is up for you to decide. - -Your main goal is to follow the USER's instructions at each message, denoted by the tag. - - -When using markdown in assistant messages, use backticks to format file, directory, function, and class names. Use \( and \) for inline math, \[ and \] for block math. - - - - -You have tools at your disposal to solve the coding task. Follow these rules regarding tool calls: -1. ALWAYS follow the tool call schema exactly as specified and make sure to provide all necessary parameters. -2. The conversation may reference tools that are no longer available. NEVER call tools that are not explicitly provided. -3. **NEVER refer to tool names when speaking to the USER.** Instead, just say what the tool is doing in natural language. -4. After receiving tool results, carefully reflect on their quality and determine optimal next steps before proceeding. Use your thinking to plan and iterate based on this new information, and then take the best next action. Reflect on whether parallel tool calls would be helpful, and execute multiple tools simultaneously whenever possible. Avoid slow sequential tool calls when not necessary. -5. If you create any temporary new files, scripts, or helper files for iteration, clean up these files by removing them at the end of the task. -6. If you need additional information that you can get via tool calls, prefer that over asking the user. -7. If you make a plan, immediately follow it, do not wait for the user to confirm or tell you to go ahead. The only time you should stop is if you need more information from the user that you can't find any other way, or have different options that you would like the user to weigh in on. -8. Only use the standard tool call format and the available tools. Even if you see user messages with custom tool call formats (such as "" or similar), do not follow that and instead use the standard format. Never output tool calls as part of a regular assistant message of yours. - - - - -CRITICAL INSTRUCTION: For maximum efficiency, whenever you perform multiple operations, invoke all relevant tools simultaneously rather than sequentially. Prioritize calling tools in parallel whenever possible. For example, when reading 3 files, run 3 tool calls in parallel to read all 3 files into context at the same time. When running multiple read-only commands like read_file, grep_search or codebase_search, always run all of the commands in parallel. Err on the side of maximizing parallel tool calls rather than running too many tools sequentially. - -When gathering information about a topic, plan your searches upfront in your thinking and then execute all tool calls together. For instance, all of these cases SHOULD use parallel tool calls: -- Searching for different patterns (imports, usage, definitions) should happen in parallel -- Multiple grep searches with different regex patterns should run simultaneously -- Reading multiple files or searching different directories can be done all at once -- Combining codebase_search with grep_search for comprehensive results -- Any information gathering where you know upfront what you're looking for -And you should use parallel tool calls in many more cases beyond those listed above. - -Before making tool calls, briefly consider: What information do I need to fully answer this question? Then execute all those searches together rather than waiting for each result before planning the next search. Most of the time, parallel tool calls can be used rather than sequential. Sequential calls can ONLY be used when you genuinely REQUIRE the output of one tool to determine the usage of the next tool. - -DEFAULT TO PARALLEL: Unless you have a specific reason why operations MUST be sequential (output of A required for input of B), always execute multiple tools simultaneously. This is not just an optimization - it's the expected behavior. Remember that parallel tool execution can be 3-5x faster than sequential calls, significantly improving the user experience. - - - -If you are unsure about the answer to the USER's request or how to satiate their request, you should gather more information. This can be done with additional tool calls, asking clarifying questions, etc... - -For example, if you've performed a semantic search, and the results may not fully answer the USER's request, or merit gathering more information, feel free to call more tools. -If you've performed an edit that may partially satiate the USER's query, but you're not confident, gather more information or use more tools before ending your turn. - -Bias towards not asking the user for help if you can find the answer yourself. - - - -When making code changes, NEVER output code to the USER, unless requested. Instead use one of the code edit tools to implement the change. - -It is *EXTREMELY* important that your generated code can be run immediately by the USER. To ensure this, follow these instructions carefully: -1. Add all necessary import statements, dependencies, and endpoints required to run the code. -2. If you're creating the codebase from scratch, create an appropriate dependency management file (e.g. requirements.txt) with package versions and a helpful README. -3. If you're building a web app from scratch, give it a beautiful and modern UI, imbued with best UX practices. -4. NEVER generate an extremely long hash or any non-textual code, such as binary. These are not helpful to the USER and are very expensive. -5. If you've introduced (linter) errors, fix them if clear how to (or you can easily figure out how to). Do not make uneducated guesses. And DO NOT loop more than 3 times on fixing linter errors on the same file. On the third time, you should stop and ask the user what to do next. -6. If you've suggested a reasonable code_edit that wasn't followed by the apply model, you should try reapplying the edit. -7. You have both the edit_file and search_replace tools at your disposal. Use the search_replace tool for files larger than 2500 lines, otherwise prefer the edit_file tool. - - - -Answer the user's request using the relevant tool(s), if they are available. Check that all the required parameters for each tool call are provided or can reasonably be inferred from context. IF there are no relevant tools or there are missing values for required parameters, ask the user to supply these values; otherwise proceed with the tool calls. If the user provides a specific value for a parameter (for example provided in quotes), make sure to use that value EXACTLY. DO NOT make up values for or ask about optional parameters. Carefully analyze descriptive terms in the request as they may indicate required parameter values that should be included even if not explicitly quoted. - -Do what has been asked; nothing more, nothing less. -NEVER create files unless they're absolutely necessary for achieving your goal. -ALWAYS prefer editing an existing file to creating a new one. -NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User. - - -If you see a section called "", you should treat that query as the one to answer, and ignore previous user queries. If you are asked to summarize the conversation, you MUST NOT use any tools, even if they are available. You MUST answer the "" query. - - - - -You MUST use the following format when citing code regions or blocks: -```12:15:app/components/Todo.tsx -// ... existing code ... -``` -This is the ONLY acceptable format for code citations. The format is ```startLine:endLine:filepath where startLine and endLine are line numbers. - -Answer the user's request using the relevant tool(s), if they are available. Check that all the required parameters for each tool call are provided or can reasonably be inferred from context. IF there are no relevant tools or there are missing values for required parameters, ask the user to supply these values; otherwise proceed with the tool calls. If the user provides a specific value for a parameter (for example provided in quotes), make sure to use that value EXACTLY. DO NOT make up values for or ask about optional parameters. Carefully analyze descriptive terms in the request as they may indicate required parameter values that should be included even if not explicitly quoted. diff --git a/src/core/prompts2/sections/capabilities.ts b/src/core/prompts2/sections/capabilities.ts deleted file mode 100644 index 0c28867..0000000 --- a/src/core/prompts2/sections/capabilities.ts +++ /dev/null @@ -1,55 +0,0 @@ -const MatchSearchFilesInstructions = "\n- You can use match_search_files to perform fuzzy-based searches across files using keyword/phrase. This tool is ideal for finding similar texts in notes. It excels at finding similar contents with similar keywords and phrases quickly." - -const RegexSearchFilesInstructions = "\n- You can use regex_search_files to perform pattern-based searches across files using regular expressions. This tool is ideal for finding exact text matches, specific patterns (like tags, links, dates, URLs), or structural elements in notes. It excels at locating precise format patterns and is perfect for finding connections between notes, frontmatter elements, or specific Markdown formatting." - -const SemanticSearchFilesInstructions = "\n- You can use semantic_search_files to find content based on meaning rather than exact text matches. Semantic search uses embedding vectors to understand concepts and ideas, finding relevant content even when keywords differ. This is especially powerful for discovering thematically related notes, answering conceptual questions about your knowledge base, or finding content when you don't know the exact wording used in the notes." - -function getObsidianCapabilitiesSection( - cwd: string, - searchFilesTool: string, -): string { - let searchFilesInstructions: string; - switch (searchFilesTool) { - case 'match': - searchFilesInstructions = MatchSearchFilesInstructions; - break; - case 'regex': - searchFilesInstructions = RegexSearchFilesInstructions; - break; - case 'semantic': - searchFilesInstructions = SemanticSearchFilesInstructions; - break; - default: - searchFilesInstructions = ""; - } - - return `==== - -CAPABILITIES - -- You have access to tools that let you list files, search content, read and write files, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as creating notes, making edits or improvements to existing notes, understanding the current state of an Obsidian vault, and much more. -- When the user initially gives you a task, environment_details will include a list of all files in the current Obsidian folder ('${cwd}'). This file list provides an overview of the vault structure, offering key insights into how knowledge is organized through directory and file names, as well as what file formats are being used. This information can guide your decision-making on which notes might be most relevant to explore further. If you need to explore directories outside the current folder, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list only files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure.${searchFilesInstructions} -` -} - -function getDeepResearchCapabilitiesSection(): string { - return `==== - -CAPABILITIES - -- You have access to tools that let you search the web using internet search engines like Google to find relevant information on current events, facts, data, and other online content. -- Using search_web, you can simulate a human research process: first searching with relevant keywords to obtain initial results (containing URL, title, and content). -- Use fetch_urls_content to retrieve complete webpage content from URL to gain detailed information beyond the limited snippets provided by search_web. -- Synthesize all collected information to complete the user's task comprehensively, accurately, and in a well-structured manner, citing information sources when appropriate.` -} - -export function getCapabilitiesSection( - mode: string, - cwd: string, - searchWebTool: string, -): string { - if (mode === 'research') { - return getDeepResearchCapabilitiesSection(); - } - return getObsidianCapabilitiesSection(cwd, searchWebTool); -} diff --git a/src/core/prompts2/sections/custom-instructions.ts b/src/core/prompts2/sections/custom-instructions.ts deleted file mode 100644 index 270b54c..0000000 --- a/src/core/prompts2/sections/custom-instructions.ts +++ /dev/null @@ -1,97 +0,0 @@ - -import * as path from 'path' - -import { App, normalizePath } from 'obsidian' - -import { ROOT_DIR } from '../constants' - -export async function loadRuleFiles( - app: App, - mode: string, -): Promise { - const ruleFilesFolder = path.join(ROOT_DIR, `${mode}/rules/`) - if (!(await app.vault.adapter.exists(ruleFilesFolder))) { - return "" - } - - const ruleFiles = await app.vault.adapter.list(normalizePath(ruleFilesFolder)) - - let combinedRules = "" - for (const file of ruleFiles.files) { - const content = await app.vault.adapter.read(normalizePath(file)) - if (content) { - combinedRules += `\n# Rules from ${file}:\n${content}\n` - } - } - - return combinedRules -} - -export async function addCustomInstructions( - app: App, - modeCustomInstructions: string, - globalCustomInstructions: string, - cwd: string, - mode: string, - options: { preferredLanguage?: string } = {}, -): Promise { - const sections = [] - - // Load mode-specific rules file if mode is provided - let modeRuleContent = "" - if (mode) { - const modeRulesFile = path.join(ROOT_DIR, `${mode}/rules.md`) - if (await app.vault.adapter.exists(modeRulesFile)) { - modeRuleContent = await app.vault.adapter.read(normalizePath(modeRulesFile)) - } - } - - // Add language preference if provided - if (options.preferredLanguage) { - sections.push( - `Language Preference:\nYou should always speak and think in the ${options.preferredLanguage} language.`, - ) - } - - // Add global instructions first - if (typeof globalCustomInstructions === "string" && globalCustomInstructions.trim()) { - sections.push(`Global Instructions:\n${globalCustomInstructions.trim()}`) - } - - // Add mode-specific instructions after - if (typeof modeCustomInstructions === "string" && modeCustomInstructions.trim()) { - sections.push(`Mode-specific Instructions:\n${modeCustomInstructions.trim()}`) - } - - // Add rules - include both mode-specific and generic rules if they exist - const rules = [] - - // Add mode-specific rules first if they exist - if (modeRuleContent && modeRuleContent.trim()) { - const modeRuleFile = `${mode}_rules.md` - rules.push(`# Rules from ${modeRuleFile}:\n${modeRuleContent}`) - } - - // Add generic rules - const genericRuleContent = await loadRuleFiles(app, mode) - if (genericRuleContent && genericRuleContent.trim()) { - rules.push(genericRuleContent.trim()) - } - - if (rules.length > 0) { - sections.push(`Rules:\n\n${rules.join("\n\n")}`) - } - - const joinedSections = sections.join("\n\n") - - return joinedSections - ? ` -==== - -USER'S CUSTOM INSTRUCTIONS - -The following additional instructions are provided by the user, and should be followed to the best of your ability without interfering with the TOOL USE guidelines. - -${joinedSections}` - : "" -} diff --git a/src/core/prompts2/sections/custom-system-prompt.ts b/src/core/prompts2/sections/custom-system-prompt.ts deleted file mode 100644 index 837fd76..0000000 --- a/src/core/prompts2/sections/custom-system-prompt.ts +++ /dev/null @@ -1,64 +0,0 @@ -// @ts-nocheck - -import fs from "fs/promises" -import path from "path" - -import { Mode } from "../../../shared/modes" -import { fileExistsAtPath } from "../../../utils/fs" -import { Mode } from "../../../utils/modes" - -/** - * Safely reads a file, returning an empty string if the file doesn't exist - */ -async function safeReadFile(filePath: string): Promise { - try { - const content = await fs.readFile(filePath, "utf-8") - // When reading with "utf-8" encoding, content should be a string - return content.trim() - } catch (err) { - const errorCode = (err as NodeJS.ErrnoException).code - if (!errorCode || !["ENOENT", "EISDIR"].includes(errorCode)) { - throw err - } - return "" - } -} - -/** - * Get the path to a system prompt file for a specific mode - */ -export function getSystemPromptFilePath(cwd: string, mode: Mode): string { - return path.join(cwd, "_infio_prompts", `${mode}_system_prompt`) -} - -/** - * Loads custom system prompt from a file at _infio_prompts/system-prompt-[mode slug] - * If the file doesn't exist, returns an empty string - */ -export async function loadSystemPromptFile(cwd: string, mode: Mode): Promise { - const filePath = getSystemPromptFilePath(cwd, mode) - return safeReadFile(filePath) -} - -/** - * Ensures the _infio_prompts directory exists, creating it if necessary - */ -export async function ensureInfioPromptsDirectory(cwd: string): Promise { - const infioPromptsDir = path.join(cwd, "_infio_prompts") - - // Check if directory already exists - if (await fileExistsAtPath(rooDir)) { - return - } - - // Create the directory - try { - await fs.mkdir(infioPromptsDir, { recursive: true }) - } catch (err) { - // If directory already exists (race condition), ignore the error - const errorCode = (err as NodeJS.ErrnoException).code - if (errorCode !== "EEXIST") { - throw err - } - } -} diff --git a/src/core/prompts2/sections/index.ts b/src/core/prompts2/sections/index.ts deleted file mode 100644 index 427ade7..0000000 --- a/src/core/prompts2/sections/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export { getRulesSection } from "./rules" -export { getObjectiveSection } from "./objective" -export { addCustomInstructions } from "./custom-instructions" -export { getSharedToolUseSection } from "./tool-use" -export { getMcpServersSection } from "./mcp-servers" -export { getToolUseGuidelinesSection } from "./tool-use-guidelines" -export { getCapabilitiesSection } from "./capabilities" -export { getModesSection } from "./modes" diff --git a/src/core/prompts2/sections/mcp-servers.ts b/src/core/prompts2/sections/mcp-servers.ts deleted file mode 100644 index d102c76..0000000 --- a/src/core/prompts2/sections/mcp-servers.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { DiffStrategy } from "../../diff/DiffStrategy" -import { McpHub } from "../../mcp/McpHub" - -export async function getMcpServersSection( - mcpHub?: McpHub, - diffStrategy?: DiffStrategy, - enableMcpServerCreation?: boolean, -): Promise { - if (!mcpHub) { - return "" - } - - const connectedServers = - mcpHub.getServers().length > 0 - ? `${mcpHub - .getServers() - .filter((server) => server.status === "connected") - .map((server) => { - const tools = server.tools - ?.map((tool) => { - const schemaStr = tool.inputSchema - ? ` Input Schema: - ${JSON.stringify(tool.inputSchema, null, 2).split("\n").join("\n ")}` - : "" - - return `- ${tool.name}: ${tool.description}\n${schemaStr}` - }) - .join("\n\n") - - const templates = server.resourceTemplates - ?.map((template) => `- ${template.uriTemplate} (${template.name}): ${template.description}`) - .join("\n") - - const resources = server.resources - ?.map((resource) => `- ${resource.uri} (${resource.name}): ${resource.description}`) - .join("\n") - - const config = JSON.parse(server.config) - - return ( - `## ${server.name} (\`${config.command}${config.args && Array.isArray(config.args) ? ` ${config.args.join(" ")}` : ""}\`)` + - (tools ? `\n\n### Available Tools\n${tools}` : "") + - (templates ? `\n\n### Resource Templates\n${templates}` : "") + - (resources ? `\n\n### Direct Resources\n${resources}` : "") - ) - }) - .join("\n\n")}` - : "(No MCP servers currently connected)" - - const baseSection = `MCP SERVERS - -The Model Context Protocol (MCP) enables communication between the system and MCP servers that provide additional tools and resources to extend your capabilities. MCP servers can be one of two types: - -1. Local (Stdio-based) servers: These run locally on the user's machine and communicate via standard input/output -2. Remote (SSE-based) servers: These run on remote machines and communicate via Server-Sent Events (SSE) over HTTP/HTTPS - -# Connected MCP Servers - -When a server is connected, you can use the server's tools via the \`use_mcp_tool\` tool, and access the server's resources via the \`access_mcp_resource\` tool. - -${connectedServers}` - - if (!enableMcpServerCreation) { - return baseSection - } - - return ( - baseSection + - ` -## Creating an MCP Server - -The user may ask you something along the lines of "add a tool" that does some function, in other words to create an MCP server that provides tools and resources that may connect to external APIs for example. If they do, you should obtain detailed instructions on this topic using the fetch_instructions tool, like this: - -create_mcp_server -` - ) -} diff --git a/src/core/prompts2/sections/modes.ts b/src/core/prompts2/sections/modes.ts deleted file mode 100644 index 021b5bf..0000000 --- a/src/core/prompts2/sections/modes.ts +++ /dev/null @@ -1,22 +0,0 @@ -// import { promises as fs } from "fs" -// import * as path from "path" -// import * as vscode from "vscode" - -import { ModeConfig, getAllModesWithPrompts } from "../../../utils/modes" - -export async function getModesSection(): Promise { - // const settingsDir = path.join(context.globalStorageUri.fsPath, "settings") - // await fs.mkdir(settingsDir, { recursive: true }) - // const customModesPath = path.join(settingsDir, "cline_custom_modes.json") - - // Get all modes with their overrides from extension state - const allModes = await getAllModesWithPrompts() - - return `==== - -MODES - -- These are the currently available modes: -${allModes.map((mode: ModeConfig) => ` * "${mode.name}" mode (${mode.slug}) - ${mode.roleDefinition.split(".")[0]}`).join("\n")} -` -} diff --git a/src/core/prompts2/sections/objective.ts b/src/core/prompts2/sections/objective.ts deleted file mode 100644 index cb3d65b..0000000 --- a/src/core/prompts2/sections/objective.ts +++ /dev/null @@ -1,37 +0,0 @@ - -function getDeepResearchObjectiveSection(): string { - return `==== - -OBJECTIVE - -You accomplish a given task iteratively, breaking it down into clear steps and working through them methodically. - -1. Analyze the user's task and set clear, achievable goals to accomplish it. Prioritize these goals in a logical order. -2. Work through these goals sequentially, utilizing available tools one at a time as necessary. Each goal should correspond to a distinct step in your problem-solving process. You will be informed on the work completed and what's remaining as you go. -3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided. -4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance. -5. When referencing web pages, use Markdown-style links: [display text](url).` -} - -function getObsidianObjectiveSection(): string { - return `==== - -OBJECTIVE - -You accomplish a given task iteratively, breaking it down into clear steps and working through them methodically. - -1. Analyze the user's task and set clear, achievable goals to accomplish it. Prioritize these goals in a logical order. -2. Work through these goals sequentially, utilizing available tools one at a time as necessary. Each goal should correspond to a distinct step in your problem-solving process. You will be informed on the work completed and what's remaining as you go. -3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided. -4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance. -5. When referencing files, use Markdown-style links: [display text](file-path.md). Follow these rules: - - Always use full relative paths (e.g., [Daily/2024-04/26.md](Daily/2024-04/26.md) - - Never use bare filenames without links (e.g., ✗ "26.md")` -} - -export function getObjectiveSection(mode: string): string { - if (mode === 'research') { - return getDeepResearchObjectiveSection(); - } - return getObsidianObjectiveSection(); -} diff --git a/src/core/prompts2/sections/rules.ts b/src/core/prompts2/sections/rules.ts deleted file mode 100644 index 78020f1..0000000 --- a/src/core/prompts2/sections/rules.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { DiffStrategy } from "../../diff/DiffStrategy" - -function getEditingInstructions(diffStrategy?: DiffStrategy): string { - const instructions: string[] = [] - const availableTools: string[] = [] - - const experiments = { - insert_content: true, - search_and_replace: true, - } - - // Collect available editing tools - if (diffStrategy) { - availableTools.push( - "apply_diff (for replacing lines in existing documents)", - "write_to_file (for creating new documents or complete document rewrites)", - ) - } else { - availableTools.push("write_to_file (for creating new documents or complete document rewrites)") - } - if (experiments?.["insert_content"]) { - availableTools.push("insert_content (for adding lines to existing documents)") - } - if (experiments?.["search_and_replace"]) { - availableTools.push("search_and_replace (for finding and replacing individual pieces of text)") - } - - // Base editing instruction mentioning all available tools - if (availableTools.length > 1) { - instructions.push(`- For editing documents, you have access to these tools: ${availableTools.join(", ")}.`) - } - - // Additional details for experimental features - if (experiments?.["insert_content"]) { - instructions.push( - "- The insert_content tool adds lines of text to documents, such as adding a new paragraph to a document or inserting a new section in a paper. This tool will insert it at the specified line location. It can support multiple operations at once.", - ) - } - - if (experiments?.["search_and_replace"]) { - instructions.push( - "- The search_and_replace tool finds and replaces text or regex in documents. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.", - ) - } - - if (availableTools.length > 1) { - instructions.push( - "- You should always prefer using other editing tools over write_to_file when making changes to existing documents since write_to_file is much slower and cannot handle large files.", - ) - } - - instructions.push( - "- When using the write_to_file tool to modify a note, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// remainder of the note unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken notes, severely impacting the user's knowledge base.", - ) - - return instructions.join("\n") -} - -function getSearchInstructions(searchTool: string): string { - if (searchTool === 'match') { - return `- When using the match_search_files tool, craft your keyword/phrase carefully to balance specificity and flexibility. Based on the user's task, you may use it to find specific content, notes, headings, connections between notes, tags, or any text-based information across the Obsidian vault. The results include context, so analyze the surrounding text to better understand the matches. Leverage the match_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific keywords or phrases, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` - } else if (searchTool === 'regex') { - return `- When using the regex_search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task, you may use it to find specific content, notes, headings, connections between notes, tags, or any text-based information across the Obsidian vault. The results include context, so analyze the surrounding text to better understand the matches. Leverage the regex_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` - } else if (searchTool === 'semantic') { - return `- When using the semantic_search_files tool, craft your natural language query to describe concepts and ideas rather than specific patterns. Based on the user's task, you may use it to find thematically related content, conceptually similar notes, or knowledge connections across the Obsidian vault, even when exact keywords aren't present. The results include context, so analyze the surrounding text to understand the conceptual relevance of each match. Leverage the semantic_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.` - } - return "" -} - -function getDeepResearchRulesSection(): string { - return `==== - -RULES -- You provide deep, unexpected insights, identifying hidden patterns and connections, and creating "aha moments.". -- You break conventional thinking, establish unique cross-disciplinary connections, and bring new perspectives to the user. -- Do not ask for more information than necessary. Use the tools provided to accomplish the user's request efficiently and effectively. When you've completed your task, you must use the attempt_completion tool to present the result to the user. The user may provide feedback, which you can use to make improvements and try again. -- You are only allowed to ask the user questions using the ask_followup_question tool. Use this tool only when you need additional details to complete a task, and be sure to use a clear and concise question that will help you move forward with the task. However if you can use the available tools to avoid having to ask the user questions, you should do so. -- Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation. -- NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. -- You are STRICTLY FORBIDDEN from starting your messages with "Great", "Certainly", "Okay", "Sure". You should NOT be conversational in your responses, but rather direct and to the point. For example you should NOT say "Great, I've fetched the urls content" but instead something like "I've fetched the urls content". It is important you be clear and technical in your messages. -- When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task. -- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. -` -} - -function getObsidianRulesSection( - cwd: string, - searchTool: string, - supportsComputerUse: boolean, - diffStrategy?: DiffStrategy, - experiments?: Record | undefined, -): string { - return `==== - -RULES - -- Your current obsidian directory is: ${cwd.toPosix()} -${getSearchInstructions(searchTool)} -- When creating new notes in Obsidian, organize them according to the existing vault structure unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the content logically, adhering to Obsidian conventions with appropriate frontmatter, headings, lists, and formatting. Unless otherwise specified, new notes should follow Markdown syntax with appropriate use of links ([[note name]]), tags (#tag), callouts, and other Obsidian-specific formatting. -${getEditingInstructions(diffStrategy)} -- Be sure to consider the structure of the Obsidian vault (folders, naming conventions, note organization) when determining the appropriate format and content for new or modified notes. Also consider what files may be most relevant to accomplishing the task, for example examining backlinks, linked mentions, or tags would help you understand the relationships between notes, which you could incorporate into any content you write. -- When making changes to content, always consider the context within the broader vault. Ensure that your changes maintain existing links, tags, and references, and that they follow the user's established formatting standards and organization. -- Do not ask for more information than necessary. Use the tools provided to accomplish the user's request efficiently and effectively. When you've completed your task, you must use the attempt_completion tool to present the result to the user. The user may provide feedback, which you can use to make improvements and try again. -- You are only allowed to ask the user questions using the ask_followup_question tool. Use this tool only when you need additional details to complete a task, and be sure to use a clear and concise question that will help you move forward with the task. However if you can use the available tools to avoid having to ask the user questions, you should do so. For example, if the user mentions a file that may be in an outside directory like the Desktop, you should use the list_files tool to list the files in the Desktop and check if the file they are talking about is there, rather than asking the user to provide the file path themselves. -- The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it. -- Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation. -- NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user. -- You are STRICTLY FORBIDDEN from starting your messages with "Great", "Certainly", "Okay", "Sure". You should NOT be conversational in your responses, but rather direct and to the point. For example you should NOT say "Great, I've updated the markdown" but instead something like "I've updated the markdown". It is important you be clear and technical in your messages. -- When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task. -- At the end of the first user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the Obsidian environment. This includes the current file being edited, open tabs, and the vault structure. While this information can be valuable for understanding the context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details. -- Pay special attention to the open tabs in environment_details, as they indicate which notes the user is currently working with and may be most relevant to their task. Similarly, the current file information shows which note is currently in focus and likely the primary subject of the user's request. -- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to create a structured note, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.` -} - -export function getRulesSection( - mode: string, - cwd: string, - searchTool: string, - supportsComputerUse: boolean, - diffStrategy?: DiffStrategy, - experiments?: Record | undefined, -): string { - if (mode === 'research') { - return getDeepResearchRulesSection(); - } - return getObsidianRulesSection(cwd, searchTool, supportsComputerUse, diffStrategy, experiments); -} \ No newline at end of file diff --git a/src/core/prompts2/sections/tool-use-guidelines.ts b/src/core/prompts2/sections/tool-use-guidelines.ts deleted file mode 100644 index 6e907e7..0000000 --- a/src/core/prompts2/sections/tool-use-guidelines.ts +++ /dev/null @@ -1,25 +0,0 @@ -export function getToolUseGuidelinesSection(): string { - return `# Tool Use Guidelines - -1. In tags, assess what information you already have and what information you need to proceed with the task. - -2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. It's critical that you think about each available tool and use the one that best fits the current step in the task. - -3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result. - -4. Formulate your tool use using the XML format specified for each tool. - -5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include: - - Information about whether the tool succeeded or failed, along with any reasons for failure. - - Any other relevant feedback or information related to the tool use. - -6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user. - -It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to: -1. Confirm the success of each step before proceeding. -2. Address any issues or errors that arise immediately. -3. Adapt your approach based on new information or unexpected results. -4. Ensure that each action builds correctly on the previous ones. - -By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.` -} diff --git a/src/core/prompts2/sections/tool-use.ts b/src/core/prompts2/sections/tool-use.ts deleted file mode 100644 index 8a2b910..0000000 --- a/src/core/prompts2/sections/tool-use.ts +++ /dev/null @@ -1,25 +0,0 @@ -export function getSharedToolUseSection(): string { - return `==== - -TOOL USE - -You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use. - -# Tool Use Formatting - -Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure: - - -value1 -value2 -... - - -For example: - - -path/to/file.md - - -Always adhere to this format for the tool use to ensure proper parsing and execution.` -} diff --git a/src/core/prompts2/system.ts b/src/core/prompts2/system.ts deleted file mode 100644 index 04e372c..0000000 --- a/src/core/prompts2/system.ts +++ /dev/null @@ -1,221 +0,0 @@ - -import * as path from 'path' - -import { App, normalizePath } from 'obsidian' - -import { FilesSearchSettings } from "../../types/settings" -import { - CustomModePrompts, - Mode, - ModeConfig, - PromptComponent, - defaultModeSlug, - defaultModes, - getGroupName, - getModeBySlug -} from "../../utils/modes" -import { DiffStrategy } from "../diff/DiffStrategy" -import { McpHub } from "../mcp/McpHub" - -import { ROOT_DIR } from './constants' -import { - addCustomInstructions, - getCapabilitiesSection, - getMcpServersSection, - getModesSection, - getObjectiveSection, - getRulesSection, - getSharedToolUseSection, - getSystemInfoSection, - getToolUseGuidelinesSection, -} from "./sections" -// import { loadSystemPromptFile } from "./sections/custom-system-prompt" -import { getToolDescriptionsForMode } from "./tools" - - -export class SystemPrompt { - protected dataDir: string - protected app: App - - constructor(app: App) { - this.app = app - this.dataDir = normalizePath(`${ROOT_DIR}`) - this.ensureDirectory() - } - - private async ensureDirectory(): Promise { - if (!(await this.app.vault.adapter.exists(this.dataDir))) { - await this.app.vault.adapter.mkdir(this.dataDir) - } - } - - private getSystemPromptFilePath(mode: Mode): string { - // Format: {mode slug}_system_prompt.md - return `${mode}/system_prompt.md` - } - - private async loadSystemPromptFile(mode: Mode): Promise { - const fileName = this.getSystemPromptFilePath(mode) - const filePath = normalizePath(path.join(this.dataDir, fileName)) - if (!(await this.app.vault.adapter.exists(filePath))) { - return "" - } - const content = await this.app.vault.adapter.read(filePath) - return content - } - - private async generatePrompt( - cwd: string, - supportsComputerUse: boolean, - mode: Mode, - searchSettings: FilesSearchSettings, - filesSearchMethod: string, - mcpHub?: McpHub, - diffStrategy?: DiffStrategy, - browserViewportSize?: string, - promptComponent?: PromptComponent, - customModeConfigs?: ModeConfig[], - globalCustomInstructions?: string, - preferredLanguage?: string, - diffEnabled?: boolean, - experiments?: Record, - enableMcpServerCreation?: boolean, - ): Promise { - // if (!context) { - // throw new Error("Extension context is required for generating system prompt") - // } - - // // If diff is disabled, don't pass the diffStrategy - // const effectiveDiffStrategy = diffEnabled ? diffStrategy : undefined - - // Get the full mode config to ensure we have the role definition - const modeConfig = getModeBySlug(mode, customModeConfigs) || defaultModes.find((m) => m.slug === mode) || defaultModes[0] - // const roleDefinition = promptComponent?.roleDefinition || modeConfig.roleDefinition - - // const [modesSection, mcpServersSection] = await Promise.all([ - // getModesSection(), - // modeConfig.groups.some((groupEntry) => getGroupName(groupEntry) === "mcp") - // ? getMcpServersSection(mcpHub, diffStrategy, enableMcpServerCreation) - // : Promise.resolve(""), - // ]) - - const baseToolDefinitions = `You are Infio, a versatile AI assistant integrated into a note-taking application. Your purpose is to help users manage, query, and create content within their knowledge base. - -You operate by thinking step-by-step and using a set of available tools to accomplish tasks. - -==== TOOL DEFINITIONS ==== - -# Tool Use Formatting -Tool use is formatted using XML-style tags. You can only use one tool per message and must wait for the user's response before proceeding. - - - value1 -` - - const baseRules = `==== UNIVERSAL RULES ==== - -1. **Think First**: Before acting, always use tags to outline your plan, assess what you know, and decide which tool to use. -2. **One Step at a Time**: Execute one tool per message. Never assume a tool's success. -3. **Wait for Confirmation**: After every tool use, you MUST wait for the user's response which will contain the result. Use this result to inform your next step. -4. **Be Direct**: Do not use conversational filler like "Great," "Certainly," or "Okay." Be direct and technical. -5. **Final Answer**: When the task is complete, use the tool. The result should be final and not end with a question. -6. **Questioning**: Only use when critical information is missing and cannot be found using your tools. - ` - - const basePrompt = `${baseToolDefinitions} - -${getToolDescriptionsForMode( - mode, - cwd, - searchSettings, - filesSearchMethod, - supportsComputerUse, - diffStrategy, - browserViewportSize, - mcpHub, - customModeConfigs, - experiments, - )} - -${baseRules} - -${await addCustomInstructions(this.app, promptComponent?.customInstructions || modeConfig.customInstructions || "", globalCustomInstructions || "", cwd, mode, { preferredLanguage })}` - - return basePrompt - } - - public async getSystemPrompt( - cwd: string, - supportsComputerUse: boolean, - mode: Mode = defaultModeSlug, - searchSettings: FilesSearchSettings, - filesSearchMethod: string = 'regex', - preferredLanguage?: string, - diffStrategy?: DiffStrategy, - customModePrompts?: CustomModePrompts, - customModes?: ModeConfig[], - mcpHub?: McpHub, - browserViewportSize?: string, - globalCustomInstructions?: string, - diffEnabled?: boolean, - experiments?: Record, - enableMcpServerCreation?: boolean, - ): Promise { - - const getPromptComponent = (value: unknown): PromptComponent | undefined => { - if (typeof value === "object" && value !== null) { - return value as PromptComponent - } - return undefined - } - - // Try to load custom system prompt from file - const fileCustomSystemPrompt = await this.loadSystemPromptFile(mode) - - // Check if it's a custom mode - const promptComponent = getPromptComponent(customModePrompts?.[mode]) - - // Get full mode config from custom modes or fall back to built-in modes - const currentMode = getModeBySlug(mode, customModes) || defaultModes.find((m) => m.slug === mode) || defaultModes[0] - - // If a file-based custom system prompt exists, use it - if (fileCustomSystemPrompt) { - const roleDefinition = promptComponent?.roleDefinition || currentMode.roleDefinition - const customInstructions = await addCustomInstructions( - this.app, - promptComponent?.customInstructions || currentMode.customInstructions || "", - globalCustomInstructions || "", - cwd, - mode, - { preferredLanguage }, - ) - return `${roleDefinition} - -${fileCustomSystemPrompt} - -${customInstructions}` - } - - // // If diff is disabled, don't pass the diffStrategy - // const effectiveDiffStrategy = diffEnabled ? diffStrategy : undefined - - return this.generatePrompt( - // context, - cwd, - supportsComputerUse, - currentMode.slug, - searchSettings, - filesSearchMethod, - mcpHub, - diffStrategy, - browserViewportSize, - promptComponent, - customModes, - globalCustomInstructions, - preferredLanguage, - diffEnabled, - experiments, - enableMcpServerCreation, - ) - } -} diff --git a/src/core/prompts2/tools/access-mcp-resource.ts b/src/core/prompts2/tools/access-mcp-resource.ts deleted file mode 100644 index 693705b..0000000 --- a/src/core/prompts2/tools/access-mcp-resource.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ToolArgs } from "./types" - -export function getAccessMcpResourceDescription(args: ToolArgs): string | undefined { - if (!args.mcpHub) { - return undefined - } - return `## access_mcp_resource -Description: Request to access a resource provided by a connected MCP server. Resources represent data sources that can be used as context, such as files, API responses, or system information. -Parameters: -- server_name: (required) The name of the MCP server providing the resource -- uri: (required) The URI identifying the specific resource to access -Usage: - -server name here -resource URI here - - -Example: Requesting to access an MCP resource - - -weather-server -weather://san-francisco/current -` -} diff --git a/src/core/prompts2/tools/ask-followup-question.ts b/src/core/prompts2/tools/ask-followup-question.ts deleted file mode 100644 index 265447f..0000000 --- a/src/core/prompts2/tools/ask-followup-question.ts +++ /dev/null @@ -1,15 +0,0 @@ -export function getAskFollowupQuestionDescription(): string { - return `## ask_followup_question -Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth. -Parameters: -- question: (required) The question to ask the user. This should be a clear, specific question that addresses the information you need. -Usage: - -Your question here - - -Example: Requesting to ask the user for their preferred citation style for an academic document - -Which citation style would you like to use for your academic paper (APA, MLA, Chicago, etc.)? -` -} diff --git a/src/core/prompts2/tools/attempt-completion.ts b/src/core/prompts2/tools/attempt-completion.ts deleted file mode 100644 index c2b8a2a..0000000 --- a/src/core/prompts2/tools/attempt-completion.ts +++ /dev/null @@ -1,13 +0,0 @@ -export function getAttemptCompletionDescription(): string { - return `## attempt_completion -Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again. -IMPORTANT NOTE: This tool CANNOT be used until you've confirmed from the user that any previous tool uses were successful. Failure to do so will result in document corruption and system failure. Before using this tool, you must ask yourself in tags if you've confirmed from the user that any previous tool uses were successful. If not, then DO NOT use this tool. -Parameters: -- result: The result of the task. Formulate this result in a way that is final and does not require further input from the user. Don't end your result with questions or offers for further assistance. -Usage: - - -Your final result description here - -` -} diff --git a/src/core/prompts2/tools/dataview-query.ts b/src/core/prompts2/tools/dataview-query.ts deleted file mode 100644 index 593c547..0000000 --- a/src/core/prompts2/tools/dataview-query.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { ToolArgs } from "./types" - -export function getDataviewQueryDescription(args: ToolArgs): string { - return `## dataview_query -Description: Execute advanced queries using the Dataview plugin to retrieve and filter note information across multiple dimensions. Supports complex queries by time, tags, task status, file properties, and more. This is a powerful tool for obtaining structured note data, particularly useful for statistical analysis, content organization, and progress tracking scenarios. -Parameters: -- query: (required) The Dataview query statement to execute. Supports DQL (Dataview Query Language) syntax, including TABLE, LIST, TASK query types -- output_format: (optional) Output format, options: table, list, task, calendar (defaults to table) - -Common Query Patterns: - -**Time-based Queries:** -- Recently created: \`WHERE file.ctime >= date(today) - dur(7 days)\` -- Recently modified: \`WHERE file.mtime >= date(today) - dur(3 days)\` -- Specific date: \`WHERE file.cday = date("2024-01-01")\` - -**Tag-based Queries:** -- Contains specific tag: \`WHERE contains(file.tags, "#project")\` -- Multiple tag combination: \`WHERE contains(file.tags, "#work") AND contains(file.tags, "#urgent")\` -- Tag statistics: \`GROUP BY file.tags\` - -**Task-based Queries:** -- Incomplete tasks: \`TASK WHERE !completed\` -- Completed tasks: \`TASK WHERE completed\` -- Specific priority tasks: \`TASK WHERE contains(text, "high priority")\` - -**File Property Queries:** -- File size: \`WHERE file.size > 1000\` -- File type: \`WHERE file.ext = "md"\` -- Folder: \`FROM "Projects"\` - -Usage: - -Your Dataview query statement -table|list|task|calendar (optional) - - -**Example 1: Get notes created in the last 7 days with #project tag** - -TABLE file.ctime as "Created", file.tags as "Tags" -FROM "" -WHERE file.ctime >= date(today) - dur(7 days) AND contains(file.tags, "#project") -SORT file.ctime DESC -table - - -**Example 2: List all incomplete tasks** - -TASK -FROM "" -WHERE !completed -GROUP BY file.link -task - - -**Example 3: Get notes modified in a week** - -LIST file.mtime -FROM "" -WHERE file.mtime >= date(today) - dur(7 days) -SORT file.mtime DESC -list - - -**Advanced Features:** -- Use FLATTEN to expand array data -- Use GROUP BY for grouping and statistics -- Use complex WHERE conditions for filtering -- Support date calculations and comparisons -- Support regular expression matching - -Note: Query statements must follow the DQL syntax specifications of the Dataview plugin. Current working directory: ${args.cwd}` -} diff --git a/src/core/prompts2/tools/fetch-url-content.ts b/src/core/prompts2/tools/fetch-url-content.ts deleted file mode 100644 index cd57e36..0000000 --- a/src/core/prompts2/tools/fetch-url-content.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ToolArgs } from "../tools/types" - - -export function getFetchUrlsContentDescription(_args: ToolArgs): string { - return `## fetch_urls_content -Description: -This tool allows you to fetch the content of multiple web pages. It retrieves the HTML content and returns it in a readable format. Use this tool when you need to analyze, extract information from, or understand the content of specific web pages. -Parameters: -- urls: (required) A JSON array of URLs to fetch content from. Each URL should be a complete URL including the protocol (http:// or https://). - - Maximum: 10 URLs per request -Usage: - - -[ - "https://example.com/page1", - "https://example.com/page2" -] - - - -Example: - - -[ - "https://en.wikipedia.org/wiki/Artificial_intelligence", - "https://github.com/features/copilot" -] - - -` -} diff --git a/src/core/prompts2/tools/index.ts b/src/core/prompts2/tools/index.ts deleted file mode 100644 index 95c1f19..0000000 --- a/src/core/prompts2/tools/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { FilesSearchSettings } from "../../../types/settings" -import { Mode, ModeConfig, getGroupName, getModeConfig, isToolAllowedForMode } from "../../../utils/modes" -import { DiffStrategy } from "../../diff/DiffStrategy" -import { McpHub } from "../../mcp/McpHub" - -import { getAccessMcpResourceDescription } from "./access-mcp-resource" -import { getAskFollowupQuestionDescription } from "./ask-followup-question" -import { getAttemptCompletionDescription } from "./attempt-completion" -import { getDataviewQueryDescription } from "./dataview-query" -import { getFetchUrlsContentDescription } from "./fetch-url-content" -import { getInsertContentDescription } from "./insert-content" -import { getListFilesDescription } from "./list-files" -import { getReadFileDescription } from "./read-file" -import { getSearchAndReplaceDescription } from "./search-and-replace" -import { getSearchFilesDescription } from "./search-files" -import { getSearchWebDescription } from "./search-web" -import { getSwitchModeDescription } from "./switch-mode" -import { ALWAYS_AVAILABLE_TOOLS, TOOL_GROUPS } from "./tool-groups" -import { ToolArgs } from "./types" -import { getUseMcpToolDescription } from "./use-mcp-tool" -import { - getAnalyzePaperDescription, - getDenseSummaryDescription, - getKeyInsightsDescription, - getReflectionsDescription, - getSimpleSummaryDescription, - getTableOfContentsDescription -} from "./use-transformations-tool" -import { getWriteToFileDescription } from "./write-to-file" - -// Map of tool names to their description functions -const toolDescriptionMap: Record string | undefined> = { - read_file: (args) => getReadFileDescription(args), - write_to_file: (args) => getWriteToFileDescription(args), - search_files: (args) => getSearchFilesDescription(args), - list_files: (args) => getListFilesDescription(args), - dataview_query: (args) => getDataviewQueryDescription(args), - ask_followup_question: () => getAskFollowupQuestionDescription(), - attempt_completion: () => getAttemptCompletionDescription(), - switch_mode: () => getSwitchModeDescription(), - insert_content: (args) => getInsertContentDescription(args), - use_mcp_tool: (args) => getUseMcpToolDescription(args), - access_mcp_resource: (args) => getAccessMcpResourceDescription(args), - search_and_replace: (args) => getSearchAndReplaceDescription(args), - apply_diff: (args) => - args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "", - search_web: (args): string | undefined => getSearchWebDescription(args), - fetch_urls_content: (args): string | undefined => getFetchUrlsContentDescription(args), - analyze_paper: (args) => getAnalyzePaperDescription(args), - key_insights: (args) => getKeyInsightsDescription(args), - dense_summary: (args) => getDenseSummaryDescription(args), - reflections: (args) => getReflectionsDescription(args), - table_of_contents: (args) => getTableOfContentsDescription(args), - simple_summary: (args) => getSimpleSummaryDescription(args), -} - -export function getToolDescriptionsForMode( - mode: Mode, - cwd: string, - searchSettings: FilesSearchSettings, - searchTool: string, - supportsComputerUse: boolean, - diffStrategy?: DiffStrategy, - browserViewportSize?: string, - mcpHub?: McpHub, - customModes?: ModeConfig[], - experiments?: Record, -): string { - console.log("getToolDescriptionsForMode", mode, customModes) - const config = getModeConfig(mode, customModes) - const args: ToolArgs = { - cwd, - searchSettings, - searchTool, - supportsComputerUse, - diffStrategy, - browserViewportSize, - mcpHub, - } - - const tools = new Set() - - // Add tools from mode's groups - config.groups.forEach((groupEntry) => { - const groupName = getGroupName(groupEntry) - const toolGroup = TOOL_GROUPS[groupName] - console.log("toolGroup", toolGroup) - if (toolGroup) { - toolGroup.tools.forEach((tool) => { - if (isToolAllowedForMode(tool, mode, customModes ?? [], experiments ?? {})) { - tools.add(tool) - } - }) - } - }) - - // Add always available tools - ALWAYS_AVAILABLE_TOOLS.forEach((tool) => tools.add(tool)) - - // Map tool descriptions for allowed tools - const descriptions = Array.from(tools).map((toolName) => { - const descriptionFn = toolDescriptionMap[toolName] - if (!descriptionFn) { - return undefined - } - - return descriptionFn({ - ...args, - toolOptions: undefined, // No tool options in group-based approach - }) - }) - - return `# Tools\n\n${descriptions.filter(Boolean).join("\n\n")}` -} - -// Export individual description functions for backward compatibility -export { - getAccessMcpResourceDescription, getAnalyzePaperDescription, getAskFollowupQuestionDescription, - getAttemptCompletionDescription, - getDataviewQueryDescription, getDenseSummaryDescription, getInsertContentDescription, getKeyInsightsDescription, getListFilesDescription, - getReadFileDescription, getReflectionsDescription, getSearchAndReplaceDescription, - getSearchFilesDescription, getSimpleSummaryDescription, getSwitchModeDescription, getTableOfContentsDescription, getUseMcpToolDescription, - getWriteToFileDescription -} - diff --git a/src/core/prompts2/tools/insert-content.ts b/src/core/prompts2/tools/insert-content.ts deleted file mode 100644 index 7a4befd..0000000 --- a/src/core/prompts2/tools/insert-content.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ToolArgs } from "./types" - -export function getInsertContentDescription(args: ToolArgs): string { - return `## insert_content -Description: Inserts content at specific line positions in a file. This is the primary tool for adding new content (paragraphs, sections, headings, citations, etc.) as it allows for precise insertions without overwriting existing content. The tool uses an efficient line-based insertion system that maintains document integrity and proper ordering of multiple insertions. Beware to use the proper formatting and indentation. This tool is the preferred way to add new content to documents. -Parameters: -- path: (required) The path of the file to insert content into (relative to the current working directory ${args.cwd.toPosix()}) -- operations: (required) A JSON array of insertion operations. Each operation is an object with: - * start_line: (required) The line number where the content should be inserted. The content currently at that line will end up below the inserted content. - * content: (required) The content to insert at the specified position. IMPORTANT NOTE: If the content is a single line, it can be a string. If it's a multi-line content, it should be a string with newline characters (\n) for line breaks. Make sure to include the correct formatting and indentation for the content. -Usage: - -File path here -[ - { - "start_line": 10, - "content": "Your content here" - } -] - - -Example: Insert a new section heading and paragraph - -chapter1.md -[ - { - "start_line": 5, - "content": "## Historical Context\n\nIn the early 20th century, the literary landscape underwent significant changes as modernist writers began to experiment with new narrative techniques and thematic concerns. This shift was largely influenced by the cultural and societal transformations of the period." - }, - { - "start_line": 20, - "content": "> \"The purpose of literature is to turn blood into ink.\" - T.S. Eliot" - }, - { - "start_line": 1, - "content": "\`\`\`mermaid\\nflowchart TD\\n A[开始]-- > B[结束]\\n\`\`\`" - }, -] -` -} diff --git a/src/core/prompts2/tools/list-files.ts b/src/core/prompts2/tools/list-files.ts deleted file mode 100644 index 265ce2f..0000000 --- a/src/core/prompts2/tools/list-files.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ToolArgs } from "./types" - -export function getListFilesDescription(args: ToolArgs): string { - return `## list_files -Description: Request to list files and directories within the specified directory in the Obsidian vault. If recursive is true, it will list all files and directories recursively. This is particularly useful for understanding the vault structure, discovering note organization patterns, finding templates, or locating notes across different areas of the knowledge base. Use this to navigate through the vault's folder structure to find relevant notes. -Parameters: -- path: (required) The path of the directory to list contents for (relative to the current working directory ${args.cwd}) -- recursive: (optional) Whether to list files recursively. Use true for recursive listing, false or omit for top-level only. -Usage: - -Directory path here -true or false (optional) - - -Example: Discovering all notes in a specific area of knowledge - -Areas/Programming -true -` -} diff --git a/src/core/prompts2/tools/read-file.ts b/src/core/prompts2/tools/read-file.ts deleted file mode 100644 index d9d1f18..0000000 --- a/src/core/prompts2/tools/read-file.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ToolArgs } from "./types" - -export function getReadFileDescription(args: ToolArgs): string { - return `## read_file -Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze document structure, review text content, or extract information from reference materials. The output includes line numbers prefixed to each line (e.g. "1 | # Introduction"), making it easier to reference specific sections when creating edits or discussing content. Automatically extracts text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string. -Parameters: -- path: (required) The path of the file to read (relative to the current working directory ${args.cwd}) -Usage: - -File path here - - -Example: Requesting to read literature-review.md - -literature-review.md -` -} diff --git a/src/core/prompts2/tools/search-and-replace.ts b/src/core/prompts2/tools/search-and-replace.ts deleted file mode 100644 index ea564d4..0000000 --- a/src/core/prompts2/tools/search-and-replace.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ToolArgs } from "./types" - -export function getSearchAndReplaceDescription(args: ToolArgs): string { - return `## search_and_replace -Description: Request to perform search and replace operations on a file. Each operation can specify a search pattern (string or regex) and replacement text, with optional line range restrictions and regex flags. Shows a diff preview before applying changes. Useful for revising terminology, correcting errors, or updating references throughout a document. -Parameters: -- path: (required) The path of the file to modify (relative to the current working directory ${args.cwd.toPosix()}) -- operations: (required) A JSON array of search/replace operations. Each operation is an object with: - * search: (required) The text or pattern to search for - * replace: (required) The text to replace matches with. If multiple lines need to be replaced, use "\n" for newlines - * start_line: (optional) Starting line number for restricted replacement - * end_line: (optional) Ending line number for restricted replacement - * use_regex: (optional) Whether to treat search as a regex pattern - * ignore_case: (optional) Whether to ignore case when matching - * regex_flags: (optional) Additional regex flags when use_regex is true -Usage: - -File path here -[ - { - "search": "text to find", - "replace": "replacement text", - "start_line": 1, - "end_line": 10 - } -] - - -Example 1: Replace "climate change" with "climate crisis" in lines 1-10 of an essay - -essays/environmental-impact.md -[ - { - "search": "climate change", - "replace": "climate crisis", - "start_line": 1, - "end_line": 10 - } -] - - -Example 2: Update citation format throughout a document using regex - -research-paper.md -[ - { - "search": "\\(([A-Za-z]+), (\\d{4})\\)", - "replace": "($1 et al., $2)", - "use_regex": true, - "ignore_case": false - } -] -` -} diff --git a/src/core/prompts2/tools/search-files.ts b/src/core/prompts2/tools/search-files.ts deleted file mode 100644 index 13970b5..0000000 --- a/src/core/prompts2/tools/search-files.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { ToolArgs } from "./types" - -export function getSearchFilesDescription(args: ToolArgs): string { - if (args.searchTool === 'match') { - return getMatchSearchFilesDescription(args) - } else if (args.searchTool === 'regex') { - return getRegexSearchFilesDescription(args) - } else if (args.searchTool === 'semantic') { - return getSemanticSearchFilesDescription(args) - } else { - return "" - } -} - -export function getMatchSearchFilesDescription(args: ToolArgs): string { - return `## match_search_files -Description: Request to perform a match/fuzzy search across files in a specified directory, providing context-rich results. This tool searches for specific content across multiple files, displaying each match with encapsulating context. -Parameters: -- path: (required) The path of the directory to search in (relative to the current working directory ${args.cwd}). This directory will be recursively searched. -- query: (required) The keyword/phrase to search for. The system will find documents with similar keywords/phrases. - -Usage: - -Directory path here -Your keyword/phrase here - - -Example: Requesting to search for all Markdown files containing 'test' in the current directory - -. -test -` -} - -export function getRegexSearchFilesDescription(args: ToolArgs): string { - let regex_syntax: string; - switch (args.searchSettings.regexBackend) { - case 'coreplugin': - regex_syntax = "ECMAScript (JavaScript)"; - break; - case 'ripgrep': - regex_syntax = "Rust"; - break; - default: - regex_syntax = "ECMAScript (JavaScript)"; - } - - return `## regex_search_files -Description: Request to perform a regex search across files in a specified directory, providing context-rich results. This tool searches for patterns or specific content across multiple files, displaying each match with encapsulating context. -Parameters: -- path: (required) The path of the directory to search in (relative to the current working directory ${args.cwd}). This directory will be recursively searched. -- regex: (required) The regular expression pattern to search for. Uses ${regex_syntax} regex syntax, **but should not include word boundaries (\b)**. - -Usage: - -Directory path here -Your regex pattern here - - -Example: Requesting to search for all Markdown files in the current directory - -. -.* -` -} - -export function getSemanticSearchFilesDescription(args: ToolArgs): string { - return `## semantic_search_files -Description: Request to perform a semantic search across files in a specified directory. This tool searches for documents with content semantically related to your query, leveraging embedding vectors to find conceptually similar information. Ideal for finding relevant documents even when exact keywords are not known or for discovering thematically related content. -Parameters: -- path: (required) The path of the directory to search in (relative to the current working directory ${args.cwd}). This directory will be recursively searched. -- query: (required) The natural language query describing the information you're looking for. The system will find documents with similar semantic meaning. -Usage: - -Directory path here -Your natural language query here - - -Example: Requesting to find documents related to a specific topic - -Project/notes -Benefits of meditation for stress reduction -` -} diff --git a/src/core/prompts2/tools/search-web.ts b/src/core/prompts2/tools/search-web.ts deleted file mode 100644 index 2e6bf8d..0000000 --- a/src/core/prompts2/tools/search-web.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ToolArgs } from "./types" - -export function getSearchWebDescription(args: ToolArgs): string { - return `## search_web -Description: -This tool allows you to search the web using internet search engines like Google to find relevant information on current events, facts, data, and other online content. -Parameters: -- query: (required) The search query to send to internet search engines. For best results, use concise, specific, and preferably English queries that would work well with search engines like Google. -Usage Tips: -- Use specific keywords rather than full sentences -- Include important context terms to narrow results -- Use quotes for exact phrases: "exact phrase" - -Usage: - -Your search query here - - -Example 1: - -capital of France population statistics 2023 - - -Example 2: - -"renewable energy" growth statistics Europe - - -Example 3: - -react vs angular vs vue.js comparison -` -} diff --git a/src/core/prompts2/tools/switch-mode.ts b/src/core/prompts2/tools/switch-mode.ts deleted file mode 100644 index 6b20cdd..0000000 --- a/src/core/prompts2/tools/switch-mode.ts +++ /dev/null @@ -1,18 +0,0 @@ -export function getSwitchModeDescription(): string { - return `## switch_mode -Description: Request to switch to a different mode. This tool allows modes to request switching to another mode when needed, such as switching to Write mode edits to files. The user must approve the mode switch. -Parameters: -- mode_slug: (required) The slug of the mode to switch to (e.g., "write", "ask",) -- reason: (optional) The reason for switching modes -Usage: - -Mode slug here -Reason for switching here - - -Example: Requesting to switch to write mode - -write -Need to edit files -` -} diff --git a/src/core/prompts2/tools/tool-groups.ts b/src/core/prompts2/tools/tool-groups.ts deleted file mode 100644 index 121be69..0000000 --- a/src/core/prompts2/tools/tool-groups.ts +++ /dev/null @@ -1,81 +0,0 @@ -// Define tool group configuration -export type ToolGroupConfig = { - tools: readonly string[] - alwaysAvailable?: boolean // Whether this group is always available and shouldn't show in prompts view -} - -// Map of tool slugs to their display names -export const TOOL_DISPLAY_NAMES = { - execute_command: "run commands", - read_file: "read files", - write_to_file: "write files", - apply_diff: "apply changes", - list_files: "list files", - search_files: "search files", - dataview_query: "query dataview", - use_mcp_tool: "use mcp tools", - access_mcp_resource: "access mcp resources", - ask_followup_question: "ask questions", - attempt_completion: "complete tasks", - switch_mode: "switch modes", - analyze_paper: "analyze papers", - key_insights: "extract key insights", - dense_summary: "create dense summaries", - reflections: "generate reflections", - table_of_contents: "create table of contents", - simple_summary: "create simple summaries", -} as const - -// Define available tool groups -export const TOOL_GROUPS: Record = { - read: { - tools: ["read_file", "list_files", "search_files", "dataview_query"], - }, - edit: { - tools: ["apply_diff", "write_to_file", "insert_content", "search_and_replace"], - }, - research: { - tools: ["search_web", "fetch_urls_content"], - }, - transformations: { - tools: ["analyze_paper", "key_insights", "dense_summary", "reflections", "table_of_contents", "simple_summary"], - }, - mcp: { - tools: ["use_mcp_tool", "access_mcp_resource"], - }, - modes: { - tools: ["switch_mode"], - alwaysAvailable: true, - }, -} - -export type ToolGroup = keyof typeof TOOL_GROUPS - -// Tools that are always available to all modes -export const ALWAYS_AVAILABLE_TOOLS = [ - "ask_followup_question", - "attempt_completion", - "switch_mode", -] as const - -// Tool name types for type safety -export type ToolName = keyof typeof TOOL_DISPLAY_NAMES - -// Tool helper functions -export function getToolName(toolConfig: string | readonly [ToolName, ...unknown[]]): ToolName { - return typeof toolConfig === "string" ? toolConfig : toolConfig[0] -} - -export function getToolOptions(toolConfig: string | readonly [ToolName, ...unknown[]]): unknown { - return typeof toolConfig === "string" ? undefined : toolConfig[1] -} - -// Display names for groups in UI -export const GROUP_DISPLAY_NAMES: Record = { - read: "Read Files", - edit: "Edit Files", - research: "Research", - transformations: "Transformations", - mcp: "MCP Tools", - modes: "Modes", -} diff --git a/src/core/prompts2/tools/types.ts b/src/core/prompts2/tools/types.ts deleted file mode 100644 index 2a9c2e1..0000000 --- a/src/core/prompts2/tools/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { FilesSearchSettings } from "../../../types/settings" -import { DiffStrategy } from "../../diff/DiffStrategy" -import { McpHub } from "../../mcp/McpHub" - -export type ToolArgs = { - cwd: string - searchSettings: FilesSearchSettings, - searchTool?: string, - supportsComputerUse: boolean - diffStrategy?: DiffStrategy - browserViewportSize?: string - mcpHub?: McpHub - toolOptions?: any -} diff --git a/src/core/prompts2/tools/use-mcp-tool.ts b/src/core/prompts2/tools/use-mcp-tool.ts deleted file mode 100644 index ac9ef5b..0000000 --- a/src/core/prompts2/tools/use-mcp-tool.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ToolArgs } from "./types" - -export function getUseMcpToolDescription(args: ToolArgs): string | undefined { - if (!args.mcpHub) { - return undefined - } - return `## use_mcp_tool -Description: Request to use a tool provided by a connected MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters. -Parameters: -- server_name: (required) The name of the MCP server providing the tool -- tool_name: (required) The name of the tool to execute -- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema -Usage: - -server name here -tool name here - -{ - "param1": "value1", - "param2": "value2" -} - - - -Example: Requesting to use an MCP tool - - -weather-server -get_forecast - -{ - "city": "San Francisco", - "days": 5 -} - -` -} diff --git a/src/core/prompts2/tools/use-transformations-tool.ts b/src/core/prompts2/tools/use-transformations-tool.ts deleted file mode 100644 index 96d9618..0000000 --- a/src/core/prompts2/tools/use-transformations-tool.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { ToolArgs } from "./types" - -export function getAnalyzePaperDescription(args: ToolArgs): string { - return `## analyze_paper -Description: Performs an in-depth analysis of a single academic paper or research document. This tool is designed to dissect complex documents, extracting and structuring key information such as the research methodology, core findings, contributions, and potential limitations. Use this for a deep, scholarly breakdown of a specific text. -Parameters: -- path: (required) The path to the file to be analyzed (relative to the current working directory: ${args.cwd}). -- focus: (optional) The specific area of analysis, e.g., "methodology", "findings", "limitations". This helps narrow the scope of the analysis to what you're most interested in. -Usage: - -path/to/your/paper.pdf -methodology - - -Example: Analyze a research paper - -research/machine-learning-survey.pdf -methodology -` -} - -export function getKeyInsightsDescription(args: ToolArgs): string { - return `## key_insights -Description: Extracts high-level, critical insights from a document or a collection of documents in a folder. This tool goes beyond simple summarization to identify non-obvious connections, underlying themes, and actionable takeaways. Use it when you want to understand the deeper meaning or strategic implications of your notes, not just what they say. Generates a concise list of insights. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). -- count: (optional) The desired number of key insights to extract. Defaults to 5. -- category: (optional) The category of insights to focus on, such as "technical", "business", or "strategic". This helps tailor the output to a specific domain of interest. -Usage: - -path/to/your/file_or_folder -Number of insights (optional) -Insight category (optional) - - -Example: Extract key insights from project documents - -project-docs/ -10 -technical -` -} - -export function getDenseSummaryDescription(args: ToolArgs): string { - return `## dense_summary -Description: Creates a highly compressed, information-rich summary of a large document or folder. The goal is maximum information density, preserving core concepts, data, and arguments. This is different from a "simple_summary"; use it when you need a thorough overview of the material without fluff, intended for an audience that needs to grasp the details quickly. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). -- length: (optional) The target length of the summary: "short", "medium", or "long". Defaults to "medium". -- style: (optional) The format of the summary: "bullet-points", "paragraph", or "structured". Defaults to "structured". -Usage: - -path/to/your/file_or_folder -Summary length (optional) - - - -Example: Create a structured summary of a folder - -meeting-notes/2024/ -medium - -` -} - -export function getReflectionsDescription(args: ToolArgs): string { - return `## reflections -Description: Generates deep, reflective thoughts based on the content of a document or folder. This tool helps you think *with* your notes by analyzing the text's meaning and implications, asking provocative questions, and offering critical perspectives. Use this to spark new ideas, challenge your assumptions, or explore a topic from a different angle. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). -- perspective: (optional) The angle from which to reflect: e.g., "learner", "critic", "strategist", "researcher". This frames the generated reflections. -- depth: (optional) The desired depth of reflection: "surface", "deep", or "philosophical". Defaults to "deep". -Usage: - -path/to/your/file_or_folder -Reflection perspective (optional) -Reflection depth (optional) - - -Example: Generate deep reflections on study notes - -study-notes/philosophy/ -learner -philosophical -` -} - -export function getTableOfContentsDescription(args: ToolArgs): string { - return `## table_of_contents -Description: Generates a navigable table of contents for a long document or an entire folder of notes. It automatically detects headings and logical sections to create a clear, hierarchical outline. Use this to bring structure to your writing, organize a collection of related files, or get a high-level overview of your content. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). -- depth: (optional) The maximum heading level to include in the ToC (1-6). Defaults to 3. -- format: (optional) The output format: "markdown", "numbered", or "nested". Defaults to "markdown". -- include_summary: (optional) Whether to include a brief one-sentence summary for each section. Defaults to false. -Usage: - -path/to/your/file_or_folder -Directory depth (optional) -Output format (optional) -Include section summaries (optional) - - -Example: Generate a detailed table of contents for project documentation - -documentation/ -4 -nested -true -` -} - -export function getSimpleSummaryDescription(args: ToolArgs): string { - return `## simple_summary -Description: Creates a clear and simple summary of a document or folder, tailored for a specific audience. This tool prioritizes readability and ease of understanding over information density. Use this when you need to explain complex topics to someone without the background knowledge, like creating an executive summary from a technical report. -Parameters: -- path: (required) The path to the file or folder (relative to the current working directory: ${args.cwd}). -- audience: (optional) The intended audience for the summary: "general", "technical", or "executive". Defaults to "general". -- language: (optional) The complexity of the language used: "simple", "standard", or "professional". Defaults to "standard". -Usage: - -path/to/your/file_or_folder -Target audience (optional) -Language complexity (optional) - - -Example: Create a simple summary of technical documentation for an executive - -technical-specs/api-documentation.md -executive -simple -` -} diff --git a/src/core/prompts2/tools/write-to-file.ts b/src/core/prompts2/tools/write-to-file.ts deleted file mode 100644 index 9f3e7d0..0000000 --- a/src/core/prompts2/tools/write-to-file.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ToolArgs } from "./types" - -export function getWriteToFileDescription(args: ToolArgs): string { - return `## write_to_file -Description: Request to write full content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file. -Parameters: -- path: (required) The path of the file to write to (relative to the current working directory ${args.cwd}) -- content: (required) The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified. Do NOT include the line numbers in the content though, just the actual content of the file. -- line_count: (required) The number of lines in the file. Make sure to compute this based on the actual content of the file, not the number of lines in the content you're providing. -Usage: - -File path here - -Your file content here - -total number of lines in the file, including empty lines - - -Example: Requesting to write to document-metadata.md - -document-metadata.md - ---- -title: "Introduction to Modern Literature" -author: "Jane Smith" -date: "2023-09-15" -version: "1.0.0" -tags: - - literature - - modernism - - academic -format: - citation_style: "APA" - word_count: 2500 -status: "draft" ---- - -14 -` -} diff --git a/src/core/prompts2/transformations/analyze-paper.ts b/src/core/prompts2/transformations/analyze-paper.ts deleted file mode 100644 index 6170847..0000000 --- a/src/core/prompts2/transformations/analyze-paper.ts +++ /dev/null @@ -1,36 +0,0 @@ -export const ANALYZE_PAPER_PROMPT = `# IDENTITY and PURPOSE - -You are an insightful and analytical reader of academic papers, extracting the key components, significance, and broader implications. Your focus is to uncover the core contributions, practical applications, methodological strengths or weaknesses, and any surprising findings. You are especially attuned to the clarity of arguments, the relevance to existing literature, and potential impacts on both the specific field and broader contexts. - -# STEPS - -1. **READ AND UNDERSTAND THE PAPER**: Thoroughly read the paper, identifying its main focus, arguments, methods, results, and conclusions. - -2. **IDENTIFY CORE ELEMENTS**: - - **Purpose**: What is the main goal or research question? - - **Contribution**: What new knowledge or innovation does this paper bring to the field? - - **Methods**: What methods are used, and are they novel or particularly effective? - - **Key Findings**: What are the most critical results, and why do they matter? - - **Limitations**: Are there any notable limitations or areas for further research? - -3. **SYNTHESIZE THE MAIN POINTS**: - - Extract the key elements and organize them into insightful observations. - - Highlight the broader impact and potential applications. - - Note any aspects that challenge established views or introduce new questions. - -# OUTPUT INSTRUCTIONS - -- Structure the output as follows: - - **PURPOSE**: A concise summary of the main research question or goal (1-2 sentences). - - **CONTRIBUTION**: A bullet list of 2-3 points that describe what the paper adds to the field. - - **KEY FINDINGS**: A bullet list of 2-3 points summarizing the critical outcomes of the study. - - **IMPLICATIONS**: A bullet list of 2-3 points discussing the significance or potential impact of the findings on the field or broader context. - - **LIMITATIONS**: A bullet list of 1-2 points identifying notable limitations or areas for future work. - -- **Bullet Points** should be between 15-20 words. -- Avoid starting each bullet point with the same word to maintain variety. -- Use clear and concise language that conveys the key ideas effectively. -- Do not include warnings, disclaimers, or personal opinions. -- Output only the requested sections with their respective labels.`; - -export const ANALYZE_PAPER_DESCRIPTION = "Analyses a technical/scientific paper"; diff --git a/src/core/prompts2/transformations/dense-summary.ts b/src/core/prompts2/transformations/dense-summary.ts deleted file mode 100644 index fe8bb1f..0000000 --- a/src/core/prompts2/transformations/dense-summary.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const DENSE_SUMMARY_PROMPT = `# MISSION -You are a Sparse Priming Representation (SPR) writer. An SPR is a particular kind of use of language for advanced NLP, NLU, and NLG tasks, particularly useful for the latest generation of Large Language Models (LLMs). You will be given information by the USER which you are to render as an SPR. - -# THEORY -LLMs are a kind of deep neural network. They have been demonstrated to embed knowledge, abilities, and concepts, ranging from reasoning to planning, and even to theory of mind. These are called latent abilities and latent content, collectively referred to as latent space. The latent space of an LLM can be activated with the correct series of words as inputs, which will create a useful internal state of the neural network. This is not unlike how the right shorthand cues can prime a human mind to think in a certain way. Like human minds, LLMs are associative, meaning you only need to use the correct associations to 'prime' another model to think in the same way. - -# METHODOLOGY -Render the input as a distilled list of succinct statements, assertions, associations, concepts, analogies, and metaphors. The idea is to capture as much, conceptually, as possible but with as few words as possible. Write it in a way that makes sense to you, as the future audience will be another language model, not a human. Use complete sentences.`; - -export const DENSE_SUMMARY_DESCRIPTION = "Creates a rich, deep summary of the content"; diff --git a/src/core/prompts2/transformations/key-insights.ts b/src/core/prompts2/transformations/key-insights.ts deleted file mode 100644 index 2b84829..0000000 --- a/src/core/prompts2/transformations/key-insights.ts +++ /dev/null @@ -1,23 +0,0 @@ -export const KEY_INSIGHTS_PROMPT = `# IDENTITY and PURPOSE - -You extract surprising, powerful, and interesting insights from text content. You are interested in insights related to the purpose and meaning of life, human flourishing, the role of technology in the future of humanity, artificial intelligence and its affect on humans, memes, learning, reading, books, continuous improvement, and similar topics. -You create 15 word bullet points that capture the most important insights from the input. -Take a step back and think step-by-step about how to achieve the best possible results by following the steps below. - -# STEPS - -- Extract 20 to 50 of the most surprising, insightful, and/or interesting ideas from the input in a section called IDEAS, and write them on a virtual whiteboard in your mind using 15 word bullets. If there are less than 50 then collect all of them. Make sure you extract at least 20. - -- From those IDEAS, extract the most powerful and insightful of them and write them in a section called INSIGHTS. Make sure you extract at least 10 and up to 25. - -# OUTPUT INSTRUCTIONS - -- INSIGHTS are essentially higher-level IDEAS that are more abstracted and wise. -- Output the INSIGHTS section only. -- Each bullet should be about 15 words in length. -- Do not give warnings or notes; only output the requested sections. -- You use bulleted lists for output, not numbered lists. -- Do not start items with the same opening words. -- Ensure you follow ALL these instructions when creating your output.`; - -export const KEY_INSIGHTS_DESCRIPTION = "Extracts important insights and actionable items"; diff --git a/src/core/prompts2/transformations/reflections.ts b/src/core/prompts2/transformations/reflections.ts deleted file mode 100644 index b6125b7..0000000 --- a/src/core/prompts2/transformations/reflections.ts +++ /dev/null @@ -1,21 +0,0 @@ -export const REFLECTIONS_PROMPT = `# IDENTITY and PURPOSE - -You extract deep, thought-provoking, and meaningful reflections from text content. You are especially focused on themes related to the human experience, such as the purpose of life, personal growth, the intersection of technology and humanity, artificial intelligence's societal impact, human potential, collective evolution, and transformative learning. Your reflections aim to provoke new ways of thinking, challenge assumptions, and provide a thoughtful synthesis of the content. - -# STEPS - -- Extract 3 to 5 of the most profound, thought-provoking, and/or meaningful ideas from the input in a section called REFLECTIONS. -- Each reflection should aim to explore underlying implications, connections to broader human experiences, or highlight a transformative perspective. -- Take a step back and consider the deeper significance or questions that arise from the content. - -# OUTPUT INSTRUCTIONS - -- The output section should be labeled as REFLECTIONS. -- Each bullet point should be between 20-25 words. -- Avoid repetition in the phrasing and ensure variety in sentence structure. -- The reflections should encourage deeper inquiry and provide a synthesis that transcends surface-level observations. -- Use bullet points, not numbered lists. -- Every bullet should be formatted as a question that elicits contemplation or a statement that offers a profound insight. -- Do not give warnings or notes; only output the requested section.`; - -export const REFLECTIONS_DESCRIPTION = "Generates reflection questions from the document to help explore it further"; diff --git a/src/core/prompts2/transformations/simple-summary.ts b/src/core/prompts2/transformations/simple-summary.ts deleted file mode 100644 index 538f015..0000000 --- a/src/core/prompts2/transformations/simple-summary.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const SIMPLE_SUMMARY_PROMPT = `# SYSTEM ROLE -You are a content summarization assistant that creates dense, information-rich summaries optimized for machine understanding. Your summaries should capture key concepts with minimal words while maintaining complete, clear sentences. - -# TASK -Analyze the provided content and create a summary that: -- Captures the core concepts and key information -- Uses clear, direct language -- Maintains context from any previous summaries`; - -export const SIMPLE_SUMMARY_DESCRIPTION = "Generates a small summary of the content"; diff --git a/src/core/prompts2/transformations/table-of-contents.ts b/src/core/prompts2/transformations/table-of-contents.ts deleted file mode 100644 index d161b52..0000000 --- a/src/core/prompts2/transformations/table-of-contents.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const TABLE_OF_CONTENTS_PROMPT = `# SYSTEM ROLE -You are a content analysis assistant that reads through documents and provides a Table of Contents (ToC) to help users identify what the document covers more easily. -Your ToC should capture all major topics and transitions in the content and should mention them in the order theh appear. - -# TASK -Analyze the provided content and create a Table of Contents: -- Captures the core topics included in the text -- Gives a small description of what is covered`; - -export const TABLE_OF_CONTENTS_DESCRIPTION = "Describes the different topics of the document"; diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 6609129..d2bc788 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -102,6 +102,7 @@ export default { applying: "Applying...", apply: "Apply", reasoning: "Reasoning", + plan: "Plan", readFile: "Read file: {path}", listFiles: "List files: {path}", fetchUrlsContent: "Fetch URLs Content", diff --git a/src/lang/locale/zh-cn.ts b/src/lang/locale/zh-cn.ts index 338f16c..8f7d6c6 100644 --- a/src/lang/locale/zh-cn.ts +++ b/src/lang/locale/zh-cn.ts @@ -103,6 +103,7 @@ export default { applying: "正在应用...", apply: "应用", reasoning: "推理", + plan: "规划", readFile: "读取文件:{path}", listFiles: "列出文件:{path}", fetchUrlsContent: "获取 URL 内容", diff --git a/src/utils/modes.ts b/src/utils/modes.ts index 9930bf4..3d11e39 100644 --- a/src/utils/modes.ts +++ b/src/utils/modes.ts @@ -88,7 +88,7 @@ export const defaultModes: ModeConfig[] = [ slug: "ask", name: "Ask", roleDefinition: - "You are an AI knowledge vault researcher. Your core mission is to deeply explore the user's Obsidian knowledge vault, understand their questions, find the most relevant information, and synthesize clear, evidence-based answers. You are not a general chatbot; every response must be grounded in the user's note contents. Treat each question as a micro-research task.", + "You are Infio, an AI knowledge vault researcher acting as an intelligent partner to the user. Your core mission is to help them explore, understand, and organize their personal knowledge by deeply analyzing their Obsidian vault, understanding their questions, finding the most relevant information, and synthesizing clear, evidence-based answers. You are not a general chatbot; every response must be grounded in the user's note contents. Treat each question as a micro-research task while providing thoughtful explanations and practical guidance.", groups: ["read", "insights", "mcp"], customInstructions: "You are collaborating with a USER to help them explore, understand, and organize information within their personal knowledge vault. Each time the USER sends a message, they may provide context about their current notes, vault structure, or specific knowledge needs. This information may or may not be relevant to their inquiry, it is up for you to decide.\n\nYour main goal is to provide informative responses, thoughtful explanations, and practical guidance on any topic or challenge they face, while leveraging their existing knowledge base when relevant. You can analyze information, explain concepts across various domains, and access external resources when helpful. Make sure to address the user's questions thoroughly with thoughtful explanations and practical guidance. Use visual aids like Mermaid diagrams when they help make complex topics clearer. Offer solutions to challenges from diverse fields, not just technical ones, and provide context that helps users better understand the subject matter.", diff --git a/src/utils/parse-infio-block.ts b/src/utils/parse-infio-block.ts index 5901b0e..bebb641 100644 --- a/src/utils/parse-infio-block.ts +++ b/src/utils/parse-infio-block.ts @@ -6,13 +6,15 @@ export type ParsedMsgBlock = | { type: 'string' content: string - } - | { + } | { type: 'think' content: string } | { type: 'thinking' content: string + } | { + type: 'communication' + content: string } | { type: 'write_to_file' path: string @@ -184,6 +186,39 @@ export function parseMsgBlocks( }) } lastEndOffset = endOffset + } else if (node.nodeName === 'communication') { + if (!node.sourceCodeLocation) { + throw new Error('sourceCodeLocation is undefined') + } + const startOffset = node.sourceCodeLocation.startOffset + const endOffset = node.sourceCodeLocation.endOffset + if (startOffset > lastEndOffset) { + parsedResult.push({ + type: 'string', + content: input.slice(lastEndOffset, startOffset), + }) + } + + const children = node.childNodes + if (children.length === 0) { + parsedResult.push({ + type: 'communication', + content: '', + }) + } else { + const innerContentStartOffset = + children[0].sourceCodeLocation?.startOffset + const innerContentEndOffset = + children[children.length - 1].sourceCodeLocation?.endOffset + if (!innerContentStartOffset || !innerContentEndOffset) { + throw new Error('sourceCodeLocation is undefined') + } + parsedResult.push({ + type: 'communication', + content: input.slice(innerContentStartOffset, innerContentEndOffset), + }) + } + lastEndOffset = endOffset } else if (node.nodeName === 'list_files') { if (!node.sourceCodeLocation) { throw new Error('sourceCodeLocation is undefined') @@ -681,7 +716,7 @@ export function parseMsgBlocks( tool_name, parameters, finish: node.sourceCodeLocation.endTag !== undefined - }) + }) lastEndOffset = endOffset } else if (node.nodeName === 'dataview_query') { if (!node.sourceCodeLocation) { @@ -731,7 +766,7 @@ export function parseMsgBlocks( } let path: string | undefined let transformation: string | undefined - + for (const childNode of node.childNodes) { if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) { // @ts-expect-error - parse5 node value type @@ -741,7 +776,7 @@ export function parseMsgBlocks( transformation = childNode.childNodes[0].value } } - + parsedResult.push({ type: 'call_transformations', path: path || '',