From 1bf571d63f835c6701d4ee48c253b0102b781b43 Mon Sep 17 00:00:00 2001 From: Logan Yang Date: Sun, 15 Mar 2026 23:30:05 -0700 Subject: [PATCH] fix(tools): daily note template workflow for past/future dates (#2304) * fix(tools): improve daily note template workflow for past/future dates Update prompt instructions for creating past/future daily notes to use template:read for template content, with a fallback to ask the user for the template path if the Templates plugin isn't configured. Co-Authored-By: Claude Opus 4.6 (1M context) * fix(tools): list templates before reading in daily note workflow The workflow told the agent to call template:read directly without the required name argument. Now it explicitly lists templates first to discover the name, then passes it to template:read. Co-Authored-By: Claude Opus 4.6 (1M context) * fix(tools): route task queries to obsidianTasks instead of localSearch Add explicit prompt instruction to always use obsidianTasks for task queries, not localSearch. For time-based task queries, use verbose mode and filter by file dates. localSearch searches note content but doesn't understand markdown checkbox semantics. Co-Authored-By: Claude Opus 4.6 (1M context) * fix(tools): reduce reasoning noise and fix tasks schema hint Skip redundant success reasoning steps (e.g. "Listed vault tasks" after "Listing vault tasks"). Only show result steps on failure or when they add info (search source counts). Also fix tasks tool schema: the LLM kept guessing command="list" instead of "tasks" because z.literal lacked a clear hint. Added 'Must be exactly "tasks"' to the description. Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- src/LLMProviders/chainRunner/AutonomousAgentChainRunner.ts | 7 +++++-- src/tools/ObsidianCliTools.ts | 4 +++- src/tools/builtinTools.ts | 5 ++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/LLMProviders/chainRunner/AutonomousAgentChainRunner.ts b/src/LLMProviders/chainRunner/AutonomousAgentChainRunner.ts index a195dd8f..9086fc19 100644 --- a/src/LLMProviders/chainRunner/AutonomousAgentChainRunner.ts +++ b/src/LLMProviders/chainRunner/AutonomousAgentChainRunner.ts @@ -869,9 +869,12 @@ export class AutonomousAgentChainRunner extends CopilotPlusChainRunner { } } - // Add tool result step (shown in rolling display - this is the "what was found") + // Add tool result step only when it provides new info (failure or source counts). + // Skip redundant success steps like "Listed vault tasks" after "Listing vault tasks". const resultSummary = summarizeToolResult(tc.name, result, sourceInfo, toolCall.args); - this.addReasoningStep(resultSummary, tc.name); + if (!result.success || sourceInfo) { + this.addReasoningStep(resultSummary, tc.name); + } // Add ToolMessage to conversation const toolMessage = createToolResultMessage( diff --git a/src/tools/ObsidianCliTools.ts b/src/tools/ObsidianCliTools.ts index 15861e32..4a37b18b 100644 --- a/src/tools/ObsidianCliTools.ts +++ b/src/tools/ObsidianCliTools.ts @@ -141,7 +141,9 @@ export const obsidianPropertiesTool = createLangChainTool({ // --------------------------------------------------------------------------- const tasksSchema = z.object({ - command: z.literal("tasks").describe("List tasks across the vault with optional filters."), + command: z + .literal("tasks") + .describe('Must be exactly "tasks". Lists tasks across the vault with optional filters.'), file: z.string().optional().describe("Filter tasks by file name."), path: z.string().optional().describe("Filter tasks by vault-relative file path."), todo: z.boolean().optional().describe("Show only incomplete (todo) tasks."), diff --git a/src/tools/builtinTools.ts b/src/tools/builtinTools.ts index 5600a0ed..30d717fe 100644 --- a/src/tools/builtinTools.ts +++ b/src/tools/builtinTools.ts @@ -348,6 +348,7 @@ export function registerCliTools(): void { - daily:path — get the vault-relative file path (useful for follow-up readNote calls). - daily:append and daily:prepend also auto-create the daily note if it doesn't exist, but do NOT apply the template. - Use \\n for newlines and \\t for tabs in content strings. +- For past or future daily notes (e.g. "yesterday's daily note"): NEVER ask the user for the date — use the time tools. Workflow: (1) call getCurrentTime to resolve the date, (2) call daily:path to discover the date format and folder, (3) call obsidianTemplates with command=templates to list available template names, then call template:read with the name that matches (e.g. "Daily Note Template"), (4) use writeToFile to create the note at the resolved path with the template content, replacing variables like {{date}} with the target date. If templates returns an error or no daily template is found, ask the user for their template path and use readNote to read it. - For arbitrary file writes beyond daily notes, use writeToFile or replaceInFile instead. - If the user names a specific vault, pass it using the vault parameter.`, }, @@ -396,13 +397,15 @@ export function registerCliTools(): void { category: "cli", requiresVault: true, customPromptInstructions: `For obsidianTasks: +- ALWAYS use this tool when the user asks about tasks, todos, or checkboxes. Do NOT use localSearch for task queries. - Use to list and filter tasks across the vault. - todo=true: show only incomplete tasks. done=true: show only completed tasks. - status="x": filter by specific status character (e.g., "/" for in-progress, "x" for done, " " for open). - daily=true: show tasks from today's daily note only. - verbose=true: group tasks by file with line numbers. - total=true: return only the task count. -- file= resolves like a wikilink (name only). path= uses exact vault-relative path.`, +- file= resolves like a wikilink (name only). path= uses exact vault-relative path. +- For time-based task queries (e.g. "tasks from last month"): use verbose=true to get tasks grouped by file, then filter results by file dates or daily note filenames to match the time range.`, }, });