feat: add journal entry update, disable, append, prepend tools

Four new tools for full journal entry lifecycle management:

- ae_journal_entry_update  — PATCH any combination of fields (title,
  content, summary, tags, enable); only provided fields are changed
- ae_journal_entry_disable — soft-delete via enable=false
- ae_journal_entry_append  — fetch entry, append timestamped section
  to the bottom (ideal for running logs / data logs)
- ae_journal_entry_prepend — fetch entry, prepend timestamped section
  to the top (most-recent-first pattern)

Shared _get_entry / _patch_entry helpers keep the read-modify-write
logic DRY. Also fixed journal_entry_create to prefer the canonical
journal_entry_id field over the legacy id_random alias.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-04-28 22:02:22 -04:00
parent 44f215c764
commit ed191cf0b4
2 changed files with 251 additions and 3 deletions

View File

@@ -17,8 +17,12 @@ IMPORTANT: These tools are separate from the ae_* MCP tools used by the fleet ag
from google.genai import types
from tools.web import search as _web_search
from tools.ae_knowledge import journal_search as _ae_journal_search
from tools.ae_knowledge import journal_entry_create as _ae_journal_entry_create
from tools.ae_knowledge import journal_list as _ae_journal_list
from tools.ae_knowledge import journal_entry_create as _ae_journal_entry_create
from tools.ae_knowledge import journal_entry_update as _ae_journal_entry_update
from tools.ae_knowledge import journal_entry_disable as _ae_journal_entry_disable
from tools.ae_knowledge import journal_entry_append as _ae_journal_entry_append
from tools.ae_knowledge import journal_entry_prepend as _ae_journal_entry_prepend
from tools.ae_tasks import task_list as _ae_task_list
from tools.files import file_read as _file_read
from tools.system import claude_allow_dir as _claude_allow_dir, shell_exec as _shell_exec
@@ -148,6 +152,79 @@ _ae_journal_entry_create_declaration = types.FunctionDeclaration(
),
)
_ae_journal_entry_update_declaration = types.FunctionDeclaration(
name="ae_journal_entry_update",
description=(
"Update fields on an existing journal entry. Only the fields you provide are changed — "
"omitted fields are left as-is. Use ae_journal_search to find the entry_id first. "
"To soft-delete, use ae_journal_entry_disable instead."
),
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"entry_id": types.Schema(type=types.Type.STRING, description="Journal entry id_random"),
"title": types.Schema(type=types.Type.STRING, description="New title"),
"content": types.Schema(type=types.Type.STRING, description="Replacement content (full, markdown supported)"),
"summary": types.Schema(type=types.Type.STRING, description="New summary"),
"tags": types.Schema(type=types.Type.STRING, description="Replacement comma-separated tags"),
"enable": types.Schema(type=types.Type.BOOLEAN, description="Set false to hide/disable the entry"),
},
required=["entry_id"],
),
)
_ae_journal_entry_disable_declaration = types.FunctionDeclaration(
name="ae_journal_entry_disable",
description=(
"Soft-delete a journal entry by setting enable=false. "
"The entry is hidden but not permanently removed. "
"Use ae_journal_search to find the entry_id first."
),
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"entry_id": types.Schema(type=types.Type.STRING, description="Journal entry id_random"),
},
required=["entry_id"],
),
)
_ae_journal_entry_append_declaration = types.FunctionDeclaration(
name="ae_journal_entry_append",
description=(
"Append a new section to the bottom of a journal entry's content. "
"Each section gets a UTC timestamp heading unless you provide one. "
"Ideal for timestamped logs, running notes, or data logs."
),
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"entry_id": types.Schema(type=types.Type.STRING, description="Journal entry id_random"),
"content": types.Schema(type=types.Type.STRING, description="The text to append (markdown supported)"),
"heading": types.Schema(type=types.Type.STRING, description="Optional section heading (defaults to current UTC timestamp)"),
},
required=["entry_id", "content"],
),
)
_ae_journal_entry_prepend_declaration = types.FunctionDeclaration(
name="ae_journal_entry_prepend",
description=(
"Prepend a new section to the top of a journal entry's content. "
"Each section gets a UTC timestamp heading unless you provide one. "
"Useful for most-recent-first logs."
),
parameters=types.Schema(
type=types.Type.OBJECT,
properties={
"entry_id": types.Schema(type=types.Type.STRING, description="Journal entry id_random"),
"content": types.Schema(type=types.Type.STRING, description="The text to prepend (markdown supported)"),
"heading": types.Schema(type=types.Type.STRING, description="Optional section heading (defaults to current UTC timestamp)"),
},
required=["entry_id", "content"],
),
)
_ae_task_list_declaration = types.FunctionDeclaration(
name="ae_task_list",
description=(
@@ -202,6 +279,10 @@ _CALLABLES: dict[str, callable] = {
"ae_journal_list": _ae_journal_list,
"ae_journal_search": _ae_journal_search,
"ae_journal_entry_create": _ae_journal_entry_create,
"ae_journal_entry_update": _ae_journal_entry_update,
"ae_journal_entry_disable": _ae_journal_entry_disable,
"ae_journal_entry_append": _ae_journal_entry_append,
"ae_journal_entry_prepend": _ae_journal_entry_prepend,
"ae_task_list": _ae_task_list,
"file_read": _file_read,
"claude_allow_dir": _claude_allow_dir,
@@ -567,6 +648,10 @@ TOOL_DECLARATIONS = [
_ae_journal_list_declaration,
_ae_journal_search_declaration,
_ae_journal_entry_create_declaration,
_ae_journal_entry_update_declaration,
_ae_journal_entry_disable_declaration,
_ae_journal_entry_append_declaration,
_ae_journal_entry_prepend_declaration,
_ae_task_list_declaration,
_file_read_declaration,
_claude_allow_dir_declaration,