- Force notification summaries to avoid markdown formatting - Normalize generated notification text before system display - Cover plain-text notification formatting with tests
6.3 KiB
6.3 KiB
Notifications Module Documentation
Purpose
This module provides notification message preparation utilities for the web server runtime, including text truncation, plain-text normalization, and optional message summarization for system notifications.
Entrypoints and structure
packages/web/server/lib/notifications/index.js: public entrypoint imported bypackages/web/server/index.js.packages/web/server/lib/notifications/routes.js: route registration for push, visibility, and session status/attention endpoints.packages/web/server/lib/notifications/push-runtime.js: push subscription persistence, VAPID initialization, and UI visibility runtime.packages/web/server/lib/notifications/emitter-runtime.js: desktop/stdout + UI SSE notification emission runtime.packages/web/server/lib/notifications/runtime.js: trigger runtime for OpenCode event-driven notification fanout.packages/web/server/lib/notifications/template-runtime.js: notification template variables, zen-model helpers, and session text/title enrichment runtime.packages/web/server/lib/notifications/message.js: helper implementation module.packages/web/server/lib/notifications/message.test.js: unit tests for notification message helpers.
Public exports
Notifications API (re-exported from message.js)
truncateNotificationText(text, maxLength): Truncates text to specified max length, appending...if truncated.prepareNotificationLastMessage({ message, settings, summarize }): Prepares the last message for notification display, with optional summarization support.
Route registration API (routes.js)
registerNotificationRoutes(app, dependencies): Registers notification-owned endpoints:GET /api/push/vapid-public-keyPOST /api/push/subscribeDELETE /api/push/subscribePOST /api/push/visibilityGET /api/push/visibilityGET /api/session-activityGET /api/sessions/snapshotGET /api/sessions/statusGET /api/sessions/:id/statusGET /api/sessions/attentionGET /api/sessions/:id/attentionPOST /api/sessions/:id/viewPOST /api/sessions/:id/unviewPOST /api/sessions/:id/message-sent
Trigger runtime API (runtime.js)
createNotificationTriggerRuntime(dependencies): creates runtime-owned debounced trigger handling for OpenCode events.- Returned API:
maybeSendPushForTrigger(payload)
- Owns:
- completion/error/question/permission trigger routing
- session parent cache for subtask suppression
- template resolution and fallback behavior
- native notification fanout and web push payload fanout
Push runtime API (push-runtime.js)
createPushRuntime(dependencies): creates runtime for web push and UI visibility state.- Returned API:
getOrCreateVapidKeys()ensurePushInitialized()setPushInitialized(value)addOrUpdatePushSubscription(uiSessionToken, subscription, userAgent)removePushSubscription(uiSessionToken, endpoint)sendPushToAllUiSessions(payload, options?)updateUiVisibility(token, visible)isAnyUiVisible()isUiVisible(token)
Emitter runtime API (emitter-runtime.js)
createNotificationEmitterRuntime(dependencies): creates runtime for unified notification emission channels.- Returned API:
writeSseEvent(res, payload)emitDesktopNotification(payload)broadcastUiNotification(payload)
Template runtime API (template-runtime.js)
createNotificationTemplateRuntime(dependencies): creates shared notification/template + zen helper runtime.- Returned API:
resolveNotificationTemplate(template, variables)shouldApplyResolvedTemplateMessage(template, resolved, variables)fetchFreeZenModels()resolveZenModel(override)validateZenModelAtStartup()summarizeText(text, targetLength, zenModel)extractLastMessageText(payload, maxLength?)fetchLastAssistantMessageText(sessionId, messageId, maxLength?)maybeCacheSessionInfoFromEvent(payload)buildTemplateVariables(payload, sessionId)getCachedZenModels()
Constants
Default values
DEFAULT_NOTIFICATION_MESSAGE_MAX_LENGTH: 250 (default max length for notification text).DEFAULT_NOTIFICATION_SUMMARY_THRESHOLD: 200 (minimum message length to trigger summarization).DEFAULT_NOTIFICATION_SUMMARY_LENGTH: 100 (target length for summarized messages).
Settings object format
The settings parameter for prepareNotificationLastMessage supports:
summarizeLastMessage(boolean): Whether to enable summarization for long messages.summaryThreshold(number): Minimum message length to trigger summarization (default: 200).summaryLength(number): Target length for summarized messages (default: 100).maxLastMessageLength(number): Maximum length for the final notification text (default: 250).
Response contracts
truncateNotificationText
- Returns empty string for non-string input.
- Returns original text if under max length.
- Returns
${text.slice(0, maxLength)}...for truncated text.
prepareNotificationLastMessage
- Returns empty string for empty/null message.
- Returns truncated original message if summarization disabled, message under threshold, or summarization fails.
- Returns truncated summary if summarization succeeds and returns non-empty string.
- Normalizes markdown-like formatting to plain text before truncation.
- Always applies
maxLastMessageLengthtruncation to final result.
Notes for contributors
Adding new notification helpers
- Add new helper functions to
packages/web/server/lib/notifications/message.js. - Export functions that are intended for public use.
- Follow existing patterns for input validation (e.g., type checking for strings).
- Use
resolvePositiveNumberfor numeric parameters with fallbacks to maintain safe defaults. - Add corresponding unit tests in
packages/web/server/lib/notifications/message.test.js.
Error handling
prepareNotificationLastMessagecatches summarization errors and falls back to original message.- Invalid numeric parameters default to safe fallback values.
- Non-string inputs are handled gracefully (return empty string).
Testing
- Run
bun run type-check,bun run lint, andbun run buildbefore finalizing changes. - Unit tests should cover truncation behavior, summarization success/failure, and edge cases (empty strings, invalid inputs).