Skip to content

Notification Tools

The AI assistant (Vernis) can view and manage notifications on behalf of the user through four tools. These run in the assistant’s chat context — not during voice calls or task execution.

ToolPermission RequiredPurpose
get_notificationsNotification:Collection:ListList notifications with filters
get_unread_countNotification:Collection:ListGet unread notification count
mark_notification_readNotification:Instance:MarkReadMark a single notification as read
mark_all_notifications_readNotification:Instance:MarkReadMark all notifications as read

Tools are registered in collect_assistant_tools in tool_registry_service.rs. The registry checks the user’s session permissions and only includes tools the user is authorized to use:

// List/count tools — need Collection:List
if can_list_notifications {
tools.push(build_get_notifications_tool(session.clone()));
tools.push(build_get_unread_count_tool(session.clone()));
}
// Mark-read tools — need Instance:MarkRead
if can_mark_notifications_read {
tools.push(build_mark_notification_read_tool(session.clone()));
tools.push(build_mark_all_notifications_read_tool(session.clone()));
}

The system prompt’s capabilities section is also updated dynamically — bold markers flag write operations so the AI knows to use confirmation flows.

Lists the user’s notifications with optional filters.

Input:

ParameterTypeDefaultDescription
categoryOption<String>NoneFilter: "call", "task", "task_completed", "plan", "system"
unread_onlyOption<bool>NoneWhen true, only unread notifications
time_rangeString"all_time""today", "yesterday", "last_7_days", "last_30_days", "last_90_days", "all_time"
limitOption<u64>20Results per page (1–50)
offsetOption<u64>0Pagination offset

Response:

{
"notifications": [
{
"id": "a1b2c3d4-...",
"category": "task",
"title": "New task assigned",
"body": "Follow up with client about proposal",
"entity_type": "task",
"entity_id": "e5f6a7b8-...",
"entity_deep_link": "/tasks/e5f6a7b8-...",
"is_read": false,
"created_at": "2026-03-28 14:30:00"
}
],
"count": 1,
"total_count": 42,
"notifications_page": "/notifications"
}

Each notification includes an entity_deep_link generated by page_context_mapper::entity_deep_link — this lets the assistant point users to the relevant page.

Returns the number of unread notifications. No parameters.

{
"unread_count": 7,
"notifications_page": "/notifications"
}

Marks a single notification as read using a two-step confirmation pattern.

Input:

ParameterTypeDescription
idStringNotification UUID
confirmedboolfalse = preview, true = execute

Preview response (confirmed: false):

{
"action": "mark_notification_read",
"status": "preview",
"preview": {
"id": "a1b2c3d4-...",
"title": "New task assigned",
"category": "task",
"created_at": "2026-03-28 14:30:00"
},
"message": "Ready to mark notification 'New task assigned' as read. Call again with confirmed=true to proceed."
}

Execution response (confirmed: true):

{
"action": "mark_notification_read",
"status": "completed",
"notification_id": "a1b2c3d4-...",
"notifications_page": "/notifications",
"message": "Notification 'New task assigned' marked as read."
}

If the notification is already read, returns status: "already_read" without requiring confirmation.

Marks all unread notifications as read. Same two-step confirmation pattern.

Input:

ParameterTypeDescription
confirmedboolfalse = preview with unread count, true = execute

Preview response:

{
"action": "mark_all_notifications_read",
"status": "preview",
"preview": { "unread_count": 7 },
"message": "Ready to mark 7 notification(s) as read. Call again with confirmed=true to proceed."
}

Uses Entity::update_many() to batch-update all unread notifications in a single query.

The write tools (mark_notification_read, mark_all_notifications_read) follow Loquent’s standard confirmation pattern for destructive assistant actions:

  1. Preview call (confirmed: false) — returns what will happen without making changes
  2. The AI presents the preview to the user and asks for approval
  3. Execute call (confirmed: true) — performs the action

This pattern is signaled to the AI via bold markers in the system prompt capabilities section, ensuring the assistant always asks before modifying data.

FilePurpose
src/mods/assistant/tools/notifications/mod.rsModule exports
src/mods/assistant/tools/notifications/ai_get_notifications_tool.rsList tool
src/mods/assistant/tools/notifications/ai_get_unread_count_tool.rsCount tool
src/mods/assistant/tools/notifications/ai_mark_notification_read_tool.rsSingle mark-read
src/mods/assistant/tools/notifications/ai_mark_all_notifications_read_tool.rsBulk mark-read
src/mods/assistant/services/tool_registry_service.rsRegistration logic
src/mods/assistant/services/build_system_prompt_service.rsSystem prompt integration