From 1266b583e4cf865a06ebd28ff853f6f4c42c1344 Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 16 Apr 2026 12:00:17 +0200 Subject: [PATCH] feat(ai-tools): unlock create_note + create_journal_entry + habit tools for agents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the three biggest tool-coverage gaps so the shipped agent templates can actually do their job end-to-end. Before this, the Recherche-Agent couldn't create notes (only edit), the Today-Agent couldn't create journal entries, and no habit-related tool was server-proposable at all. shared-ai (proposable-tools.ts): - create_note (notes) — key unlock: Recherche-Agent now creates per-source notes and the summary report. - create_journal_entry (journal) — key unlock: Today-Agent proposes a poem as a journal entry with optional mood. - create_habit (habits) — agent can suggest new habits. - log_habit (habits) — agent can log a habit completion for today. Organized the list with per-module section comments for readability now that we're at 15 proposable tools. mana-ai (planner/tools.ts): - 5 new tool definitions with full parameter schemas: * create_note (title, content?) * create_journal_entry (content, title?, mood? enum) * create_habit (title, icon, color) * log_habit (habitId, note?) - Drift-guard contract test passes (41/41) — confirms the mana-ai tool list is in sync with the shared-ai canonical set. Webapp (policy.ts): - get_habits added to AUTO_TOOLS (read-only; agent can inspect which habits exist without nagging the user for approval). - list_notes added to AUTO_TOOLS (was already used in the reasoning loop but missing from the explicit auto-list; the planner default fell through to 'propose' which was wasteful for a read op). Module coverage after this change: ✅ todo (5 tools) ✅ calendar (2) ✅ notes (5 incl. create) ✅ places (4) ✅ drink (3) ✅ food (2) ✅ news (1) ✅ journal (1) ✅ habits (3) Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/mana/apps/web/src/lib/data/ai/policy.ts | 2 + .../shared-ai/src/policy/proposable-tools.ts | 12 ++++ services/mana-ai/src/planner/tools.ts | 62 +++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/apps/mana/apps/web/src/lib/data/ai/policy.ts b/apps/mana/apps/web/src/lib/data/ai/policy.ts index e5bf0132f..e3292b5e1 100644 --- a/apps/mana/apps/web/src/lib/data/ai/policy.ts +++ b/apps/mana/apps/web/src/lib/data/ai/policy.ts @@ -41,11 +41,13 @@ export interface AiPolicy { const AUTO_TOOLS: Record = { get_task_stats: 'auto', list_tasks: 'auto', + list_notes: 'auto', get_todays_events: 'auto', get_drink_progress: 'auto', nutrition_summary: 'auto', get_places: 'auto', location_log: 'auto', + get_habits: 'auto', // Append-only self-state logs: AI proposing "did you drink water?" + // user confirming + AI logging it should not require a second approval. log_drink: 'auto', diff --git a/packages/shared-ai/src/policy/proposable-tools.ts b/packages/shared-ai/src/policy/proposable-tools.ts index c86e35040..d40974a4e 100644 --- a/packages/shared-ai/src/policy/proposable-tools.ts +++ b/packages/shared-ai/src/policy/proposable-tools.ts @@ -17,17 +17,29 @@ */ export const AI_PROPOSABLE_TOOL_NAMES = [ + // ── Todo ────────────────────────────────── 'create_task', 'complete_task', 'complete_tasks_by_title', + // ── Calendar ────────────────────────────── 'create_event', + // ── Places ──────────────────────────────── 'create_place', 'visit_place', + // ── Drink ───────────────────────────────── 'undo_drink', + // ── News ────────────────────────────────── 'save_news_article', + // ── Notes ───────────────────────────────── + 'create_note', 'update_note', 'append_to_note', 'add_tag_to_note', + // ── Journal ─────────────────────────────── + 'create_journal_entry', + // ── Habits ──────────────────────────────── + 'create_habit', + 'log_habit', ] as const; export type AiProposableToolName = (typeof AI_PROPOSABLE_TOOL_NAMES)[number]; diff --git a/services/mana-ai/src/planner/tools.ts b/services/mana-ai/src/planner/tools.ts index 7f5a794ea..291e81497 100644 --- a/services/mana-ai/src/planner/tools.ts +++ b/services/mana-ai/src/planner/tools.ts @@ -146,6 +146,68 @@ export const AI_AVAILABLE_TOOLS: readonly AvailableTool[] = [ }, ], }, + + // ── Notes: create ──────────────────────────────────────── + { + name: 'create_note', + module: 'notes', + description: 'Erstellt eine neue Notiz. Gibt die ID der angelegten Notiz zurueck.', + parameters: [ + { name: 'title', type: 'string', description: 'Titel der Notiz', required: true }, + { + name: 'content', + type: 'string', + description: 'Inhalt der Notiz (Markdown)', + required: false, + }, + ], + }, + + // ── Journal ────────────────────────────────────────────── + { + name: 'create_journal_entry', + module: 'journal', + description: + 'Erstellt einen neuen Tagebuch-Eintrag fuer den heutigen Tag. Gibt die ID zurueck.', + parameters: [ + { + name: 'content', + type: 'string', + description: 'Inhalt des Eintrags (Markdown)', + required: true, + }, + { name: 'title', type: 'string', description: 'Optionaler Titel', required: false }, + { + name: 'mood', + type: 'string', + description: 'Stimmung', + required: false, + enum: ['great', 'good', 'neutral', 'bad', 'terrible'], + }, + ], + }, + + // ── Habits ─────────────────────────────────────────────── + { + name: 'create_habit', + module: 'habits', + description: 'Erstellt einen neuen Habit-Tracker. Gibt die ID des neuen Habits zurueck.', + parameters: [ + { name: 'title', type: 'string', description: 'Titel des Habits', required: true }, + { name: 'icon', type: 'string', description: 'Emoji-Icon', required: true }, + { name: 'color', type: 'string', description: 'Hex-Farbe (z.B. #EF4444)', required: true }, + ], + }, + { + name: 'log_habit', + module: 'habits', + description: + 'Loggt eine Ausfuehrung eines existierenden Habits fuer heute. Optional mit Notiz.', + parameters: [ + { name: 'habitId', type: 'string', description: 'ID des Habits', required: true }, + { name: 'note', type: 'string', description: 'Optionale Notiz zum Log', required: false }, + ], + }, ]; export const AI_AVAILABLE_TOOL_NAMES = new Set(AI_AVAILABLE_TOOLS.map((t) => t.name));