update workspace

This commit is contained in:
duanfuxiang
2025-06-27 22:08:36 +08:00
parent 0df4e4edd3
commit 772270863c
86 changed files with 6988 additions and 1156 deletions

114
src/utils/dataview.ts Normal file
View File

@@ -0,0 +1,114 @@
import { App } from "obsidian";
import { DataviewApi, getAPI } from "obsidian-dataview";
export interface DataviewQueryResult {
success: boolean;
data?: string;
error?: string;
}
export class DataviewManager {
private app: App;
constructor(app: App) {
this.app = app;
}
/**
* 获取 Dataview API 实例(动态获取,确保插件已加载)
*/
private getAPI(): DataviewApi | null {
try {
const api = getAPI(this.app) as DataviewApi | null;
return api;
} catch (error) {
console.error('获取 Dataview API 失败:', error);
return null;
}
}
/**
* 检查 Dataview 插件是否可用
*/
isDataviewAvailable(): boolean {
const api = this.getAPI();
return api !== null && api !== undefined;
}
/**
* 执行 Dataview 查询
*/
async executeQuery(query: string): Promise<DataviewQueryResult> {
const api = this.getAPI();
if (!api) {
return {
success: false,
error: "Dataview 插件未安装或未启用"
};
}
try {
// 使用 Dataview 的查询引擎
const result = await api.queryMarkdown(query, "", {});
// 检查 Result 对象的结构
if (result && typeof result === 'object' && 'successful' in result) {
if (result.successful) {
return {
success: true,
data: String(result.value || '')
};
} else {
return {
success: false,
error: String(result.error || '查询失败')
};
}
}
// 如果不是 Result 对象,直接处理
return {
success: true,
data: this.formatQueryResult(result)
};
} catch (error) {
console.error('Dataview 查询执行失败:', error);
return {
success: false,
error: error instanceof Error ? error.message : '未知错误'
};
}
}
/**
* 格式化查询结果(备用方法)
*/
private formatQueryResult(result: unknown): string {
if (result === null || result === undefined) {
return '查询结果为空';
}
// 如果是字符串,直接返回
if (typeof result === 'string') {
return result;
}
// 尝试 JSON 序列化
if (typeof result === 'object') {
try {
return JSON.stringify(result, null, 2);
} catch (e) {
return `对象结果(无法序列化): ${Object.prototype.toString.call(result)}`;
}
}
// 其他类型,转换为字符串
return String(result);
}
}
// 导出一个全局实例创建函数
export function createDataviewManager(app: App): DataviewManager {
return new DataviewManager(app);
}

View File

