@mastra/core
Version:
1 lines • 8.69 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["z","createNotificationSignal","createTool"],"sources":["../../src/notifications/tool.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { createTool } from '../tools';\nimport type { ToolExecutionContext } from '../tools';\nimport { createNotificationSignal } from './signals';\nimport type { NotificationsStorage } from './storage';\nimport type { ListNotificationsInput, NotificationRecord, NotificationStatus } from './types';\n\nconst notificationActionSchema = z.object({\n action: z.enum(['list', 'read', 'markSeen', 'dismiss', 'archive', 'search']),\n threadId: z.string().optional(),\n id: z.string().optional(),\n status: z.enum(['pending', 'delivered', 'seen', 'dismissed', 'archived', 'discarded', 'failed']).optional(),\n priority: z.enum(['low', 'medium', 'high', 'urgent']).optional(),\n source: z.string().optional(),\n query: z.string().optional(),\n limit: z.number().int().positive().optional(),\n});\n\ntype NotificationInboxAction = z.infer<typeof notificationActionSchema>;\n\ntype NotificationToolAgent = {\n sendSignal: (\n signal: ReturnType<typeof createNotificationSignal>,\n target: { resourceId: string; threadId: string },\n ) => { signal: ReturnType<typeof createNotificationSignal>; persisted?: Promise<void> };\n};\n\nconst isReadable = (notification: NotificationRecord) =>\n notification.status === 'pending' || notification.status === 'delivered';\n\nasync function deliverNotifications({\n notifications,\n storage,\n context,\n}: {\n notifications: NotificationRecord[];\n storage: NotificationsStorage;\n context: ToolExecutionContext;\n}) {\n let delivered = 0;\n let markedSeen = 0;\n let unavailable = 0;\n let alreadyRead = 0;\n\n for (const notification of notifications) {\n if (!isReadable(notification)) {\n alreadyRead += 1;\n continue;\n }\n\n const agentId = notification.agentId ?? context?.agent?.agentId;\n const resourceId = notification.resourceId ?? context?.agent?.resourceId;\n const mastra = context?.mastra;\n const agent =\n agentId && typeof mastra?.getAgentById === 'function' ? await mastra.getAgentById(agentId) : undefined;\n\n if (agent && resourceId && !notification.deliveredSignalId) {\n const signal = createNotificationSignal({ ...notification, status: 'delivered' });\n const result = (agent as NotificationToolAgent).sendSignal(signal, {\n resourceId,\n threadId: notification.threadId,\n });\n await result.persisted;\n await storage.updateNotification({\n threadId: notification.threadId,\n id: notification.id,\n status: 'seen',\n deliveredSignalId: result.signal.id,\n });\n delivered += 1;\n continue;\n }\n\n if (notification.deliveredSignalId) {\n await storage.updateNotification({ threadId: notification.threadId, id: notification.id, status: 'seen' });\n markedSeen += 1;\n } else {\n unavailable += 1;\n }\n }\n\n const message =\n delivered > 0\n ? `${delivered} notification${delivered === 1 ? '' : 's'} will now be delivered.`\n : 'No unread notifications needed delivery.';\n\n return { message, delivered, markedSeen, unavailable, alreadyRead };\n}\n\nexport function createNotificationInboxTool({ storage }: { storage: NotificationsStorage }) {\n return createTool({\n id: 'notification-inbox',\n description:\n 'Inspect and manage the current thread notification inbox. Use this to list pending notifications, read full details after a summary, mark notifications seen, dismiss, archive, or search old notifications.',\n inputSchema: notificationActionSchema,\n execute: async (input: NotificationInboxAction, context) => {\n const threadId = input.threadId ?? context?.agent?.threadId;\n if (!threadId) {\n throw new Error('notification-inbox requires a threadId');\n }\n\n if (input.action === 'list') {\n const listInput: ListNotificationsInput = {\n threadId,\n status: input.status,\n priority: input.priority,\n source: input.source,\n limit: input.limit,\n };\n return { notifications: await storage.listNotifications(listInput) };\n }\n\n if (input.action === 'search') {\n if (!input.query) throw new Error('notification-inbox search requires query');\n return {\n notifications: await storage.listNotifications({\n threadId,\n search: input.query,\n status: input.status,\n priority: input.priority,\n source: input.source,\n limit: input.limit,\n }),\n };\n }\n\n if (input.action === 'read') {\n const notifications = input.id\n ? [await storage.getNotification({ threadId, id: input.id })]\n : await storage.listNotifications({\n threadId,\n status: input.status ?? ['pending', 'delivered'],\n priority: input.priority,\n source: input.source,\n limit: input.limit,\n });\n if (input.id && !notifications[0])\n throw new Error(`Notification ${input.id} was not found for thread ${threadId}`);\n return deliverNotifications({\n notifications: notifications.filter((notification): notification is NotificationRecord =>\n Boolean(notification),\n ),\n storage,\n context,\n });\n }\n\n if (!input.id) throw new Error(`notification-inbox ${input.action} requires id`);\n const statusByAction = {\n markSeen: 'seen',\n dismiss: 'dismissed',\n archive: 'archived',\n } satisfies Record<'markSeen' | 'dismiss' | 'archive', NotificationStatus>;\n\n return {\n notification: await storage.updateNotification({\n threadId,\n id: input.id,\n status: statusByAction[input.action],\n }),\n };\n },\n });\n}\n"],"mappings":"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"}