@novu/framework 2.11.1 → 2.11.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -9
- package/ai-sdk/package.json +4 -0
- package/cards/package.json +4 -0
- package/dist/{esm/index-D6L0Yufw.d.ts → cjs/agent.types-DdgaVUb7.d.cts} +356 -193
- package/dist/cjs/ai-sdk/index.cjs +1 -0
- package/dist/cjs/ai-sdk/index.d.cts +39 -0
- package/dist/cjs/cards.cjs +57 -0
- package/dist/cjs/cards.d.cts +2 -0
- package/dist/cjs/{health-check.types-D4NEyjyC.d.cts → health-check.types-CkUmYLNG.d.cts} +6 -140
- package/dist/cjs/index-BCp3U0UG.d.cts +189 -0
- package/dist/cjs/index.cjs +138 -138
- package/dist/cjs/index.d.cts +5 -3
- package/dist/cjs/internal/index.cjs +1 -1
- package/dist/cjs/internal/index.d.cts +96 -4
- package/dist/cjs/jsx-dev-runtime.cjs +1 -1
- package/dist/cjs/jsx-runtime.cjs +1 -1
- package/dist/cjs/langchain/index.cjs +1 -0
- package/dist/cjs/langchain/index.d.cts +105 -0
- package/dist/cjs/servers/express.cjs +137 -137
- package/dist/cjs/servers/express.d.cts +6 -4
- package/dist/cjs/servers/h3.cjs +136 -136
- package/dist/cjs/servers/h3.d.cts +6 -4
- package/dist/cjs/servers/lambda.cjs +137 -137
- package/dist/cjs/servers/lambda.d.cts +6 -5
- package/dist/cjs/servers/nest.cjs +136 -136
- package/dist/cjs/servers/nest.d.cts +21 -7
- package/dist/cjs/servers/next.cjs +138 -138
- package/dist/cjs/servers/next.d.cts +6 -4
- package/dist/cjs/servers/nuxt.cjs +136 -136
- package/dist/cjs/servers/nuxt.d.cts +6 -4
- package/dist/cjs/servers/remix.cjs +138 -138
- package/dist/cjs/servers/remix.d.cts +6 -4
- package/dist/cjs/servers/sveltekit.cjs +136 -136
- package/dist/cjs/servers/sveltekit.d.cts +6 -4
- package/dist/cjs/step-resolver.d.cts +3 -2
- package/dist/cjs/{subscriber.types-PRaHFLJu.d.cts → subscriber.types-DxMMRBIi.d.cts} +2 -78
- package/dist/cjs/util.types-DaFfsxgy.d.cts +78 -0
- package/dist/{cjs/index-BNiIiOE-.d.cts → esm/agent.types-Bu3DhlVb.d.ts} +356 -193
- package/dist/esm/ai-sdk/index.d.ts +39 -0
- package/dist/esm/ai-sdk/index.js +1 -0
- package/dist/esm/cards.d.ts +2 -0
- package/dist/esm/cards.js +1 -0
- package/dist/esm/{chunk-KLCBNFAF.js → chunk-3XT6S7TZ.js} +14 -14
- package/dist/esm/chunk-3ZWME5KT.js +0 -0
- package/dist/esm/chunk-C3P3ZH2I.js +36 -0
- package/dist/esm/chunk-FHYMHX3T.js +1 -0
- package/dist/esm/chunk-KLIOXJR3.js +1 -0
- package/dist/esm/chunk-W6DIBD4Z.js +1 -0
- package/dist/esm/chunk-YF62BBGH.js +98 -0
- package/dist/esm/{health-check.types-C-81VaBO.d.ts → health-check.types-nDCnGlmX.d.ts} +6 -140
- package/dist/esm/index-DEehllqa.d.ts +189 -0
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/internal/index.d.ts +96 -4
- package/dist/esm/internal/index.js +1 -1
- package/dist/esm/jsx-dev-runtime.js +1 -1
- package/dist/esm/jsx-runtime-7EPQR56T.js +1 -0
- package/dist/esm/jsx-runtime.js +1 -1
- package/dist/esm/langchain/index.d.ts +105 -0
- package/dist/esm/langchain/index.js +1 -0
- package/dist/esm/servers/express.d.ts +6 -4
- package/dist/esm/servers/express.js +1 -1
- package/dist/esm/servers/h3.d.ts +6 -4
- package/dist/esm/servers/h3.js +1 -1
- package/dist/esm/servers/lambda.d.ts +6 -5
- package/dist/esm/servers/lambda.js +1 -1
- package/dist/esm/servers/nest.d.ts +21 -7
- package/dist/esm/servers/nest.js +1 -1
- package/dist/esm/servers/next.d.ts +6 -4
- package/dist/esm/servers/next.js +1 -1
- package/dist/esm/servers/nuxt.d.ts +6 -4
- package/dist/esm/servers/nuxt.js +1 -1
- package/dist/esm/servers/remix.d.ts +6 -4
- package/dist/esm/servers/remix.js +1 -1
- package/dist/esm/servers/sveltekit.d.ts +6 -4
- package/dist/esm/servers/sveltekit.js +1 -1
- package/dist/esm/step-resolver.d.ts +3 -2
- package/dist/esm/step-resolver.js +1 -1
- package/dist/esm/{subscriber.types-CC7F0JO_.d.ts → subscriber.types-BbyO_Cz6.d.ts} +2 -78
- package/dist/esm/util.types-DaFfsxgy.d.ts +78 -0
- package/dist/esm/validators.js +1 -1
- package/package.json +55 -7
- package/dist/esm/chunk-52LSX2V5.js +0 -1
- package/dist/esm/chunk-N4PZBM53.js +0 -1
- package/dist/esm/chunk-ND6IQFTA.js +0 -133
|
@@ -1,8 +1,156 @@
|
|
|
1
1
|
import { ChatElement, Emoji, CardElement } from 'chat';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { A as Awaitable } from './util.types-DaFfsxgy.js';
|
|
3
|
+
|
|
4
|
+
declare enum ChannelTypeEnum {
|
|
5
|
+
IN_APP = "in_app",
|
|
6
|
+
EMAIL = "email",
|
|
7
|
+
SMS = "sms",
|
|
8
|
+
CHAT = "chat",
|
|
9
|
+
PUSH = "push"
|
|
10
|
+
}
|
|
11
|
+
interface IAttachmentOptions {
|
|
12
|
+
mime: string;
|
|
13
|
+
file: Buffer;
|
|
14
|
+
name?: string;
|
|
15
|
+
channels?: ChannelTypeEnum[];
|
|
16
|
+
cid?: string;
|
|
17
|
+
disposition?: string;
|
|
18
|
+
}
|
|
19
|
+
interface ITriggerPayload {
|
|
20
|
+
attachments?: IAttachmentOptions[];
|
|
21
|
+
[key: string]: string | string[] | boolean | number | undefined | IAttachmentOptions | IAttachmentOptions[] | Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
interface ISubscriberPayload {
|
|
24
|
+
subscriberId: string;
|
|
25
|
+
firstName?: string;
|
|
26
|
+
lastName?: string;
|
|
27
|
+
email?: string;
|
|
28
|
+
phone?: string;
|
|
29
|
+
avatar?: string;
|
|
30
|
+
locale?: string;
|
|
31
|
+
data?: Record<string, unknown>;
|
|
32
|
+
channels?: ISubscriberChannel[];
|
|
33
|
+
}
|
|
34
|
+
interface ISubscriberChannel {
|
|
35
|
+
providerId: ChatProviderIdEnum | PushProviderIdEnum;
|
|
36
|
+
integrationIdentifier?: string;
|
|
37
|
+
credentials: IChannelCredentials;
|
|
38
|
+
}
|
|
39
|
+
interface IChannelCredentials {
|
|
40
|
+
webhookUrl?: string;
|
|
41
|
+
deviceTokens?: string[];
|
|
42
|
+
}
|
|
43
|
+
interface ITopic {
|
|
44
|
+
type: 'Topic';
|
|
45
|
+
topicKey: string;
|
|
46
|
+
exclude?: string[];
|
|
47
|
+
}
|
|
48
|
+
type TriggerRecipientsPayload = string | ISubscriberPayload | ITopic | ISubscriberPayload[] | ITopic[];
|
|
49
|
+
declare enum TriggerEventStatusEnum {
|
|
50
|
+
ERROR = "error",
|
|
51
|
+
NOT_ACTIVE = "trigger_not_active",
|
|
52
|
+
NO_WORKFLOW_ACTIVE_STEPS = "no_workflow_active_steps_defined",
|
|
53
|
+
NO_WORKFLOW_STEPS = "no_workflow_steps_defined",
|
|
54
|
+
PROCESSED = "processed",
|
|
55
|
+
SUBSCRIBER_MISSING = "subscriber_id_missing",
|
|
56
|
+
TENANT_MISSING = "no_tenant_found"
|
|
57
|
+
}
|
|
58
|
+
declare enum ChatProviderIdEnum {
|
|
59
|
+
Slack = "slack",
|
|
60
|
+
Discord = "discord",
|
|
61
|
+
MsTeams = "msteams",
|
|
62
|
+
Mattermost = "mattermost",
|
|
63
|
+
Ryver = "ryver",
|
|
64
|
+
Zulip = "zulip",
|
|
65
|
+
GrafanaOnCall = "grafana-on-call",
|
|
66
|
+
GetStream = "getstream",
|
|
67
|
+
RocketChat = "rocket-chat",
|
|
68
|
+
WhatsAppBusiness = "whatsapp-business",
|
|
69
|
+
ChatWebhook = "chat-webhook",
|
|
70
|
+
Telegram = "telegram"
|
|
71
|
+
}
|
|
72
|
+
declare enum PushProviderIdEnum {
|
|
73
|
+
FCM = "fcm",
|
|
74
|
+
APNS = "apns",
|
|
75
|
+
EXPO = "expo",
|
|
76
|
+
OneSignal = "one-signal",
|
|
77
|
+
Pushpad = "pushpad",
|
|
78
|
+
PushWebhook = "push-webhook",
|
|
79
|
+
PusherBeams = "pusher-beams",
|
|
80
|
+
AppIO = "appio"
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A preference for a notification delivery workflow.
|
|
84
|
+
*
|
|
85
|
+
* This provides a shortcut to setting all channels to the same preference.
|
|
86
|
+
*/
|
|
87
|
+
type WorkflowPreference = {
|
|
88
|
+
/**
|
|
89
|
+
* A flag specifying if notification delivery is enabled for the workflow.
|
|
90
|
+
*
|
|
91
|
+
* If `true`, notification delivery is enabled by default for all channels.
|
|
92
|
+
*
|
|
93
|
+
* This setting can be overridden by the channel preferences.
|
|
94
|
+
*
|
|
95
|
+
* @default true
|
|
96
|
+
*/
|
|
97
|
+
enabled: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* A flag specifying if the preference is read-only.
|
|
100
|
+
*
|
|
101
|
+
* If `true`, the preference cannot be changed by the Subscriber.
|
|
102
|
+
*
|
|
103
|
+
* @default false
|
|
104
|
+
*/
|
|
105
|
+
readOnly: boolean;
|
|
106
|
+
};
|
|
107
|
+
/** A preference for a notification delivery channel. */
|
|
108
|
+
type ChannelPreference = {
|
|
109
|
+
/**
|
|
110
|
+
* A flag specifying if notification delivery is enabled for the channel.
|
|
111
|
+
*
|
|
112
|
+
* If `true`, notification delivery is enabled.
|
|
113
|
+
*
|
|
114
|
+
* @default true
|
|
115
|
+
*/
|
|
116
|
+
enabled: boolean;
|
|
117
|
+
};
|
|
118
|
+
type WorkflowPreferences = {
|
|
119
|
+
/**
|
|
120
|
+
* A preference for the workflow.
|
|
121
|
+
*
|
|
122
|
+
* The values specified here will be used if no preference is specified for a channel.
|
|
123
|
+
*/
|
|
124
|
+
all: WorkflowPreference;
|
|
125
|
+
/**
|
|
126
|
+
* A preference for each notification delivery channel.
|
|
127
|
+
*
|
|
128
|
+
* If no preference is specified for a channel, the `all` preference will be used.
|
|
129
|
+
*/
|
|
130
|
+
channels: Record<ChannelTypeEnum, ChannelPreference>;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Recursively make all properties of type `T` optional.
|
|
134
|
+
*/
|
|
135
|
+
type DeepPartial<T> = T extends object ? {
|
|
136
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
137
|
+
} : T;
|
|
138
|
+
/** A partial set of workflow preferences. */
|
|
139
|
+
type WorkflowPreferencesPartial = DeepPartial<WorkflowPreferences>;
|
|
140
|
+
|
|
141
|
+
type Verdict = 'approve' | 'deny';
|
|
142
|
+
interface ToolApprovalRequestPayload {
|
|
143
|
+
approvalId: string;
|
|
144
|
+
toolCallId: string;
|
|
145
|
+
name: string;
|
|
146
|
+
input?: Record<string, unknown>;
|
|
147
|
+
}
|
|
148
|
+
interface ParsedApprovalAction {
|
|
149
|
+
approved: boolean;
|
|
150
|
+
approvalId: string;
|
|
151
|
+
}
|
|
152
|
+
declare function buildApprovalActionId(verdict: Verdict, approvalId: string): string;
|
|
153
|
+
declare function parseApprovalActionId(id: string | undefined): ParsedApprovalAction | null;
|
|
6
154
|
|
|
7
155
|
declare enum AgentEventEnum {
|
|
8
156
|
ON_MESSAGE = "onMessage",
|
|
@@ -64,6 +212,24 @@ interface AgentSubscriber {
|
|
|
64
212
|
/** Arbitrary custom data attached to the subscriber in Novu. */
|
|
65
213
|
data?: Record<string, unknown>;
|
|
66
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Tool-call details on a tool-related history entry. Which fields are set depends on the
|
|
217
|
+
* entry's `type` (`tool_approval_request`, `tool_approval_decision`, or `tool_result`).
|
|
218
|
+
*/
|
|
219
|
+
interface AgentToolData {
|
|
220
|
+
/** Id of the tool call. */
|
|
221
|
+
toolCallId?: string;
|
|
222
|
+
/** Name of the tool. */
|
|
223
|
+
toolName?: string;
|
|
224
|
+
/** Id linking an approval request to its decision. */
|
|
225
|
+
approvalId?: string;
|
|
226
|
+
/** Arguments the tool was called with. */
|
|
227
|
+
input?: Record<string, unknown>;
|
|
228
|
+
/** Whether the tool call was approved or denied. */
|
|
229
|
+
approved?: boolean;
|
|
230
|
+
/** What the tool returned (or the `execution-denied` marker for a denied call). */
|
|
231
|
+
output?: unknown;
|
|
232
|
+
}
|
|
67
233
|
/**
|
|
68
234
|
* A single entry in the conversation history.
|
|
69
235
|
* `ctx.history` is an ordered array of these entries — map them to your LLM's
|
|
@@ -72,17 +238,22 @@ interface AgentSubscriber {
|
|
|
72
238
|
interface AgentHistoryEntry {
|
|
73
239
|
/** Message role: `'user'`, `'assistant'`, or `'system'`. */
|
|
74
240
|
role: string;
|
|
75
|
-
/**
|
|
241
|
+
/**
|
|
242
|
+
* The kind of entry: `'message'`, `'edit'`, `'signal'`, or a tool-lifecycle event
|
|
243
|
+
* (`'tool_approval_request'`, `'tool_approval_decision'`, `'tool_result'`).
|
|
244
|
+
*/
|
|
76
245
|
type: string;
|
|
77
246
|
/** Plain-text representation of the message content. */
|
|
78
247
|
content: string;
|
|
79
248
|
richContent?: Record<string, unknown>;
|
|
80
249
|
senderName?: string;
|
|
81
|
-
/**
|
|
250
|
+
/** Structured data for `signal` entries (e.g. metadata updates). */
|
|
82
251
|
signalData?: {
|
|
83
252
|
type: string;
|
|
84
253
|
payload?: Record<string, unknown>;
|
|
85
254
|
};
|
|
255
|
+
/** Tool-call details — set on tool-lifecycle entries (`tool_*`). */
|
|
256
|
+
toolData?: AgentToolData;
|
|
86
257
|
createdAt: string;
|
|
87
258
|
}
|
|
88
259
|
/** Resolved inbound email domain metadata (present when `platform === 'email'`). */
|
|
@@ -150,6 +321,7 @@ type MessageContent = string | ChatElement;
|
|
|
150
321
|
interface ReplyContent {
|
|
151
322
|
markdown?: string;
|
|
152
323
|
card?: CardElement;
|
|
324
|
+
toolApprovalCard?: ToolApprovalCard;
|
|
153
325
|
files?: FileRef[];
|
|
154
326
|
}
|
|
155
327
|
/**
|
|
@@ -166,6 +338,89 @@ interface AgentAction {
|
|
|
166
338
|
/** Platform-native message ID of the message containing the clicked button/action. */
|
|
167
339
|
sourceMessageId?: string;
|
|
168
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* A tool call that requires user approval before it runs.
|
|
343
|
+
* Pass this to `ctx.toolApproval.request()` when your agent wants to gate a tool.
|
|
344
|
+
*/
|
|
345
|
+
interface AgentToolCall {
|
|
346
|
+
id: string;
|
|
347
|
+
name: string;
|
|
348
|
+
input?: Record<string, unknown>;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Presentation descriptor for Novu's built-in tool-approval card. Returned by the
|
|
352
|
+
* injected `approvalCard()` helper. Novu renders it natively on Slack and as a
|
|
353
|
+
* portable fallback elsewhere; Approve/Deny action ids are always supplied by Novu.
|
|
354
|
+
*
|
|
355
|
+
* Channel mapping (self-hosted):
|
|
356
|
+
* - **Slack (native card):** `icon`, `title`, `subtitle`, `body`, `approveLabel`, `denyLabel`
|
|
357
|
+
* - **Other channels (portable card):** `title`, `subtitle`, `approveLabel`, `denyLabel`
|
|
358
|
+
*
|
|
359
|
+
* `icon` and `body` are ignored on non-Slack channels — the portable fallback has no
|
|
360
|
+
* card image or body block. Catalog icons are 32×32; custom `https://` URLs should match.
|
|
361
|
+
*/
|
|
362
|
+
interface ToolApprovalCard {
|
|
363
|
+
type: 'tool-approval-card';
|
|
364
|
+
/** Slack only. Catalog id (`'stripe'`), `https://` URL, or omit to auto-match the tool name. Use 32×32 px for custom URLs. */
|
|
365
|
+
icon?: string;
|
|
366
|
+
/** All channels. Card title. Defaults to `Tool approval required`. */
|
|
367
|
+
title?: string;
|
|
368
|
+
/** All channels. Card subtitle; auto-generated from the tool name/input when omitted. */
|
|
369
|
+
subtitle?: string;
|
|
370
|
+
/** Slack only. Optional markdown body (e.g. argument preview). Not shown on portable fallback. */
|
|
371
|
+
body?: string;
|
|
372
|
+
/** All channels. Approve button label. Defaults to `Approve`. */
|
|
373
|
+
approveLabel?: string;
|
|
374
|
+
/** All channels. Deny button label. Defaults to `Deny`. */
|
|
375
|
+
denyLabel?: string;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Returned by `ctx.toolApproval.request()`. Return it from `onMessage` to post
|
|
379
|
+
* an approval card and end the turn until the user approves or denies.
|
|
380
|
+
*/
|
|
381
|
+
declare class PendingApproval {
|
|
382
|
+
readonly __novuPendingApproval: true;
|
|
383
|
+
}
|
|
384
|
+
/** Optional customization for tool approval messages. */
|
|
385
|
+
interface ToolApprovalConfig {
|
|
386
|
+
/**
|
|
387
|
+
* Build the approval message shown while waiting for a decision.
|
|
388
|
+
*
|
|
389
|
+
* Return `approvalCard(...)` for Novu's channel-adaptive card (native on Slack,
|
|
390
|
+
* fallback elsewhere), or return a string/`Card` to take full control (portable
|
|
391
|
+
* on every channel). Use the provided `actionIds` on your own buttons.
|
|
392
|
+
*/
|
|
393
|
+
renderApproval?: (args: {
|
|
394
|
+
toolCall: AgentToolCall;
|
|
395
|
+
actionIds: {
|
|
396
|
+
approve: string;
|
|
397
|
+
deny: string;
|
|
398
|
+
};
|
|
399
|
+
approvalCard: (overrides?: Omit<ToolApprovalCard, 'type'>) => ToolApprovalCard;
|
|
400
|
+
}) => MessageContent | ToolApprovalCard;
|
|
401
|
+
}
|
|
402
|
+
/** Passed to `onToolApproval` when the user clicks Approve or Deny. */
|
|
403
|
+
interface ToolApprovalDecision {
|
|
404
|
+
/** The tool that was awaiting approval. */
|
|
405
|
+
toolCall: AgentToolCall;
|
|
406
|
+
/** `true` if the user approved, `false` if they denied. */
|
|
407
|
+
approved: boolean;
|
|
408
|
+
/**
|
|
409
|
+
* Handle to the approval message. When you register `onToolApproval`, you own
|
|
410
|
+
* card cleanup — call `edit()` or `delete()` as needed. When the framework
|
|
411
|
+
* handles the approval click, the card is deleted for you.
|
|
412
|
+
*/
|
|
413
|
+
approvalMessage: ReplyHandle;
|
|
414
|
+
}
|
|
415
|
+
/** Controls on `ctx.toolApproval` for gating tool calls. */
|
|
416
|
+
interface ToolApprovalControl {
|
|
417
|
+
/**
|
|
418
|
+
* Post an approval message and pause the turn.
|
|
419
|
+
* Return the result (`return ctx.toolApproval.request(...)`) from `onMessage`
|
|
420
|
+
* to end the turn until the user decides.
|
|
421
|
+
*/
|
|
422
|
+
request(toolCall: AgentToolCall): Promise<PendingApproval>;
|
|
423
|
+
}
|
|
169
424
|
/** An emoji reaction added to or removed from a message. */
|
|
170
425
|
interface AgentReaction {
|
|
171
426
|
/** Platform-native ID of the message that was reacted to. */
|
|
@@ -192,8 +447,10 @@ interface ReplyHandle {
|
|
|
192
447
|
edit(content: MessageContent, options?: {
|
|
193
448
|
files?: FileRef[];
|
|
194
449
|
}): Promise<ReplyHandle>;
|
|
450
|
+
/** Delete this message from the platform. Removes the rendered message only — history is preserved. */
|
|
451
|
+
delete(): Promise<void>;
|
|
195
452
|
}
|
|
196
|
-
interface
|
|
453
|
+
interface AgentHandlerContext {
|
|
197
454
|
/** Live state of the current conversation, including persisted metadata. */
|
|
198
455
|
readonly conversation: AgentConversation;
|
|
199
456
|
/**
|
|
@@ -227,6 +484,15 @@ interface AgentContextBase {
|
|
|
227
484
|
reply(content: MessageContent, options?: {
|
|
228
485
|
files?: FileRef[];
|
|
229
486
|
}): Promise<ReplyHandle>;
|
|
487
|
+
/**
|
|
488
|
+
* Gate tool calls that need user approval before they run.
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* if (needsApproval(toolCall)) {
|
|
492
|
+
* return ctx.toolApproval.request(toolCall);
|
|
493
|
+
* }
|
|
494
|
+
*/
|
|
495
|
+
readonly toolApproval: ToolApprovalControl;
|
|
230
496
|
/**
|
|
231
497
|
* Mark the conversation as resolved. Optionally provide a summary for the resolution record.
|
|
232
498
|
* Triggers the `onResolve` handler if one is registered.
|
|
@@ -285,25 +551,49 @@ interface AgentContextBase {
|
|
|
285
551
|
* await ctx.reply('Done!');
|
|
286
552
|
*/
|
|
287
553
|
addReaction(messageId: string, emojiName: Emoji): void;
|
|
554
|
+
/**
|
|
555
|
+
* Delete a platform message by id. Queued and flushed with the next `ctx.reply()`,
|
|
556
|
+
* or automatically when the handler completes (same batching as `ctx.addReaction()`).
|
|
557
|
+
* Deletes the rendered message only — conversation history is preserved.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ctx.deleteMessage(ctx.action!.sourceMessageId!);
|
|
561
|
+
* await ctx.reply('Processing…');
|
|
562
|
+
*/
|
|
563
|
+
deleteMessage(messageId: string): void;
|
|
564
|
+
/**
|
|
565
|
+
* Control the typing / "Thinking…" status for the current turn.
|
|
566
|
+
* Posts immediately (like `reply()`), updating the indicator Novu already shows on inbound.
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* await ctx.typing('Searching the docs…'); // set / replace the status text
|
|
570
|
+
* await ctx.typing(); // reset to the default "Thinking…"
|
|
571
|
+
* await ctx.typing.stop(); // clear it for this turn
|
|
572
|
+
*
|
|
573
|
+
* Behaviour is best-effort per platform: custom text shows on Slack-like platforms,
|
|
574
|
+
* a generic typing bubble on others, and is a no-op where there is no typing channel
|
|
575
|
+
* (e.g. email). A normal turn that ends with `ctx.reply()` clears the status automatically.
|
|
576
|
+
*/
|
|
577
|
+
typing: TypingControl;
|
|
288
578
|
}
|
|
289
579
|
/** Context passed to the `onMessage` handler. */
|
|
290
|
-
interface AgentMessageContext extends
|
|
580
|
+
interface AgentMessageContext extends AgentHandlerContext {
|
|
291
581
|
readonly event: 'onMessage';
|
|
292
582
|
}
|
|
293
583
|
/** Context passed to the `onAction` handler. */
|
|
294
|
-
interface AgentActionContext extends
|
|
584
|
+
interface AgentActionContext extends AgentHandlerContext {
|
|
295
585
|
readonly event: 'onAction';
|
|
296
586
|
/** The button click or interactive action that triggered this handler. */
|
|
297
587
|
readonly action: AgentAction;
|
|
298
588
|
}
|
|
299
589
|
/** Context passed to the `onReaction` handler. */
|
|
300
|
-
interface AgentReactionContext extends
|
|
590
|
+
interface AgentReactionContext extends AgentHandlerContext {
|
|
301
591
|
readonly event: 'onReaction';
|
|
302
592
|
/** The emoji reaction that triggered this handler. */
|
|
303
593
|
readonly reaction: AgentReaction;
|
|
304
594
|
}
|
|
305
595
|
/** Context passed to the `onResolve` handler. */
|
|
306
|
-
interface AgentResolveContext extends
|
|
596
|
+
interface AgentResolveContext extends AgentHandlerContext {
|
|
307
597
|
readonly event: 'onResolve';
|
|
308
598
|
}
|
|
309
599
|
type AgentContext = AgentMessageContext | AgentActionContext | AgentReactionContext | AgentResolveContext;
|
|
@@ -346,10 +636,31 @@ interface AgentHandlers {
|
|
|
346
636
|
* `ctx.subscriber` and `ctx.conversation`.
|
|
347
637
|
*/
|
|
348
638
|
onResolve?: (ctx: AgentResolveContext) => Awaitable<MessageContent | void>;
|
|
639
|
+
/**
|
|
640
|
+
* Fires when the user approves or denies a tool call you previously gated with
|
|
641
|
+
* `ctx.toolApproval.request()`.
|
|
642
|
+
*
|
|
643
|
+
* @param decision - The tool, the user's verdict, and a handle to the approval message.
|
|
644
|
+
* @param ctx - Conversation context (history, subscriber, metadata, reply/trigger methods).
|
|
645
|
+
*
|
|
646
|
+
* Run the tool (or skip it), then return a reply or call `ctx.reply()` directly.
|
|
647
|
+
* Register this handler whenever you call `ctx.toolApproval.request()` in `onMessage`.
|
|
648
|
+
*/
|
|
649
|
+
onToolApproval?: (decision: ToolApprovalDecision, ctx: AgentActionContext) => Awaitable<MessageContent | void>;
|
|
650
|
+
/**
|
|
651
|
+
* Customize how approval messages look. Omit to use the built-in Approve/Deny card.
|
|
652
|
+
*/
|
|
653
|
+
toolApproval?: ToolApprovalConfig;
|
|
349
654
|
}
|
|
350
655
|
interface Agent {
|
|
351
656
|
id: string;
|
|
352
657
|
handlers: AgentHandlers;
|
|
658
|
+
/**
|
|
659
|
+
* @internal Set by `agent()` / ai-sdk registration. True when the application
|
|
660
|
+
* author registered `onToolApproval` (full manual card cleanup). False when
|
|
661
|
+
* only a framework wrapper handles approval clicks (auto-delete after handler).
|
|
662
|
+
*/
|
|
663
|
+
userOnToolApproval?: boolean;
|
|
353
664
|
}
|
|
354
665
|
interface AgentBridgeRequest {
|
|
355
666
|
version: number;
|
|
@@ -398,6 +709,17 @@ type TriggerSignal = {
|
|
|
398
709
|
payload?: Record<string, unknown>;
|
|
399
710
|
};
|
|
400
711
|
type Signal = MetadataSignal | TriggerSignal;
|
|
712
|
+
/** The outcome of a tool call, reported back so it's saved in the conversation history. */
|
|
713
|
+
type ToolResult = {
|
|
714
|
+
/** Id of the tool call this result belongs to. */
|
|
715
|
+
toolCallId: string;
|
|
716
|
+
/** Name of the tool. */
|
|
717
|
+
toolName?: string;
|
|
718
|
+
/** What the tool returned (or the `execution-denied` marker for a denied call). */
|
|
719
|
+
output: unknown;
|
|
720
|
+
/** Optional human-readable summary shown in the conversation timeline. */
|
|
721
|
+
preview?: string;
|
|
722
|
+
};
|
|
401
723
|
/** In-place edit of a previously posted agent message. Identified by platform message id. */
|
|
402
724
|
interface EditPayload {
|
|
403
725
|
messageId: string;
|
|
@@ -408,6 +730,24 @@ interface AddReactionPayload {
|
|
|
408
730
|
messageId: string;
|
|
409
731
|
emojiName: Emoji;
|
|
410
732
|
}
|
|
733
|
+
/** Delete a previously posted platform message. Removes the rendered message only — history is preserved. */
|
|
734
|
+
interface DeleteMessagePayload {
|
|
735
|
+
messageId: string;
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Per-turn typing/status control op sent on the reply contract.
|
|
739
|
+
* - `{ status?: string }` — set/replace the status; omit `status` for the default "Thinking…".
|
|
740
|
+
* - `'stop'` — clear the status for this turn.
|
|
741
|
+
*/
|
|
742
|
+
type TypingOp = {
|
|
743
|
+
status?: string;
|
|
744
|
+
} | 'stop';
|
|
745
|
+
/**
|
|
746
|
+
* `ctx.typing` surface: a callable that sets/updates the status, plus `.stop()` to clear it.
|
|
747
|
+
*/
|
|
748
|
+
type TypingControl = ((status?: string) => Promise<void>) & {
|
|
749
|
+
stop: () => Promise<void>;
|
|
750
|
+
};
|
|
411
751
|
interface AgentReplyPayload {
|
|
412
752
|
conversationId: string;
|
|
413
753
|
integrationIdentifier: string;
|
|
@@ -417,7 +757,11 @@ interface AgentReplyPayload {
|
|
|
417
757
|
summary?: string;
|
|
418
758
|
};
|
|
419
759
|
signals?: Signal[];
|
|
760
|
+
toolResults?: ToolResult[];
|
|
761
|
+
toolApprovalRequest?: ToolApprovalRequestPayload;
|
|
420
762
|
addReactions?: AddReactionPayload[];
|
|
763
|
+
deleteMessages?: DeleteMessagePayload[];
|
|
764
|
+
typing?: TypingOp;
|
|
421
765
|
}
|
|
422
766
|
/** Shape returned by /agents/:id/reply when a reply or edit was delivered. */
|
|
423
767
|
interface SentMessageInfo {
|
|
@@ -425,185 +769,4 @@ interface SentMessageInfo {
|
|
|
425
769
|
platformThreadId: string;
|
|
426
770
|
}
|
|
427
771
|
|
|
428
|
-
|
|
429
|
-
* Thrown by `ctx.reply()` and `handle.edit()` when the upstream message delivery
|
|
430
|
-
* fails — e.g. the configured email provider returns 401, Slack rejects the token,
|
|
431
|
-
* or Teams rejects the request.
|
|
432
|
-
*
|
|
433
|
-
* `message` is always a short, human-readable summary.
|
|
434
|
-
* `responseBody` preserves the raw upstream body for debugging.
|
|
435
|
-
*
|
|
436
|
-
* @example
|
|
437
|
-
* ```ts
|
|
438
|
-
* import { AgentDeliveryError } from '@novu/framework';
|
|
439
|
-
*
|
|
440
|
-
* try {
|
|
441
|
-
* await ctx.reply('Hello!');
|
|
442
|
-
* } catch (err) {
|
|
443
|
-
* if (err instanceof AgentDeliveryError) {
|
|
444
|
-
* console.error('Delivery failed:', err.message);
|
|
445
|
-
* return;
|
|
446
|
-
* }
|
|
447
|
-
* throw err;
|
|
448
|
-
* }
|
|
449
|
-
* ```
|
|
450
|
-
*/
|
|
451
|
-
declare class AgentDeliveryError extends Error {
|
|
452
|
-
readonly statusCode: number;
|
|
453
|
-
readonly responseBody: string;
|
|
454
|
-
constructor(statusCode: number, responseBody: string);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Define a new conversational agent.
|
|
459
|
-
*
|
|
460
|
-
* @param agentId - Unique identifier matching the agent entity created in Novu (e.g. 'wine-bot')
|
|
461
|
-
* @param handlers - Handler functions for agent events
|
|
462
|
-
*/
|
|
463
|
-
declare function agent(agentId: string, handlers: AgentHandlers): Agent;
|
|
464
|
-
|
|
465
|
-
declare class Client {
|
|
466
|
-
private discoveredWorkflows;
|
|
467
|
-
private discoverWorkflowPromises;
|
|
468
|
-
private registeredAgents;
|
|
469
|
-
private templateEngine;
|
|
470
|
-
secretKey: string;
|
|
471
|
-
apiUrl: string;
|
|
472
|
-
version: string;
|
|
473
|
-
strictAuthentication: boolean;
|
|
474
|
-
verbose: boolean;
|
|
475
|
-
logger: Logger;
|
|
476
|
-
constructor(options?: ClientOptions);
|
|
477
|
-
private buildOptions;
|
|
478
|
-
private log;
|
|
479
|
-
/**
|
|
480
|
-
* Adds workflows to the client.
|
|
481
|
-
*
|
|
482
|
-
* A locking mechanism is used to ensure that duplicate workflows are not added.
|
|
483
|
-
*
|
|
484
|
-
* @param workflows - The workflows to add.
|
|
485
|
-
*/
|
|
486
|
-
addWorkflows(workflows: Array<Workflow>): Promise<void>;
|
|
487
|
-
addAgents(agents: Array<Agent>): void;
|
|
488
|
-
getAgent(agentId: string): Agent | undefined;
|
|
489
|
-
private addWorkflow;
|
|
490
|
-
healthCheck(): HealthCheck;
|
|
491
|
-
private getWorkflow;
|
|
492
|
-
private getStep;
|
|
493
|
-
private getRegisteredWorkflows;
|
|
494
|
-
discover(): DiscoverOutput;
|
|
495
|
-
/**
|
|
496
|
-
* Mocks data based on the given schema.
|
|
497
|
-
* The `default` value in the schema is used as the base data.
|
|
498
|
-
* If no `default` value is provided, the data is generated using JSONSchemaFaker.
|
|
499
|
-
*
|
|
500
|
-
* @param schema
|
|
501
|
-
* @returns mocked data
|
|
502
|
-
*/
|
|
503
|
-
private mock;
|
|
504
|
-
private validate;
|
|
505
|
-
private throwInvalidProvider;
|
|
506
|
-
private throwInvalidStep;
|
|
507
|
-
private throwInvalidEvent;
|
|
508
|
-
private executeStepFactory;
|
|
509
|
-
private shouldSanitize;
|
|
510
|
-
private shouldSkip;
|
|
511
|
-
executeWorkflow(event: Event): Promise<ExecuteOutput>;
|
|
512
|
-
private createExecutionPayload;
|
|
513
|
-
private prettyPrintExecute;
|
|
514
|
-
private executeProviders;
|
|
515
|
-
private previewProvider;
|
|
516
|
-
private executeProvider;
|
|
517
|
-
private executeStep;
|
|
518
|
-
private compileControls;
|
|
519
|
-
/**
|
|
520
|
-
* Preprocesses standalone translation patterns.
|
|
521
|
-
* Transforms {{t.key}} to [T:key] placeholder (not Liquid syntax, passes through unchanged).
|
|
522
|
-
*/
|
|
523
|
-
private preprocessTranslationPatterns;
|
|
524
|
-
/**
|
|
525
|
-
* Preprocesses translation keys used as filter arguments.
|
|
526
|
-
* Transforms 't.key' to '[T:key]' placeholder (not Liquid syntax, passes through unchanged).
|
|
527
|
-
* Example: pluralize: 't.apple', 't.apples' → pluralize: '[T:apple]', '[T:apples]'
|
|
528
|
-
*/
|
|
529
|
-
private preprocessFilterTranslationArgs;
|
|
530
|
-
/**
|
|
531
|
-
* Post-processes placeholders back to translation markers after Liquid render.
|
|
532
|
-
* Transforms [T:key] back to {{t.key}} for the translation service.
|
|
533
|
-
*/
|
|
534
|
-
private postprocessTranslationMarkers;
|
|
535
|
-
/**
|
|
536
|
-
* Create the controls for a step, taking both the event controls and the default controls into account
|
|
537
|
-
*
|
|
538
|
-
* @param step The step to create the controls for
|
|
539
|
-
* @param event The event that triggered the step
|
|
540
|
-
* @returns The controls for the step
|
|
541
|
-
*/
|
|
542
|
-
private createStepControls;
|
|
543
|
-
private previewStep;
|
|
544
|
-
private constructStepForPreview;
|
|
545
|
-
private extractMockDataForPreviousSteps;
|
|
546
|
-
private previewRequiredStep;
|
|
547
|
-
private getStepState;
|
|
548
|
-
private getStepCode;
|
|
549
|
-
private getWorkflowCode;
|
|
550
|
-
getCode(workflowId: string, stepId?: string): CodeResult;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
interface ServeHandlerOptions {
|
|
554
|
-
client?: Client;
|
|
555
|
-
workflows?: Array<Workflow>;
|
|
556
|
-
agents?: Array<Agent>;
|
|
557
|
-
}
|
|
558
|
-
type INovuRequestHandlerOptions<Input extends any[] = any[], Output = any> = ServeHandlerOptions & {
|
|
559
|
-
frameworkName: string;
|
|
560
|
-
client?: Client;
|
|
561
|
-
workflows?: Array<Workflow>;
|
|
562
|
-
agents?: Array<Agent>;
|
|
563
|
-
handler: Handler<Input, Output>;
|
|
564
|
-
};
|
|
565
|
-
type Handler<Input extends any[] = any[], Output = any> = (...args: Input) => HandlerResponse<Output>;
|
|
566
|
-
type HandlerResponse<Output = any> = {
|
|
567
|
-
body: () => Awaitable<any>;
|
|
568
|
-
headers: (key: string) => Awaitable<string | null | undefined>;
|
|
569
|
-
method: () => Awaitable<string>;
|
|
570
|
-
queryString?: (key: string, url: URL) => Awaitable<string | null | undefined>;
|
|
571
|
-
url: () => Awaitable<URL>;
|
|
572
|
-
transformResponse: (res: IActionResponse<string>) => Output;
|
|
573
|
-
waitUntil?: (promise: Promise<unknown>) => void;
|
|
574
|
-
};
|
|
575
|
-
type IActionResponse<TBody extends string = string> = {
|
|
576
|
-
status: number;
|
|
577
|
-
headers: Record<string, string>;
|
|
578
|
-
body: TBody;
|
|
579
|
-
};
|
|
580
|
-
declare class NovuRequestHandler<Input extends any[] = any[], Output = any> {
|
|
581
|
-
readonly frameworkName: string;
|
|
582
|
-
readonly handler: Handler<Input, Output>;
|
|
583
|
-
readonly client: Client;
|
|
584
|
-
private readonly hmacEnabled;
|
|
585
|
-
private readonly http;
|
|
586
|
-
private readonly workflows;
|
|
587
|
-
private readonly agents;
|
|
588
|
-
constructor(options: INovuRequestHandlerOptions<Input, Output>);
|
|
589
|
-
createHandler(): (...args: Input) => Promise<Output>;
|
|
590
|
-
private getStaticHeaders;
|
|
591
|
-
private createResponse;
|
|
592
|
-
private createError;
|
|
593
|
-
private handleAction;
|
|
594
|
-
private getPostActionMap;
|
|
595
|
-
triggerAction(triggerEvent: EventTriggerParams): () => Promise<IActionResponse<string>>;
|
|
596
|
-
private getGetActionMap;
|
|
597
|
-
private handlePostAction;
|
|
598
|
-
private handleGetAction;
|
|
599
|
-
private runAgentHandler;
|
|
600
|
-
private handleError;
|
|
601
|
-
private validateHmac;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Define a new notification workflow.
|
|
606
|
-
*/
|
|
607
|
-
declare function workflow<T_PayloadSchema extends Schema, T_ControlSchema extends Schema, T_EnvSchema extends Schema, T_PayloadValidated extends Record<string, unknown> = FromSchema<T_PayloadSchema>, T_PayloadUnvalidated extends Record<string, unknown> = FromSchemaUnvalidated<T_PayloadSchema>, T_Controls extends Record<string, unknown> = FromSchema<T_ControlSchema>, T_Env extends Record<string, unknown> = FromSchema<T_EnvSchema>>(workflowId: string, execute: Execute<T_PayloadValidated, T_Controls, T_Env>, workflowOptions?: WorkflowOptions<T_PayloadSchema, T_ControlSchema, T_EnvSchema>): Workflow<T_PayloadUnvalidated>;
|
|
608
|
-
|
|
609
|
-
export { type Agent as A, Client as C, type EditPayload as E, type FileRef as F, type INovuRequestHandlerOptions as I, type MessageContent as M, NovuRequestHandler as N, type ReplyContent as R, type ServeHandlerOptions as S, type TriggerSignal as T, type AgentAction as a, type AgentActionContext as b, type AgentAttachment as c, type AgentBridgeRequest as d, type AgentContext as e, type AgentConversation as f, AgentDeliveryError as g, AgentEventEnum as h, type AgentHandlers as i, type AgentHistoryEntry as j, type AgentMessage as k, type AgentMessageAuthor as l, type AgentMessageContext as m, type AgentPlatformContext as n, type AgentReaction as o, type AgentReactionContext as p, type AgentReplyPayload as q, type AgentResolveContext as r, type AgentSubscriber as s, type MetadataSignal as t, type ReplyHandle as u, type SentMessageInfo as v, type Signal as w, agent as x, workflow as y };
|
|
772
|
+
export { type Agent as A, type ToolApprovalControl as B, type AgentBridgeRequest as C, type AgentReplyPayload as D, type DeleteMessagePayload as E, type FileRef as F, type EditPayload as G, type MetadataSignal as H, type ITriggerPayload as I, type ReplyContent as J, type Signal as K, type TriggerSignal as L, type MessageContent as M, buildApprovalActionId as N, parseApprovalActionId as O, type ParsedApprovalAction as P, type ReplyHandle as R, type SentMessageInfo as S, type ToolApprovalCard as T, type WorkflowPreferencesPartial as W, type AgentAction as a, type AgentActionContext as b, type AgentAttachment as c, type AgentContext as d, type AgentConversation as e, type AgentHandlerContext as f, type AgentHandlers as g, type AgentHistoryEntry as h, type AgentMessage as i, type AgentMessageAuthor as j, type AgentMessageContext as k, type AgentPlatformContext as l, type AgentReaction as m, type AgentReactionContext as n, type AgentResolveContext as o, type AgentSubscriber as p, type AgentToolCall as q, type ToolApprovalConfig as r, type ToolApprovalDecision as s, type TriggerRecipientsPayload as t, type ISubscriberPayload as u, TriggerEventStatusEnum as v, type ToolResult as w, type ToolApprovalRequestPayload as x, AgentEventEnum as y, type TypingControl as z };
|