@@ -69,7 +69,11 @@ export function getToolsForMode(groups: readonly GroupEntry[]): string[] {
groups.forEach((group) => {
const groupName = getGroupName(group)
const groupConfig = TOOL_GROUPS[groupName]
groupConfig.tools.forEach((tool: string) => tools.add(tool))
if (groupConfig) {
groupConfig.tools.forEach((tool: string) => tools.add(tool))
} else {
console.warn(`Tool group '${groupName}' not found in TOOL_GROUPS`)
}
})
// Always add required tools
@@ -84,28 +88,37 @@ export const defaultModes: ModeConfig[] = [
slug: "ask",
name: "Ask",
roleDefinition:
"You are Infio, a versatile assistant dedicated to providing informative responses, thoughtful explanations, and practical guidance on virtually any topic or challenge you face.",
groups: ["read", "mcp"],
"You are Infio, an AI knowledge assistant powered by advanced language models. You operate within Obsidian.",
groups: ["read", "transformations", "mcp"],
customInstructions:
"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.",
"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.",
},
{
slug: "write",
name: "Write",
roleDefinition:
"You are Infio, a versatile content creator skilled in composing, editing, and organizing various text-based documents. You excel at structuring information clearly, creating well-formatted content, and helping users express their ideas effectively.",
"You are Infio, an AI writing assistant powered by advanced language models. You operate within Obsidian.",
groups: ["read", "edit", "mcp"],
customInstructions:
"You can create and modify any text-based files, with particular expertise in Markdown formatting. Help users organize their thoughts, create documentation, take notes, or draft any written content they need. When appropriate, suggest structural improvements and formatting enhancements that make content more readable and accessible. Consider the purpose and audience of each document to provide the most relevant assistance."
"You are collaborating with a USER to help them create, edit, and organize various types of written content within their knowledge vault. Each time the USER sends a message, they may provide context about their current documents, writing goals, or organizational needs. This information may or may not be relevant to their writing task, it is up for you to decide.\n\nYour main goal is to help them express their ideas effectively through well-structured, clearly formatted content that integrates seamlessly with their existing knowledge system. You can create and modify any text-based files, with particular expertise in Markdown formatting. Help users organize their thoughts, create documentation, take notes, or draft any written content they need. When appropriate, suggest structural improvements and formatting enhancements that make content more readable and accessible. Consider the purpose and audience of each document to provide the most relevant assistance."
},
{
slug: "learn",
name: "Learn",
roleDefinition:
"You are Infio, an AI learning assistant powered by advanced language models. You operate within Obsidian.",
groups: ["read", "transformations", "mcp"],
customInstructions:
"You are collaborating with a USER to enhance their learning experience within their knowledge vault. Each time the USER sends a message, they may provide context about their learning materials, study goals, or knowledge gaps. This information may or may not be relevant to their learning journey, it is up for you to decide.\n\nYour main goal is to help them actively learn and understand complex topics by transforming information into more digestible formats, creating connections between concepts, and facilitating deep comprehension. You excel at breaking down complex topics into manageable chunks, creating study materials like flashcards and summaries, and helping users build comprehensive understanding through structured learning approaches. Generate visual learning aids like concept maps and flowcharts using Mermaid diagrams when they enhance comprehension. Create organized study materials including key concepts, definitions, and practice questions. Help users connect new information to their existing knowledge base by identifying relationships and patterns across their notes. Focus on active learning techniques that promote retention and understanding rather than passive information consumption."
},
{
slug: "research",
name: "Research",
roleDefinition:
"You are Infio, an advanced research assistant specialized in comprehensive investigation and analytical thinking. You excel at breaking down complex questions, exploring multiple perspectives, and synthesizing information to provide well-reasoned conclusions.",
"You are Infio, an AI research assistant powered by advanced language models. You operate within Obsidian.",
groups: ["research", "mcp"],
customInstructions:
"You can conduct thorough research by analyzing available information, connecting related concepts, and applying structured reasoning methods. Help users explore topics in depth by considering multiple angles, identifying relevant evidence, and evaluating the reliability of sources. Use step-by-step analysis when tackling complex problems, explaining your thought process clearly. Create visual representations like Mermaid diagrams when they help clarify relationships between ideas. Use Markdown tables to present statistical data or comparative information when appropriate. Present balanced viewpoints while highlighting the strength of evidence behind different conclusions.",
"You are collaborating with a USER to conduct comprehensive research and analytical thinking within their knowledge vault. Each time the USER sends a message, they may provide context about their research questions, existing notes, or analytical needs. This information may or may not be relevant to their research, it is up for you to decide.\n\nYour main goal is to help them break down complex questions, explore multiple perspectives, and synthesize information to reach well-reasoned conclusions while building upon their existing knowledge base. You can conduct thorough research by analyzing available information, connecting related concepts, and applying structured reasoning methods. Help users explore topics in depth by considering multiple angles, identifying relevant evidence, and evaluating the reliability of sources. Use step-by-step analysis when tackling complex problems, explaining your thought process clearly. Create visual representations like Mermaid diagrams when they help clarify relationships between ideas. Use Markdown tables to present statistical data or comparative information when appropriate. Present balanced viewpoints while highlighting the strength of evidence behind different conclusions.",
},
]
@@ -208,6 +221,12 @@ export function isToolAllowedForMode(
const groupConfig = TOOL_GROUPS[groupName]
// If the group config doesn't exist, skip this group
if (!groupConfig) {
console.warn(`Tool group '${groupName}' not found in TOOL_GROUPS`)
continue
}
// If the tool isn't in this group's tools, continue to next group
if (!groupConfig.tools.includes(tool)) {
continue

View File

@@ -1,4 +1,4 @@
// @ts-nocheck
// @ts-expect-error - parse5 and JSON5 types are not perfectly aligned with the dynamic parsing logic
import JSON5 from 'json5'
import { parseFragment } from 'parse5'
@@ -93,9 +93,41 @@ export type ParsedMsgBlock =
tool_name: string
parameters: Record<string, unknown>,
finish: boolean
} | {
type: 'dataview_query'
query: string
outputFormat: string
finish: boolean
} | {
type: 'tool_result'
content: string
} | {
type: 'analyze_paper'
path: string
finish: boolean
} | {
type: 'key_insights'
path: string
finish: boolean
} | {
type: 'dense_summary'
path: string
finish: boolean
} | {
type: 'reflections'
path: string
finish: boolean
} | {
type: 'table_of_contents'
path: string
depth?: number
format?: string
include_summary?: boolean
finish: boolean
} | {
type: 'simple_summary'
path: string
finish: boolean
}
export function parseMsgBlocks(
@@ -191,8 +223,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'recursive' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
const recursiveValue = childNode.childNodes[0].value
recursive = recursiveValue ? recursiveValue.toLowerCase() === 'true' : false
}
@@ -220,6 +254,7 @@ export function parseMsgBlocks(
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
@@ -248,8 +283,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'query' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
query = childNode.childNodes[0].value
}
}
@@ -278,8 +315,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'regex' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
regex = childNode.childNodes[0].value
}
}
@@ -308,8 +347,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'query' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
query = childNode.childNodes[0].value
}
}
@@ -339,13 +380,15 @@ export function parseMsgBlocks(
// 处理子标签
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'content' && childNode.childNodes.length > 0) {
// 如果内容有多个子节点,需要合并它们
content = childNode.childNodes.map(n => n.value || '').join('')
content = childNode.childNodes.map(n => (n as any).value || '').join('')
} else if (childNode.nodeName === 'line_count' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
const lineCountStr = childNode.childNodes[0].value
lineCount = lineCountStr ? parseInt(lineCountStr) : undefined
lineCount = lineCountStr ? parseInt(lineCountStr as string) : undefined
}
}
parsedResult.push({
@@ -375,11 +418,13 @@ export function parseMsgBlocks(
// 处理子标签
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'operations' && childNode.childNodes.length > 0) {
try {
// @ts-expect-error - parse5 node value type
const operationsJson = childNode.childNodes[0].value
const operations = JSON5.parse(operationsJson)
const operations = JSON5.parse(operationsJson as string)
if (Array.isArray(operations) && operations.length > 0) {
const operation = operations[0]
startLine = operation.start_line || 1
@@ -417,12 +462,13 @@ export function parseMsgBlocks(
// 处理子标签
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'operations' && childNode.childNodes.length > 0) {
try {
// @ts-ignore
// @ts-expect-error - parse5 node value type
content = childNode.childNodes[0].value
operations = JSON5.parse(content)
operations = JSON5.parse(content as string)
} catch (error) {
console.error('Failed to parse operations JSON', error)
}
@@ -454,10 +500,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-ignore
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'diff' && childNode.childNodes.length > 0) {
// @ts-ignore
// @ts-expect-error - parse5 node value type
diff = childNode.childNodes[0].value
}
}
@@ -484,7 +530,7 @@ export function parseMsgBlocks(
let result: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'result' && childNode.childNodes.length > 0) {
// @ts-ignore
// @ts-expect-error - parse5 node value type
result = childNode.childNodes[0].value
}
}
@@ -509,7 +555,7 @@ export function parseMsgBlocks(
let question: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'question' && childNode.childNodes.length > 0) {
// @ts-ignore
// @ts-expect-error - parse5 node value type
question = childNode.childNodes[0].value
}
}
@@ -537,10 +583,10 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'mode_slug' && childNode.childNodes.length > 0) {
// @ts-ignore - 忽略 value 属性的类型错误
// @ts-expect-error - parse5 node value type
mode = childNode.childNodes[0].value
} else if (childNode.nodeName === 'reason' && childNode.childNodes.length > 0) {
// @ts-ignore - 忽略 value 属性的类型错误
// @ts-expect-error - parse5 node value type
reason = childNode.childNodes[0].value
}
}
@@ -567,7 +613,7 @@ export function parseMsgBlocks(
let query: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'query' && childNode.childNodes.length > 0) {
// @ts-ignore
// @ts-expect-error - parse5 node value type
query = childNode.childNodes[0].value
}
}
@@ -595,9 +641,9 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'urls' && childNode.childNodes.length > 0) {
try {
// @ts-ignore
// @ts-expect-error - parse5 node value type
const urlsJson = childNode.childNodes[0].value
const parsedUrls = JSON5.parse(urlsJson)
const parsedUrls = JSON5.parse(urlsJson as string)
if (Array.isArray(parsedUrls)) {
urls = parsedUrls
}
@@ -632,19 +678,19 @@ export function parseMsgBlocks(
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'server_name' && childNode.childNodes.length > 0) {
// @ts-expect-error - 忽略 value 属性的类型错误
// @ts-expect-error - parse5 node value type
server_name = childNode.childNodes[0].value
} else if (childNode.nodeName === 'tool_name' && childNode.childNodes.length > 0) {
// @ts-expect-error - 忽略 value 属性的类型错误
// @ts-expect-error - parse5 node value type
tool_name = childNode.childNodes[0].value
} else if ((childNode.nodeName === 'parameters'
|| childNode.nodeName === 'input'
|| childNode.nodeName === 'arguments')
&& childNode.childNodes.length > 0) {
try {
// @ts-expect-error - 忽略 value 属性的类型错误
// @ts-expect-error - parse5 node value type
const parametersJson = childNode.childNodes[0].value
parameters = JSON5.parse(parametersJson)
parameters = JSON5.parse(parametersJson as string)
} catch (error) {
console.debug('Failed to parse parameters JSON', error)
}
@@ -659,6 +705,209 @@ export function parseMsgBlocks(
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'dataview_query') {
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),
})
}
let query: string = ''
let outputFormat: string = 'table'
// 解析子节点
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'query' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
query = childNode.childNodes[0].value || ''
} else if (childNode.nodeName === 'output_format' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
outputFormat = childNode.childNodes[0].value || 'table'
}
}
parsedResult.push({
type: 'dataview_query',
query,
outputFormat,
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'analyze_paper') {
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),
})
}
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
parsedResult.push({
type: 'analyze_paper',
path: path || '',
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'key_insights') {
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),
})
}
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
parsedResult.push({
type: 'key_insights',
path: path || '',
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'dense_summary') {
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),
})
}
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
parsedResult.push({
type: 'dense_summary',
path: path || '',
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'reflections') {
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),
})
}
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
parsedResult.push({
type: 'reflections',
path: path || '',
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'table_of_contents') {
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),
})
}
let path: string | undefined
let depth: number | undefined
let format: string | undefined
let include_summary: boolean | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
} else if (childNode.nodeName === 'depth' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
const depthStr = childNode.childNodes[0].value
depth = depthStr ? parseInt(depthStr as string) : undefined
} else if (childNode.nodeName === 'format' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
format = childNode.childNodes[0].value
} else if (childNode.nodeName === 'include_summary' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
const summaryValue = childNode.childNodes[0].value
include_summary = summaryValue ? (summaryValue as string).toLowerCase() === 'true' : false
}
}
parsedResult.push({
type: 'table_of_contents',
path: path || '',
depth,
format,
include_summary,
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'simple_summary') {
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),
})
}
let path: string | undefined
for (const childNode of node.childNodes) {
if (childNode.nodeName === 'path' && childNode.childNodes.length > 0) {
// @ts-expect-error - parse5 node value type
path = childNode.childNodes[0].value
}
}
parsedResult.push({
type: 'simple_summary',
path: path || '',
finish: node.sourceCodeLocation.endTag !== undefined
})
lastEndOffset = endOffset
} else if (node.nodeName === 'tool_result') {
if (!node.sourceCodeLocation) {
throw new Error('sourceCodeLocation is undefined')

View File

@@ -12,20 +12,24 @@ export const TOOL_DISPLAY_NAMES = {
apply_diff: "apply changes",
search_files: "search files",
list_files: "list files",
// list_code_definition_names: "list definitions",
browser_action: "use a browser",
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",
new_task: "create new task",
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<string, ToolGroupConfig> = {
read: {
tools: ["read_file", "list_files", "search_files"],
tools: ["read_file", "list_files", "search_files", "dataview_query"],
},
edit: {
tools: ["apply_diff", "write_to_file", "insert_content", "search_and_replace"],
@@ -33,12 +37,9 @@ export const TOOL_GROUPS: Record<string, ToolGroupConfig> = {
research: {
tools: ["search_web", "fetch_urls_content"],
},
// browser: {
// tools: ["browser_action"],
// },
// command: {
// tools: ["execute_command"],
// },
transformations: {
tools: ["analyze_paper", "key_insights", "dense_summary", "reflections", "table_of_contents", "simple_summary"],
},
mcp: {
tools: ["use_mcp_tool", "access_mcp_resource"],
},