import { ChatElement, Emoji, CardElement } from 'chat'; import { A as Awaitable } from './util.types-DaFfsxgy.cjs'; type AgentErrorDelivery = { statusCode: number; responseBody: string; }; type AgentErrorOptions = { cause?: unknown; delivery?: AgentErrorDelivery; }; /** Turn and handler failures. Delivery failures use {@link AgentDeliveryError}. */ declare class AgentError extends Error { readonly cause?: unknown; readonly delivery?: AgentErrorDelivery; constructor(message: string, options?: AgentErrorOptions); } /** * Thrown by `ctx.reply()` and `handle.edit()` when the upstream message delivery * fails — e.g. the configured email provider returns 401, Slack rejects the token, * or Teams rejects the request. * * @example * ```ts * import { AgentDeliveryError } from '@novu/framework'; * * try { * await ctx.reply('Hello!'); * } catch (err) { * if (err instanceof AgentDeliveryError) { * console.error('Delivery failed:', err.message, err.statusCode); * return; * } * throw err; * } * ``` */ declare class AgentDeliveryError extends AgentError { readonly statusCode: number; readonly responseBody: string; constructor(statusCode: number, responseBody: string); } declare function toAgentError(err: unknown): AgentError; declare enum ChannelTypeEnum { IN_APP = "in_app", EMAIL = "email", SMS = "sms", CHAT = "chat", PUSH = "push", TOOL = "tool" } interface IAttachmentOptions { mime: string; file: Buffer; name?: string; channels?: ChannelTypeEnum[]; cid?: string; disposition?: string; } interface ITriggerPayload { attachments?: IAttachmentOptions[]; [key: string]: string | string[] | boolean | number | undefined | IAttachmentOptions | IAttachmentOptions[] | Record; } interface ISubscriberPayload { subscriberId: string; firstName?: string; lastName?: string; email?: string; phone?: string; avatar?: string; locale?: string; data?: Record; channels?: ISubscriberChannel[]; } interface ISubscriberChannel { providerId: ChatProviderIdEnum | PushProviderIdEnum; integrationIdentifier?: string; credentials: IChannelCredentials; } interface IChannelCredentials { webhookUrl?: string; deviceTokens?: string[]; } interface ITopic { type: 'Topic'; topicKey: string; exclude?: string[]; } type TriggerRecipientsPayload = string | ISubscriberPayload | ITopic | ISubscriberPayload[] | ITopic[]; declare enum TriggerEventStatusEnum { ERROR = "error", NOT_ACTIVE = "trigger_not_active", NO_WORKFLOW_ACTIVE_STEPS = "no_workflow_active_steps_defined", NO_WORKFLOW_STEPS = "no_workflow_steps_defined", PROCESSED = "processed", SUBSCRIBER_MISSING = "subscriber_id_missing", TENANT_MISSING = "no_tenant_found" } declare enum ChatProviderIdEnum { Slack = "slack", Discord = "discord", MsTeams = "msteams", WebexMessaging = "webex-messaging", Mattermost = "mattermost", Ryver = "ryver", Zulip = "zulip", GrafanaOnCall = "grafana-on-call", GetStream = "getstream", RocketChat = "rocket-chat", WhatsAppBusiness = "whatsapp-business", Line = "line", ChatWebhook = "chat-webhook", Novu = "novu-slack", Telegram = "telegram", Sendblue = "sendblue", NovuWebChat = "novu-web-chat" } declare enum PushProviderIdEnum { FCM = "fcm", APNS = "apns", EXPO = "expo", OneSignal = "one-signal", Pushpad = "pushpad", PushWebhook = "push-webhook", PusherBeams = "pusher-beams", AppIO = "appio" } /** * A preference for a notification delivery workflow. * * This provides a shortcut to setting all channels to the same preference. */ type WorkflowPreference = { /** * A flag specifying if notification delivery is enabled for the workflow. * * If `true`, notification delivery is enabled by default for all channels. * * This setting can be overridden by the channel preferences. * * @default true */ enabled: boolean; /** * A flag specifying if the preference is read-only. * * If `true`, the preference cannot be changed by the Subscriber. * * @default false */ readOnly: boolean; }; /** A preference for a notification delivery channel. */ type ChannelPreference = { /** * A flag specifying if notification delivery is enabled for the channel. * * If `true`, notification delivery is enabled. * * @default true */ enabled: boolean; }; type WorkflowPreferences = { /** * A preference for the workflow. * * The values specified here will be used if no preference is specified for a channel. */ all: WorkflowPreference; /** * A preference for each notification delivery channel. * * If no preference is specified for a channel, the `all` preference will be used. */ channels: Record; }; /** * Recursively make all properties of type `T` optional. */ type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial; } : T; /** A partial set of workflow preferences. */ type WorkflowPreferencesPartial = DeepPartial; type Verdict = 'approve' | 'deny'; interface ToolApprovalRequestPayload { approvalId: string; toolCallId: string; name: string; input?: Record; } interface ParsedApprovalAction { approved: boolean; approvalId: string; } declare function buildApprovalActionId(verdict: Verdict, approvalId: string): string; declare function parseApprovalActionId(id: string | undefined): ParsedApprovalAction | null; declare enum AgentEventEnum { ON_MESSAGE = "onMessage", ON_ACTION = "onAction", ON_RESOLVE = "onResolve", ON_REACTION = "onReaction" } type HumanInteractionKind = 'ask' | 'approve' | 'choose' | 'tell'; type HumanAskApproveOptions = { /** Attribution label shown to the human (e.g. `"deploy-bot"`). */ from?: string; /** Time until the request expires, in seconds (max 72h; default 24h). */ ttlSeconds?: number; /** * Novu `subscriberId`(s) allowed to settle this request. First valid answer * wins. When omitted, the conversation's first subscriber participant is used. * The maximum number of subscribers is 50. */ to?: string | string[]; }; type HumanChooseOptions = HumanAskApproveOptions; type HumanTellOptions = { /** Attribution label shown to the human (e.g. `"deploy-bot"`). */ from?: string; /** * Novu `subscriberId`(s) this notice is addressed to. In-thread delivery * still posts one card on the current conversation. */ to?: string | string[]; }; /** * Outcome of a `ctx.ask` / `ctx.approve` / `ctx.choose` request, attached to * the later `onMessage` (ask) or `onAction` (approve / choose) turn. */ type AgentHumanResponse = { /** Client-minted id returned by `ctx.ask` / `ctx.approve` / `ctx.choose`. */ requestId: string; /** Public interaction identifier (`hi_...`). */ interactionId: string; kind: HumanInteractionKind; /** Terminal status: `answered` | `approved` | `denied` | `expired` | `canceled` | `delivered`. */ status: string; /** True when the TTL elapsed before a valid answer. Do not treat `text` / `optionId` as a verdict. */ expired: boolean; /** Freeform reply text for `ask`. */ text?: string; /** `approve`: `'approve'` | `'deny'`; `choose`: the picked option id. */ optionId?: string; respondedBy?: string; /** Stable Novu subscriberId of whoever settled the interaction. */ respondedBySubscriberId?: string; }; /** Identity of the user or bot that authored a message. */ interface AgentMessageAuthor { userId: string; fullName: string; userName: string; isBot: boolean | 'unknown'; } /** A file or media attachment included with a message. */ interface AgentAttachment { type: string; url?: string; name?: string; mimeType?: string; size?: number; } /** An incoming message from the user in the current conversation. */ interface AgentMessage { /** Plain-text content of the message. */ text: string; /** Platform-native message ID (e.g. Slack `ts`, Teams `activityId`). */ platformMessageId: string; author: AgentMessageAuthor; timestamp: string; attachments?: AgentAttachment[]; } /** Live state of the current conversation thread. */ interface AgentConversation { /** Stable identifier for this conversation. */ identifier: string; /** Lifecycle status (e.g. `'open'`, `'resolved'`). */ status: string; /** * Key/value store for this conversation. * Values are written via `ctx.metadata.set()` and readable on subsequent messages. */ metadata: Record; /** Number of messages exchanged so far; starts at 1 for the first message. */ messageCount: number; createdAt: string; lastActivityAt: string; } /** * A single connect-time context value: either a bare string id, or a rich object with an `id` * and arbitrary `data`. Mirrors Novu's `ContextValue`. */ type AgentContextValue = string | { id: string; data?: Record; }; /** * Connect-time context bound to the channel connection and resolved server-side for the current * turn. * * Populated by Novu from the context an integrator passes to the Connect button (e.g. the Slack * connect flow persists it on the `ChannelConnection`). It lets a single hosted agent serve many * tenants: the agent reads its own tenant/org out of the context to scope writes. Keys are * integrator-defined context types (e.g. `tenant`), mirroring Novu's `ContextPayload`. */ type AgentContextPayload = Record; /** The Novu subscriber who initiated or is participating in the conversation. */ interface AgentSubscriber { /** Stable Novu subscriber ID. */ subscriberId: string; firstName?: string; lastName?: string; email?: string; phone?: string; avatar?: string; locale?: string; /** Arbitrary custom data attached to the subscriber in Novu. */ data?: Record; } /** Workflow-origin notification for this turn. */ interface AgentNotification = Record> { id: string; /** User-facing workflow slug — same string as `ctx.trigger(workflowId)`. */ workflowId: string; messageId: string; platformMessageId: string; sentAt: string; body: string; payload: TPayload; } /** * Tool-call details on a tool-related history entry. Which fields are set depends on the * entry's `type` (`tool_approval_request`, `tool_approval_decision`, or `tool_result`). */ interface AgentToolData { /** Id of the tool call. */ toolCallId?: string; /** Name of the tool. */ toolName?: string; /** Id linking an approval request to its decision. */ approvalId?: string; /** Arguments the tool was called with. */ input?: Record; /** Whether the tool call was approved or denied. */ approved?: boolean; /** What the tool returned (or the `execution-denied` marker for a denied call). */ output?: unknown; } /** * A single entry in the conversation history. * `ctx.history` is an ordered array of these entries — map them to your LLM's * message format before making a model call. */ interface AgentHistoryEntry { /** Message role: `'user'`, `'assistant'`, or `'system'`. */ role: string; /** * The kind of entry: `'message'`, `'edit'`, `'signal'`, or a tool-lifecycle event * (`'tool_approval_request'`, `'tool_approval_decision'`, `'tool_result'`). */ type: string; /** Plain-text representation of the message content. */ content: string; richContent?: Record; senderName?: string; /** Structured data for `signal` entries (e.g. metadata updates). */ signalData?: { type: string; payload?: Record; }; /** Tool-call details — set on tool-lifecycle entries (`tool_*`). */ toolData?: AgentToolData; createdAt: string; } /** Resolved inbound email domain metadata (present when `platform === 'email'`). */ interface AgentEmailDomainContext { id: string; name: string; data?: Record; } /** Resolved inbound email route metadata (present when `platform === 'email'`). */ interface AgentEmailRouteContext { address: string; data?: Record; } /** Resolved inbound email envelope (present when `platform === 'email'`). */ interface AgentEmailContext { domain?: AgentEmailDomainContext; route?: AgentEmailRouteContext; /** * Platform-native Message-ID of the message that started this email thread. * Equals the current message ID on the first message of a thread. */ rootMessageId?: string; } /** Platform-specific identifiers for the thread and channel. */ interface AgentPlatformContext { /** Platform-native thread ID (e.g. Slack thread `ts`, Teams conversation ID). */ threadId: string; /** Platform-native channel or chat ID. */ channelId: string; /** Whether the message arrived in a direct message rather than a shared channel. */ isDM: boolean; /** Platform-native raw message payload from the chat SDK adapter (e.g. email `NovuEmailRawMessage`). */ message?: unknown; /** Resolved inbound email routing metadata extracted from the raw payload. */ email?: AgentEmailContext; } interface FileRef { filename: string; mimeType?: string; /** * Inline file data. Binary values are encoded to base64 before being sent to Novu. * Node Buffers are supported because Buffer extends Uint8Array. * * Limit: <= 5 MB decoded. Use `url` for larger files. */ data?: string | Uint8Array | ArrayBuffer | Blob; /** * Publicly-accessible HTTP(S) URL. Recommended for larger files. * * Server-side limits: 25 MB per file, 15 files per message, 50 MB aggregate. */ url?: string; } /** * Content accepted by ctx.reply() and handle.edit(). * * - `string` — plain text or markdown; converted to platform format by the chat SDK * - `ChatElement` — interactive card built with Card(), Button(), etc. * * For file attachments, pass a `files` array as the second argument to reply()/edit(). * Cards and files can be combined on platforms that support it (e.g. WhatsApp sends media then the card). */ type MessageContent = string | ChatElement; /** Normalized content shape sent over HTTP to the reply endpoint. */ interface ReplyContent { markdown?: string; card?: CardElement; toolApprovalCard?: ToolApprovalCard; files?: FileRef[]; } /** * Data carried by a button click or other interactive action. * * Used both on the bridge wire (`AgentBridgeRequest.action`) and as the * handler-facing argument passed to `onAction(action, ctx)`. */ interface AgentAction { /** The `id` prop of the clicked `