@letta-ai/letta-code 0.28.8 → 0.28.9
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/dist/channels-public.js +1053 -0
- package/dist/channels-public.js.map +13 -0
- package/dist/channels-slack.js +534 -0
- package/dist/channels-slack.js.map +15 -0
- package/dist/types/channels/core-stream.d.ts +35 -0
- package/dist/types/channels/core-stream.d.ts.map +1 -0
- package/dist/types/channels/plugin-types.d.ts +226 -0
- package/dist/types/channels/plugin-types.d.ts.map +1 -0
- package/dist/types/channels/processor.d.ts +27 -0
- package/dist/types/channels/processor.d.ts.map +1 -0
- package/dist/types/channels/progress-builder.d.ts +13 -0
- package/dist/types/channels/progress-builder.d.ts.map +1 -0
- package/dist/types/channels/progress-formatting.d.ts +34 -0
- package/dist/types/channels/progress-formatting.d.ts.map +1 -0
- package/dist/types/channels/slack/ingress-policy.d.ts +72 -0
- package/dist/types/channels/slack/ingress-policy.d.ts.map +1 -0
- package/dist/types/channels/slack/progress.d.ts +7 -0
- package/dist/types/channels/slack/progress.d.ts.map +1 -0
- package/dist/types/channels/slack/public-utils.d.ts +11 -0
- package/dist/types/channels/slack/public-utils.d.ts.map +1 -0
- package/dist/types/channels/slack/sender.d.ts +39 -0
- package/dist/types/channels/slack/sender.d.ts.map +1 -0
- package/dist/types/channels/slack/status-controller.d.ts +35 -0
- package/dist/types/channels/slack/status-controller.d.ts.map +1 -0
- package/dist/types/channels/types.d.ts +766 -0
- package/dist/types/channels/types.d.ts.map +1 -0
- package/dist/types/channels-public.d.ts +8 -0
- package/dist/types/channels-public.d.ts.map +1 -0
- package/dist/types/channels-slack.d.ts +9 -0
- package/dist/types/channels-slack.d.ts.map +1 -0
- package/dist/types/permissions/mode.d.ts +52 -0
- package/dist/types/permissions/mode.d.ts.map +1 -0
- package/dist/types/types/protocol_v2.d.ts +4 -0
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/letta.js +2423 -1788
- package/package.json +33 -2
- package/scripts/isolated-unit-tests.json +12 -0
- package/scripts/run-unit-tests.cjs +5 -2
- package/scripts/source-file-size-baseline.json +4 -4
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel system types.
|
|
3
|
+
*
|
|
4
|
+
* A "channel" connects Letta Code agents to external messaging platforms
|
|
5
|
+
* (Telegram, Slack, etc.). Each channel has an adapter that handles
|
|
6
|
+
* platform-specific communication, and a routing table that maps
|
|
7
|
+
* platform chat IDs to agent+conversation pairs.
|
|
8
|
+
*/
|
|
9
|
+
import type { PermissionMode } from "../permissions/mode";
|
|
10
|
+
import type { ApprovalResponseBody, ListModelsResponseModelEntry, StopReasonType } from "../types/protocol_v2";
|
|
11
|
+
/**
|
|
12
|
+
* Vendor-neutral model-picker payload produced by the generic channel
|
|
13
|
+
* `/model` handler. Adapters decide how (or whether) to render it.
|
|
14
|
+
*/
|
|
15
|
+
export type ChannelModelPickerData = {
|
|
16
|
+
current: {
|
|
17
|
+
modelLabel: string;
|
|
18
|
+
modelHandle: string | null;
|
|
19
|
+
scope?: "agent" | "conversation";
|
|
20
|
+
};
|
|
21
|
+
entries: ListModelsResponseModelEntry[];
|
|
22
|
+
availableHandles?: string[] | null;
|
|
23
|
+
recentHandles?: string[];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Default channel id used for wire compatibility when WS clients omit
|
|
27
|
+
* `channel_id` on channel commands. Early protocol versions predate
|
|
28
|
+
* multi-channel support, when Telegram was the only bundled channel.
|
|
29
|
+
*/
|
|
30
|
+
export declare const LEGACY_DEFAULT_CHANNEL_ID = "telegram";
|
|
31
|
+
/**
|
|
32
|
+
* Per-turn rich draft streaming policy derived from a channel account's
|
|
33
|
+
* generic opt-in fields. Returns null when the account has not opted in.
|
|
34
|
+
* Any channel account config may declare `richDraftStreaming` /
|
|
35
|
+
* `richPrivateChatDefault`; adapters that also implement
|
|
36
|
+
* `sendRichMessageDraft` get live draft streaming from the listener.
|
|
37
|
+
*/
|
|
38
|
+
export type ChannelRichDraftStreamingPolicy = {
|
|
39
|
+
richPrivateChatDefault: boolean;
|
|
40
|
+
};
|
|
41
|
+
export declare function getRichDraftStreamingPolicy(account: unknown): ChannelRichDraftStreamingPolicy | null;
|
|
42
|
+
export declare const FIRST_PARTY_CHANNEL_IDS: readonly ["telegram", "slack", "discord", "custom", "whatsapp", "signal"];
|
|
43
|
+
export type FirstPartyChannelId = (typeof FIRST_PARTY_CHANNEL_IDS)[number];
|
|
44
|
+
/**
|
|
45
|
+
* Built-in channels shipped with Letta Code. Custom channel IDs are discovered
|
|
46
|
+
* at runtime from ~/.letta/channels/<id>/channel.json.
|
|
47
|
+
*/
|
|
48
|
+
export declare const SUPPORTED_CHANNEL_IDS: readonly ["telegram", "slack", "discord", "custom", "whatsapp", "signal"];
|
|
49
|
+
export type SupportedChannelId = string;
|
|
50
|
+
export type ChannelChatType = "direct" | "channel";
|
|
51
|
+
export type ChannelDefaultPermissionMode = Extract<PermissionMode, "standard" | "acceptEdits" | "unrestricted">;
|
|
52
|
+
export type SlackDefaultPermissionMode = ChannelDefaultPermissionMode;
|
|
53
|
+
export type DiscordDefaultPermissionMode = ChannelDefaultPermissionMode;
|
|
54
|
+
export declare const DEFAULT_SLACK_PERMISSION_MODE: SlackDefaultPermissionMode;
|
|
55
|
+
/** Per-channel mode for Discord guild channels. */
|
|
56
|
+
export type DiscordChannelMode = "open" | "mention-only";
|
|
57
|
+
export interface ChannelMessageAttachment {
|
|
58
|
+
id?: string;
|
|
59
|
+
name?: string;
|
|
60
|
+
mimeType?: string;
|
|
61
|
+
sizeBytes?: number;
|
|
62
|
+
kind: "image" | "file" | "audio" | "video";
|
|
63
|
+
/** Local file materialized for tool access. Absent when automatic download was skipped. */
|
|
64
|
+
localPath?: string;
|
|
65
|
+
/** Platform message that contains this attachment, used for scoped on-demand downloads. */
|
|
66
|
+
sourceMessageId?: string;
|
|
67
|
+
/** Platform thread that contains this attachment, when it is thread-scoped. */
|
|
68
|
+
sourceThreadId?: string | null;
|
|
69
|
+
/** Why an attachment discovered on the platform was not downloaded automatically. */
|
|
70
|
+
downloadReason?: "exceeds_auto_download_limit" | "missing_download_url" | "download_failed";
|
|
71
|
+
/** Automatic download threshold that rejected this attachment, when applicable. */
|
|
72
|
+
autoDownloadLimitBytes?: number;
|
|
73
|
+
imageDataBase64?: string;
|
|
74
|
+
/** Best-effort speech-to-text transcription (voice memos only). */
|
|
75
|
+
transcription?: string;
|
|
76
|
+
/** Best-effort reason voice memo transcription failed. */
|
|
77
|
+
transcriptionError?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface ChannelReactionNotification {
|
|
80
|
+
action: "added" | "removed";
|
|
81
|
+
emoji: string;
|
|
82
|
+
targetMessageId: string;
|
|
83
|
+
targetSenderId?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface ChannelThreadContextEntry {
|
|
86
|
+
messageId?: string;
|
|
87
|
+
senderId?: string;
|
|
88
|
+
senderName?: string;
|
|
89
|
+
text: string;
|
|
90
|
+
attachments?: ChannelMessageAttachment[];
|
|
91
|
+
}
|
|
92
|
+
export interface ChannelThreadContext {
|
|
93
|
+
label?: string;
|
|
94
|
+
starter?: ChannelThreadContextEntry;
|
|
95
|
+
history?: ChannelThreadContextEntry[];
|
|
96
|
+
}
|
|
97
|
+
export interface ChannelReplyContext {
|
|
98
|
+
messageId?: string;
|
|
99
|
+
senderId?: string;
|
|
100
|
+
senderName?: string;
|
|
101
|
+
text?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface ChannelTurnSource {
|
|
104
|
+
channel: string;
|
|
105
|
+
accountId?: string;
|
|
106
|
+
chatId: string;
|
|
107
|
+
chatType?: ChannelChatType;
|
|
108
|
+
/** Platform user who triggered the turn, when known. Slack streaming needs this in channel threads. */
|
|
109
|
+
senderId?: string;
|
|
110
|
+
/** Platform team/workspace for the triggering user, when known. */
|
|
111
|
+
senderTeamId?: string;
|
|
112
|
+
messageId?: string;
|
|
113
|
+
threadId?: string | null;
|
|
114
|
+
agentId: string;
|
|
115
|
+
conversationId: string;
|
|
116
|
+
}
|
|
117
|
+
export type ChannelTurnOutcome = "completed" | "error" | "cancelled";
|
|
118
|
+
export type ChannelTurnProgressKind = "thinking" | "responding" | "tool" | "approval" | "command" | "status" | "retry" | "error";
|
|
119
|
+
export type ChannelTurnProgressState = "started" | "updated" | "completed" | "error" | "waiting";
|
|
120
|
+
export interface ChannelTurnProgressUpdate {
|
|
121
|
+
kind: ChannelTurnProgressKind;
|
|
122
|
+
state: ChannelTurnProgressState;
|
|
123
|
+
/** Sanitized, user-facing status text. Never include tool args or output. */
|
|
124
|
+
message: string;
|
|
125
|
+
toolCallId?: string;
|
|
126
|
+
toolName?: string;
|
|
127
|
+
/** Optional sanitized argument summary for expanded tool progress details. */
|
|
128
|
+
toolDetails?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Optional sanitized error-output preview for failed tool calls. Kept
|
|
131
|
+
* separate from toolDetails so surfaces can render it as secondary detail
|
|
132
|
+
* text; it must never be used as a row title/header (LET-9509).
|
|
133
|
+
*/
|
|
134
|
+
errorDetails?: string;
|
|
135
|
+
/** Optional sanitized row title for native/rich progress surfaces. */
|
|
136
|
+
toolTitle?: string;
|
|
137
|
+
command?: string;
|
|
138
|
+
runId?: string;
|
|
139
|
+
}
|
|
140
|
+
export interface ChannelTurnProgressEvent extends ChannelTurnProgressUpdate {
|
|
141
|
+
type: "progress";
|
|
142
|
+
batchId?: string;
|
|
143
|
+
sources: ChannelTurnSource[];
|
|
144
|
+
}
|
|
145
|
+
export type ChannelControlRequestKind = "ask_user_question" | "generic_tool_approval";
|
|
146
|
+
export interface ChannelControlRequestEvent {
|
|
147
|
+
requestId: string;
|
|
148
|
+
kind: ChannelControlRequestKind;
|
|
149
|
+
source: ChannelTurnSource;
|
|
150
|
+
toolName: string;
|
|
151
|
+
input: Record<string, unknown>;
|
|
152
|
+
}
|
|
153
|
+
export type ChannelControlResponseResult = "handled" | "expired" | "unavailable" | "forbidden";
|
|
154
|
+
export interface ChannelControlResponseInput {
|
|
155
|
+
requestId: string;
|
|
156
|
+
response: ApprovalResponseBody;
|
|
157
|
+
senderId: string;
|
|
158
|
+
channel: string;
|
|
159
|
+
accountId?: string;
|
|
160
|
+
chatId: string;
|
|
161
|
+
threadId?: string | null;
|
|
162
|
+
}
|
|
163
|
+
export type ChannelTurnLifecycleEvent = {
|
|
164
|
+
type: "queued";
|
|
165
|
+
source: ChannelTurnSource;
|
|
166
|
+
} | {
|
|
167
|
+
type: "processing";
|
|
168
|
+
batchId: string;
|
|
169
|
+
sources: ChannelTurnSource[];
|
|
170
|
+
} | {
|
|
171
|
+
type: "finished";
|
|
172
|
+
batchId: string;
|
|
173
|
+
sources: ChannelTurnSource[];
|
|
174
|
+
outcome: ChannelTurnOutcome;
|
|
175
|
+
stopReason: StopReasonType;
|
|
176
|
+
error?: string;
|
|
177
|
+
runId?: string;
|
|
178
|
+
};
|
|
179
|
+
export type ChannelStartupLogger = (message: string) => void;
|
|
180
|
+
export interface ChannelAdapterStartOptions {
|
|
181
|
+
logger?: ChannelStartupLogger;
|
|
182
|
+
}
|
|
183
|
+
export interface ChannelAdapter {
|
|
184
|
+
/** Platform identifier, e.g. "telegram", "slack". */
|
|
185
|
+
readonly id: string;
|
|
186
|
+
/** Channel identifier, e.g. "telegram". */
|
|
187
|
+
readonly channelId?: string;
|
|
188
|
+
/** Account identifier within the channel. */
|
|
189
|
+
readonly accountId?: string;
|
|
190
|
+
/** Human-readable display name, e.g. "Telegram". */
|
|
191
|
+
readonly name: string;
|
|
192
|
+
/** Start receiving messages (e.g. begin long-polling). */
|
|
193
|
+
start(options?: ChannelAdapterStartOptions): Promise<void>;
|
|
194
|
+
/** Stop receiving messages gracefully. */
|
|
195
|
+
stop(): Promise<void>;
|
|
196
|
+
/** Whether the adapter is currently running. */
|
|
197
|
+
isRunning(): boolean;
|
|
198
|
+
/** Send a message through this channel. */
|
|
199
|
+
sendMessage(msg: OutboundChannelMessage): Promise<{
|
|
200
|
+
messageId: string;
|
|
201
|
+
}>;
|
|
202
|
+
/**
|
|
203
|
+
* Optionally materialize a platform attachment into the channel's local
|
|
204
|
+
* inbound directory. MessageChannel plugins expose this only when the
|
|
205
|
+
* adapter can verify the attachment against its canonical source message.
|
|
206
|
+
*/
|
|
207
|
+
downloadAttachment?(params: {
|
|
208
|
+
attachmentId: string;
|
|
209
|
+
chatId: string;
|
|
210
|
+
threadId?: string | null;
|
|
211
|
+
messageId: string;
|
|
212
|
+
}): Promise<ChannelMessageAttachment>;
|
|
213
|
+
/**
|
|
214
|
+
* Optionally stream an ephemeral rich-message draft while a final rich
|
|
215
|
+
* message is being generated. Drafts are best-effort previews; callers must
|
|
216
|
+
* still send a final persistent message with sendMessage().
|
|
217
|
+
*/
|
|
218
|
+
sendRichMessageDraft?(draft: OutboundChannelRichMessageDraft): Promise<void>;
|
|
219
|
+
/**
|
|
220
|
+
* Send a direct reply on the platform (for pairing codes, no-route
|
|
221
|
+
* messages, etc.) without going through the agent.
|
|
222
|
+
*/
|
|
223
|
+
sendDirectReply(chatId: string, text: string, options?: {
|
|
224
|
+
replyToMessageId?: string;
|
|
225
|
+
threadId?: string | null;
|
|
226
|
+
/**
|
|
227
|
+
* Structured model-picker data. Adapters with native rich UI (for
|
|
228
|
+
* example Slack Block Kit) may render it; others fall back to text.
|
|
229
|
+
*/
|
|
230
|
+
modelPicker?: ChannelModelPickerData;
|
|
231
|
+
}): Promise<void>;
|
|
232
|
+
/**
|
|
233
|
+
* Optionally enrich an inbound message with additional context before it is
|
|
234
|
+
* formatted for the agent. Slack uses this to hydrate older thread context
|
|
235
|
+
* the first time a Letta conversation is created for an existing thread.
|
|
236
|
+
*/
|
|
237
|
+
prepareInboundMessage?(msg: InboundChannelMessage, options?: {
|
|
238
|
+
isFirstRouteTurn?: boolean;
|
|
239
|
+
}): Promise<InboundChannelMessage>;
|
|
240
|
+
/**
|
|
241
|
+
* Optional lifecycle hook for channel-originated turns. Adapters can use
|
|
242
|
+
* this to surface lightweight UX feedback (for example, Slack reactions)
|
|
243
|
+
* without coupling queue/lifecycle state to a specific channel.
|
|
244
|
+
*/
|
|
245
|
+
handleTurnLifecycleEvent?(event: ChannelTurnLifecycleEvent): Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* Optional progress hook for channel-originated turns. Payloads are generic
|
|
248
|
+
* and sanitized before they reach adapters; adapters decide how to render and
|
|
249
|
+
* throttle their platform-specific UX.
|
|
250
|
+
*/
|
|
251
|
+
handleTurnProgressEvent?(event: ChannelTurnProgressEvent): Promise<void>;
|
|
252
|
+
/**
|
|
253
|
+
* Optional hook for control requests that originate from a channel turn.
|
|
254
|
+
* Adapters can render these natively (or near-natively) for Slack/Telegram
|
|
255
|
+
* instead of relying on a desktop/websocket UI intercept layer.
|
|
256
|
+
*/
|
|
257
|
+
handleControlRequestEvent?(event: ChannelControlRequestEvent): Promise<void>;
|
|
258
|
+
/** Wired by ChannelRegistry for native approval controls such as Slack buttons. */
|
|
259
|
+
onControlResponse?: (input: ChannelControlResponseInput) => Promise<ChannelControlResponseResult>;
|
|
260
|
+
/**
|
|
261
|
+
* Called by the registry when the adapter receives an inbound message.
|
|
262
|
+
* Set by ChannelRegistry during initialization.
|
|
263
|
+
*/
|
|
264
|
+
onMessage?: (msg: InboundChannelMessage) => Promise<void>;
|
|
265
|
+
}
|
|
266
|
+
export interface InboundChannelMessage {
|
|
267
|
+
/** Platform identifier, e.g. "telegram". */
|
|
268
|
+
channel: string;
|
|
269
|
+
/** Channel account that received the inbound message. */
|
|
270
|
+
accountId?: string;
|
|
271
|
+
/** Platform-specific chat/conversation ID. */
|
|
272
|
+
chatId: string;
|
|
273
|
+
/** Platform-specific sender user ID. */
|
|
274
|
+
senderId: string;
|
|
275
|
+
/** Platform-specific sender team/workspace ID, when available. */
|
|
276
|
+
senderTeamId?: string;
|
|
277
|
+
/** Sender display name, if available. */
|
|
278
|
+
senderName?: string;
|
|
279
|
+
/** Chat/channel label, if available (for discovery UIs). */
|
|
280
|
+
chatLabel?: string;
|
|
281
|
+
/** Message text content. */
|
|
282
|
+
text: string;
|
|
283
|
+
/** Unix timestamp (ms) of the message. */
|
|
284
|
+
timestamp: number;
|
|
285
|
+
/** Platform message ID for threading/replies. */
|
|
286
|
+
messageId?: string;
|
|
287
|
+
/** Canonical thread identifier used for route selection, when applicable. */
|
|
288
|
+
threadId?: string | null;
|
|
289
|
+
/** Raw platform-specific event data for future use. */
|
|
290
|
+
raw?: unknown;
|
|
291
|
+
/** Broad chat surface type used for routing/pairing decisions. */
|
|
292
|
+
chatType?: ChannelChatType;
|
|
293
|
+
/** Whether this inbound message was explicitly addressed to the bot. */
|
|
294
|
+
isMention?: boolean;
|
|
295
|
+
/** Whether this message is policy-permitted ambient traffic in an open channel. */
|
|
296
|
+
isOpenChannel?: boolean;
|
|
297
|
+
/** For platform channel threads, the parent channel ID (e.g. Discord guild channel). */
|
|
298
|
+
parentChannelId?: string;
|
|
299
|
+
/** Downloaded attachments/media associated with the inbound message. */
|
|
300
|
+
attachments?: ChannelMessageAttachment[];
|
|
301
|
+
/** Reaction metadata for non-text channel events. */
|
|
302
|
+
reaction?: ChannelReactionNotification;
|
|
303
|
+
/** Platform quote/reply context for messages sent in reply to another message. */
|
|
304
|
+
replyContext?: ChannelReplyContext;
|
|
305
|
+
/** Supplemental thread context captured before the triggering message. */
|
|
306
|
+
threadContext?: ChannelThreadContext;
|
|
307
|
+
}
|
|
308
|
+
export interface ChannelRichMessage {
|
|
309
|
+
/** Rich-message HTML content. Exactly one of html or markdown should be provided. */
|
|
310
|
+
html?: string;
|
|
311
|
+
/** Rich-message Markdown content. Exactly one of html or markdown should be provided. */
|
|
312
|
+
markdown?: string;
|
|
313
|
+
/** Optional: render the rich message right-to-left. */
|
|
314
|
+
isRtl?: boolean;
|
|
315
|
+
/** Optional: disable Telegram's automatic entity detection. */
|
|
316
|
+
skipEntityDetection?: boolean;
|
|
317
|
+
}
|
|
318
|
+
export interface OutboundChannelMessage {
|
|
319
|
+
/** Platform identifier. */
|
|
320
|
+
channel: string;
|
|
321
|
+
/** Channel account that should send the outbound message. */
|
|
322
|
+
accountId?: string;
|
|
323
|
+
/** Target chat/conversation ID. */
|
|
324
|
+
chatId: string;
|
|
325
|
+
/** Message text to send. */
|
|
326
|
+
text: string;
|
|
327
|
+
/** Optional: reply to a specific message. */
|
|
328
|
+
replyToMessageId?: string;
|
|
329
|
+
/** Optional: canonical thread identifier used for threaded channels. */
|
|
330
|
+
threadId?: string | null;
|
|
331
|
+
/** Optional: parse mode hint for the adapter (e.g. "HTML", "MarkdownV2"). */
|
|
332
|
+
parseMode?: string;
|
|
333
|
+
/** Optional: rich structured message payload for channels that support it. */
|
|
334
|
+
richMessage?: ChannelRichMessage;
|
|
335
|
+
/** Optional: Signal-style text ranges (start:length:STYLE) for platforms that support rich text entities. */
|
|
336
|
+
textStyle?: string[];
|
|
337
|
+
/** Optional: attach a local file/media path for channels that support uploads. */
|
|
338
|
+
mediaPath?: string;
|
|
339
|
+
/** Optional: override the uploaded filename for media attachments. */
|
|
340
|
+
fileName?: string;
|
|
341
|
+
/** Optional: override the uploaded title/caption metadata for media attachments. */
|
|
342
|
+
title?: string;
|
|
343
|
+
/** Optional: reaction emoji to add/remove. Slack uses names; Telegram uses native emoji or custom_emoji:<id>. */
|
|
344
|
+
reaction?: string;
|
|
345
|
+
/** Optional: remove the channel reaction instead of adding it. */
|
|
346
|
+
removeReaction?: boolean;
|
|
347
|
+
/** Optional: target message id for reactions. */
|
|
348
|
+
targetMessageId?: string;
|
|
349
|
+
/** Optional: sending agent identity, used by adapters that render web deep links. */
|
|
350
|
+
agentId?: string;
|
|
351
|
+
/** Optional: conversation identity, used by adapters that render web deep links. */
|
|
352
|
+
conversationId?: string;
|
|
353
|
+
}
|
|
354
|
+
export interface OutboundChannelRichMessageDraft {
|
|
355
|
+
/** Platform identifier. */
|
|
356
|
+
channel: string;
|
|
357
|
+
/** Channel account that should send the draft. */
|
|
358
|
+
accountId?: string;
|
|
359
|
+
/** Target chat/conversation ID. */
|
|
360
|
+
chatId: string;
|
|
361
|
+
/** Optional: canonical thread identifier used for threaded channels. */
|
|
362
|
+
threadId?: string | null;
|
|
363
|
+
/** Stable non-zero platform draft identifier for animated updates. */
|
|
364
|
+
draftId: number;
|
|
365
|
+
/** Rich structured message payload for the draft preview. */
|
|
366
|
+
richMessage: ChannelRichMessage;
|
|
367
|
+
}
|
|
368
|
+
export interface ChannelRoute {
|
|
369
|
+
/** Channel account identifier. */
|
|
370
|
+
accountId?: string;
|
|
371
|
+
/** Platform-specific chat ID. */
|
|
372
|
+
chatId: string;
|
|
373
|
+
/** Broad chat surface type for this route. */
|
|
374
|
+
chatType?: ChannelChatType;
|
|
375
|
+
/** Canonical thread identifier for threaded channels, if any. */
|
|
376
|
+
threadId?: string | null;
|
|
377
|
+
/** Letta agent ID this chat is bound to. */
|
|
378
|
+
agentId: string;
|
|
379
|
+
/** Letta conversation ID this chat is bound to. */
|
|
380
|
+
conversationId: string;
|
|
381
|
+
/** Whether this route is active. */
|
|
382
|
+
enabled: boolean;
|
|
383
|
+
/** Whether this route permits outbound MessageChannel sends. Defaults true. */
|
|
384
|
+
outboundEnabled?: boolean;
|
|
385
|
+
/** Slack-only: a detached thread stays silent until the app is mentioned again. */
|
|
386
|
+
detached?: boolean;
|
|
387
|
+
/** ISO 8601 creation timestamp. */
|
|
388
|
+
createdAt: string;
|
|
389
|
+
/** ISO 8601 update timestamp. */
|
|
390
|
+
updatedAt?: string;
|
|
391
|
+
}
|
|
392
|
+
export type DmPolicy = "pairing" | "allowlist" | "open";
|
|
393
|
+
export type SlackChannelMode = "socket";
|
|
394
|
+
export type SlackAllowBotsMode = false | "mentions";
|
|
395
|
+
export type TelegramGroupMode = "open" | "mention-only";
|
|
396
|
+
export type WhatsAppGroupMode = "disabled" | "mention" | "open";
|
|
397
|
+
export type SignalGroupMode = "disabled" | "mention" | "open";
|
|
398
|
+
export interface ChannelAccountBinding {
|
|
399
|
+
agentId: string | null;
|
|
400
|
+
conversationId: string | null;
|
|
401
|
+
}
|
|
402
|
+
interface ChannelAccountBase {
|
|
403
|
+
accountId: string;
|
|
404
|
+
displayName?: string;
|
|
405
|
+
enabled: boolean;
|
|
406
|
+
dmPolicy: DmPolicy;
|
|
407
|
+
allowedUsers: string[];
|
|
408
|
+
createdAt: string;
|
|
409
|
+
updatedAt: string;
|
|
410
|
+
}
|
|
411
|
+
export interface CustomChannelAccount extends ChannelAccountBase {
|
|
412
|
+
channel: string;
|
|
413
|
+
/** Plugin-owned persisted account settings. May contain secrets. */
|
|
414
|
+
config: Record<string, unknown>;
|
|
415
|
+
}
|
|
416
|
+
export interface TelegramChannelConfig {
|
|
417
|
+
channel: "telegram";
|
|
418
|
+
enabled: boolean;
|
|
419
|
+
token: string;
|
|
420
|
+
dmPolicy: DmPolicy;
|
|
421
|
+
allowedUsers: string[];
|
|
422
|
+
/** Group/supergroup behavior: ambient open chat or explicit mentions only. */
|
|
423
|
+
groupMode?: TelegramGroupMode;
|
|
424
|
+
/** When true and OPENAI_API_KEY is set, voice memos are auto-transcribed. */
|
|
425
|
+
transcribeVoice?: boolean;
|
|
426
|
+
/**
|
|
427
|
+
* Default true. When true, normal Telegram private-chat `send` actions use
|
|
428
|
+
* Bot API Rich Messages; explicit `send-rich` remains available either way.
|
|
429
|
+
*/
|
|
430
|
+
richPrivateChatDefault?: boolean;
|
|
431
|
+
/** When true, stream hidden Telegram rich-message drafts during generation. */
|
|
432
|
+
richDraftStreaming?: boolean;
|
|
433
|
+
}
|
|
434
|
+
export interface SlackChannelConfig {
|
|
435
|
+
channel: "slack";
|
|
436
|
+
enabled: boolean;
|
|
437
|
+
mode: SlackChannelMode;
|
|
438
|
+
botToken: string;
|
|
439
|
+
appToken: string;
|
|
440
|
+
dmPolicy: DmPolicy;
|
|
441
|
+
allowedUsers: string[];
|
|
442
|
+
/** When true and OPENAI_API_KEY is set, inbound audio attachments are auto-transcribed. */
|
|
443
|
+
transcribeVoice?: boolean;
|
|
444
|
+
/** When true, unmentioned Slack thread replies are delivered read-only until an @mention. */
|
|
445
|
+
listenMode?: boolean;
|
|
446
|
+
/**
|
|
447
|
+
* Bot-authored inbound policy. Default false drops bot messages. "mentions"
|
|
448
|
+
* accepts only explicit foreign bot mentions. There is intentionally no
|
|
449
|
+
* accept-all mode until Letta has a shared pair-loop guard.
|
|
450
|
+
*/
|
|
451
|
+
allowBots?: SlackAllowBotsMode;
|
|
452
|
+
}
|
|
453
|
+
export interface DiscordChannelConfig {
|
|
454
|
+
channel: "discord";
|
|
455
|
+
enabled: boolean;
|
|
456
|
+
token: string;
|
|
457
|
+
defaultPermissionMode: DiscordDefaultPermissionMode;
|
|
458
|
+
dmPolicy: DmPolicy;
|
|
459
|
+
allowedUsers: string[];
|
|
460
|
+
/**
|
|
461
|
+
* Optional allowlist or mode map for guild channels.
|
|
462
|
+
*
|
|
463
|
+
* Legacy `string[]` — each entry is treated as "mention-only".
|
|
464
|
+
* `Record<channelId, mode>` — each channel declares its behavior:
|
|
465
|
+
* - `"open"`: respond to every non-bot message, no @mention required
|
|
466
|
+
* - `"mention-only"`: only respond when the bot is @mentioned
|
|
467
|
+
*
|
|
468
|
+
* Empty/undefined preserves the default behavior of processing
|
|
469
|
+
* all guild channels the bot can see (mention-only for non-thread
|
|
470
|
+
* messages, open for threads with an existing route).
|
|
471
|
+
*/
|
|
472
|
+
allowedChannels?: string[] | Record<string, DiscordChannelMode>;
|
|
473
|
+
/**
|
|
474
|
+
* When `true`, @mentions in non-thread guild channels auto-create a
|
|
475
|
+
* Discord thread for the conversation. When `false`, the bot replies
|
|
476
|
+
* directly in the parent channel. Default `false`; thread creation is opt-in.
|
|
477
|
+
*/
|
|
478
|
+
autoThreadOnMention?: boolean;
|
|
479
|
+
/**
|
|
480
|
+
* Per-channel override map for thread creation on @mention.
|
|
481
|
+
* Key: guild channel ID. Value: `true` to auto-create a thread on
|
|
482
|
+
* @mention in that channel, `false` to reply in-line.
|
|
483
|
+
* Resolution order: per-channel override → account-level
|
|
484
|
+
* `autoThreadOnMention` → `false`.
|
|
485
|
+
*/
|
|
486
|
+
threadPolicyByChannel?: Record<string, boolean>;
|
|
487
|
+
/**
|
|
488
|
+
* When true, the bot sends lifecycle reaction acknowledgments on messages
|
|
489
|
+
* (👀 on receipt, ✅ on completion). Default false — the typing indicator
|
|
490
|
+
* is the primary UX for in-flight feedback.
|
|
491
|
+
*/
|
|
492
|
+
acknowledgeMessageReaction?: boolean;
|
|
493
|
+
/**
|
|
494
|
+
* When true and a guild channel is removed from `allowedChannels`,
|
|
495
|
+
* stale routes for that channel can be removed by reconcile `--apply`.
|
|
496
|
+
* This only removes routes (not conversations). Default false — routes
|
|
497
|
+
* are preserved even if the channel is no longer allowed.
|
|
498
|
+
*/
|
|
499
|
+
removeStaleRoutes?: boolean;
|
|
500
|
+
/**
|
|
501
|
+
* Optional debounce window (ms) for inbound open-channel guild messages.
|
|
502
|
+
* When greater than `0`, short back-to-back messages from the same sender
|
|
503
|
+
* in the same channel/thread stack into a single combined dispatch
|
|
504
|
+
* (trailing edge). Default `0` (disabled). Only applies to
|
|
505
|
+
* open-channel messages; DMs, @mentions, attachments, and reactions always
|
|
506
|
+
* bypass.
|
|
507
|
+
* The env var `LETTA_DISCORD_INBOUND_DEBOUNCE_MS` takes precedence if set.
|
|
508
|
+
* Clamped to `0..10000`.
|
|
509
|
+
*/
|
|
510
|
+
inboundDebounceMs?: number;
|
|
511
|
+
}
|
|
512
|
+
export interface WhatsAppChannelConfig {
|
|
513
|
+
channel: "whatsapp";
|
|
514
|
+
enabled: boolean;
|
|
515
|
+
dmPolicy: DmPolicy;
|
|
516
|
+
allowedUsers: string[];
|
|
517
|
+
agentId: string | null;
|
|
518
|
+
/** Default true. When true, only the user's own Message Yourself chat routes. */
|
|
519
|
+
selfChatMode: boolean;
|
|
520
|
+
/** Default disabled. Controls group-message ingestion. */
|
|
521
|
+
groupMode: WhatsAppGroupMode;
|
|
522
|
+
/** Optional allowlist of WhatsApp group JIDs. Empty/undefined allows any group when groupMode is not disabled. */
|
|
523
|
+
allowedGroups?: string[];
|
|
524
|
+
/** Optional textual aliases for group mention detection. */
|
|
525
|
+
mentionPatterns?: string[];
|
|
526
|
+
/** When true and OPENAI_API_KEY is set, voice memos are auto-transcribed. */
|
|
527
|
+
transcribeVoice?: boolean;
|
|
528
|
+
/** When true, supported inbound media is downloaded to local channel storage. */
|
|
529
|
+
downloadMedia?: boolean;
|
|
530
|
+
/** Maximum inbound media bytes to download. Undefined uses channel default. */
|
|
531
|
+
mediaMaxBytes?: number;
|
|
532
|
+
}
|
|
533
|
+
export interface SignalChannelConfig {
|
|
534
|
+
channel: "signal";
|
|
535
|
+
enabled: boolean;
|
|
536
|
+
dmPolicy: DmPolicy;
|
|
537
|
+
allowedUsers: string[];
|
|
538
|
+
/** Base URL for a Signal JSON-RPC/SSE bridge, e.g. http://127.0.0.1:8080. */
|
|
539
|
+
baseUrl: string;
|
|
540
|
+
/** Optional signal-cli account selector, usually the linked phone number. */
|
|
541
|
+
account?: string;
|
|
542
|
+
/** Optional UUID for self-message filtering when Signal sends UUID identities. */
|
|
543
|
+
accountUuid?: string;
|
|
544
|
+
/** Agent ID used for account-bound DM and group auto-routing. */
|
|
545
|
+
agentId: string | null;
|
|
546
|
+
/** Default false. When true, only the linked account's own Note to Self/self-chat messages route. */
|
|
547
|
+
selfChatMode: boolean;
|
|
548
|
+
/** Default disabled. Controls group-message ingestion. */
|
|
549
|
+
groupMode: SignalGroupMode;
|
|
550
|
+
/** Optional allowlist of Signal group ids. */
|
|
551
|
+
allowedGroups?: string[];
|
|
552
|
+
/** Optional textual aliases for group mention detection. */
|
|
553
|
+
mentionPatterns?: string[];
|
|
554
|
+
/** Optional sender identity -> replyable Signal recipient mapping, e.g. UUID to E.164 phone. */
|
|
555
|
+
recipientAliases?: Record<string, string>;
|
|
556
|
+
/** When true and OPENAI_API_KEY is set, inbound audio attachments are auto-transcribed. */
|
|
557
|
+
transcribeVoice?: boolean;
|
|
558
|
+
/** Default true. When true, supported inbound media is downloaded and surfaced to the agent. */
|
|
559
|
+
downloadMedia?: boolean;
|
|
560
|
+
/** Maximum inbound media bytes to consider. Undefined uses channel default. */
|
|
561
|
+
mediaMaxBytes?: number;
|
|
562
|
+
}
|
|
563
|
+
export type ChannelConfig = TelegramChannelConfig | SlackChannelConfig | DiscordChannelConfig | WhatsAppChannelConfig | SignalChannelConfig;
|
|
564
|
+
export interface TelegramChannelAccount extends ChannelAccountBase {
|
|
565
|
+
channel: "telegram";
|
|
566
|
+
token: string;
|
|
567
|
+
binding: ChannelAccountBinding;
|
|
568
|
+
/**
|
|
569
|
+
* Group/supergroup behavior. `open` preserves existing ambient room routing;
|
|
570
|
+
* `mention-only` only delivers messages explicitly addressed to this bot.
|
|
571
|
+
*/
|
|
572
|
+
groupMode?: TelegramGroupMode;
|
|
573
|
+
/** When true and OPENAI_API_KEY is set, voice memos are auto-transcribed. */
|
|
574
|
+
transcribeVoice?: boolean;
|
|
575
|
+
/**
|
|
576
|
+
* Default true. When true, normal Telegram private-chat MessageChannel sends
|
|
577
|
+
* are delivered through Bot API Rich Messages. Set false to keep `send`
|
|
578
|
+
* plain/HTML-formatted unless the agent explicitly uses `send-rich`.
|
|
579
|
+
*/
|
|
580
|
+
richPrivateChatDefault?: boolean;
|
|
581
|
+
/**
|
|
582
|
+
* When true, Telegram channel turns may stream hidden rich-message drafts
|
|
583
|
+
* while the agent is preparing a final MessageChannel send-rich call.
|
|
584
|
+
*/
|
|
585
|
+
richDraftStreaming?: boolean;
|
|
586
|
+
/**
|
|
587
|
+
* Optional debounce window (ms) for inbound group/topic messages. When
|
|
588
|
+
* greater than `0`, short back-to-back text messages in the same chat/topic
|
|
589
|
+
* stack into a single combined dispatch (trailing edge). Default `0`
|
|
590
|
+
* (disabled). DMs, attachments, and reactions bypass. The env var
|
|
591
|
+
* `LETTA_TELEGRAM_INBOUND_DEBOUNCE_MS` takes precedence if set. Clamped to
|
|
592
|
+
* `0..10000`.
|
|
593
|
+
*/
|
|
594
|
+
inboundDebounceMs?: number;
|
|
595
|
+
}
|
|
596
|
+
export interface SlackChannelAccount extends ChannelAccountBase {
|
|
597
|
+
channel: "slack";
|
|
598
|
+
mode: SlackChannelMode;
|
|
599
|
+
botToken: string;
|
|
600
|
+
appToken: string;
|
|
601
|
+
agentId: string | null;
|
|
602
|
+
defaultPermissionMode: SlackDefaultPermissionMode;
|
|
603
|
+
/** When true and OPENAI_API_KEY is set, inbound audio attachments are auto-transcribed. */
|
|
604
|
+
transcribeVoice?: boolean;
|
|
605
|
+
/** When true, unmentioned Slack thread replies are delivered read-only until an @mention. */
|
|
606
|
+
listenMode?: boolean;
|
|
607
|
+
/**
|
|
608
|
+
* Bot-authored inbound policy. Default false drops bot messages. "mentions"
|
|
609
|
+
* accepts only explicit foreign bot mentions. There is intentionally no
|
|
610
|
+
* accept-all mode until Letta has a shared pair-loop guard.
|
|
611
|
+
*/
|
|
612
|
+
allowBots?: SlackAllowBotsMode;
|
|
613
|
+
/**
|
|
614
|
+
* Optional debounce window (ms) for inbound messages. When greater than
|
|
615
|
+
* `0`, short back-to-back messages from the same sender in the same
|
|
616
|
+
* chat/thread stack into a single combined dispatch (trailing edge).
|
|
617
|
+
* Default `0` (disabled). Messages with attachments bypass the debounce.
|
|
618
|
+
* The env var `LETTA_SLACK_INBOUND_DEBOUNCE_MS` takes precedence if set.
|
|
619
|
+
*/
|
|
620
|
+
inboundDebounceMs?: number;
|
|
621
|
+
}
|
|
622
|
+
export interface DiscordChannelAccount extends ChannelAccountBase {
|
|
623
|
+
channel: "discord";
|
|
624
|
+
token: string;
|
|
625
|
+
/** When true and OPENAI_API_KEY is set, inbound audio attachments are auto-transcribed. */
|
|
626
|
+
transcribeVoice?: boolean;
|
|
627
|
+
/** Agent ID used for account-bound DM and guild auto-routing. */
|
|
628
|
+
agentId: string | null;
|
|
629
|
+
/** Permission mode for new Discord-created conversations. */
|
|
630
|
+
defaultPermissionMode: DiscordDefaultPermissionMode;
|
|
631
|
+
/**
|
|
632
|
+
* Optional allowlist or mode map for guild channels.
|
|
633
|
+
*
|
|
634
|
+
* Legacy `string[]` — each entry is treated as "mention-only".
|
|
635
|
+
* `Record<channelId, mode>` — each channel declares its behavior:
|
|
636
|
+
* - `"open"`: respond to every non-bot message, no @mention required
|
|
637
|
+
* - `"mention-only"`: only respond when the bot is @mentioned
|
|
638
|
+
*
|
|
639
|
+
* Empty/undefined preserves the default behavior of processing
|
|
640
|
+
* all guild channels the bot can see. DMs are unaffected.
|
|
641
|
+
*/
|
|
642
|
+
allowedChannels?: string[] | Record<string, DiscordChannelMode>;
|
|
643
|
+
/**
|
|
644
|
+
* When `true`, @mentions in non-thread guild channels auto-create a
|
|
645
|
+
* Discord thread for the conversation. When `false`, the bot replies
|
|
646
|
+
* directly in the parent channel. Default `false`; thread creation is opt-in.
|
|
647
|
+
*/
|
|
648
|
+
autoThreadOnMention?: boolean;
|
|
649
|
+
/**
|
|
650
|
+
* Per-channel override map for thread creation on @mention.
|
|
651
|
+
* Key: guild channel ID. Value: `true` to auto-create a thread on
|
|
652
|
+
* @mention in that channel, `false` to reply in-line.
|
|
653
|
+
* Resolution order: per-channel override → account-level
|
|
654
|
+
* `autoThreadOnMention` → `false`.
|
|
655
|
+
*/
|
|
656
|
+
threadPolicyByChannel?: Record<string, boolean>;
|
|
657
|
+
/**
|
|
658
|
+
* When true, the bot sends lifecycle reaction acknowledgments on messages
|
|
659
|
+
* (👀 on receipt, ✅ on completion). Default false — the typing indicator
|
|
660
|
+
* is the primary UX for in-flight feedback.
|
|
661
|
+
*/
|
|
662
|
+
acknowledgeMessageReaction?: boolean;
|
|
663
|
+
/**
|
|
664
|
+
* When true and a guild channel is removed from `allowedChannels`,
|
|
665
|
+
* stale routes for that channel can be removed by reconcile `--apply`.
|
|
666
|
+
* This only removes routes (not conversations). Default false — routes
|
|
667
|
+
* are preserved even if the channel is no longer allowed.
|
|
668
|
+
*/
|
|
669
|
+
removeStaleRoutes?: boolean;
|
|
670
|
+
/**
|
|
671
|
+
* Optional debounce window (ms) for inbound open-channel guild messages.
|
|
672
|
+
* When greater than `0`, short back-to-back messages from the same sender
|
|
673
|
+
* in the same channel/thread stack into a single combined dispatch
|
|
674
|
+
* (trailing edge). Default `0` (disabled). Only applies to
|
|
675
|
+
* open-channel messages; DMs, @mentions, attachments, and reactions always
|
|
676
|
+
* bypass.
|
|
677
|
+
* The env var `LETTA_DISCORD_INBOUND_DEBOUNCE_MS` takes precedence if set.
|
|
678
|
+
* Clamped to `0..10000`.
|
|
679
|
+
*/
|
|
680
|
+
inboundDebounceMs?: number;
|
|
681
|
+
}
|
|
682
|
+
export interface WhatsAppChannelAccount extends ChannelAccountBase {
|
|
683
|
+
channel: "whatsapp";
|
|
684
|
+
/** Agent ID used for account-bound DM and group auto-routing. */
|
|
685
|
+
agentId: string | null;
|
|
686
|
+
/** Default true. Explicitly set false before replying under the linked user's identity. */
|
|
687
|
+
selfChatMode: boolean;
|
|
688
|
+
/** Default disabled. Controls group-message ingestion. */
|
|
689
|
+
groupMode: WhatsAppGroupMode;
|
|
690
|
+
/** Optional allowlist of WhatsApp group JIDs. */
|
|
691
|
+
allowedGroups?: string[];
|
|
692
|
+
/** Optional textual aliases for group mention detection. */
|
|
693
|
+
mentionPatterns?: string[];
|
|
694
|
+
/** When true and OPENAI_API_KEY is set, voice memos are auto-transcribed. */
|
|
695
|
+
transcribeVoice?: boolean;
|
|
696
|
+
/** When true, supported inbound media is downloaded to local channel storage. */
|
|
697
|
+
downloadMedia?: boolean;
|
|
698
|
+
/** Maximum inbound media bytes to download. Undefined uses channel default. */
|
|
699
|
+
mediaMaxBytes?: number;
|
|
700
|
+
}
|
|
701
|
+
export interface SignalChannelAccount extends ChannelAccountBase {
|
|
702
|
+
channel: "signal";
|
|
703
|
+
/** Base URL for a Signal JSON-RPC/SSE bridge, e.g. http://127.0.0.1:8080. */
|
|
704
|
+
baseUrl: string;
|
|
705
|
+
/** Optional signal-cli account selector, usually the linked phone number. */
|
|
706
|
+
account?: string;
|
|
707
|
+
/** Optional UUID for self-message filtering when Signal sends UUID identities. */
|
|
708
|
+
accountUuid?: string;
|
|
709
|
+
/** Agent ID used for account-bound DM and group auto-routing. */
|
|
710
|
+
agentId: string | null;
|
|
711
|
+
/** Default false. When true, only the linked account's own Note to Self/self-chat messages route. */
|
|
712
|
+
selfChatMode: boolean;
|
|
713
|
+
/** Default disabled. Controls group-message ingestion. */
|
|
714
|
+
groupMode: SignalGroupMode;
|
|
715
|
+
/** Optional allowlist of Signal group ids. */
|
|
716
|
+
allowedGroups?: string[];
|
|
717
|
+
/** Optional textual aliases for group mention detection. */
|
|
718
|
+
mentionPatterns?: string[];
|
|
719
|
+
/** Optional sender identity -> replyable Signal recipient mapping, e.g. UUID to E.164 phone. */
|
|
720
|
+
recipientAliases?: Record<string, string>;
|
|
721
|
+
/** When true and OPENAI_API_KEY is set, inbound audio attachments are auto-transcribed. */
|
|
722
|
+
transcribeVoice?: boolean;
|
|
723
|
+
/** Default true. When true, supported inbound media is downloaded and surfaced to the agent. */
|
|
724
|
+
downloadMedia?: boolean;
|
|
725
|
+
/** Maximum inbound media bytes to consider. Undefined uses channel default. */
|
|
726
|
+
mediaMaxBytes?: number;
|
|
727
|
+
}
|
|
728
|
+
export type ChannelAccount = TelegramChannelAccount | SlackChannelAccount | DiscordChannelAccount | WhatsAppChannelAccount | SignalChannelAccount | CustomChannelAccount;
|
|
729
|
+
export declare function isFirstPartyChannelId(channelId: string): channelId is FirstPartyChannelId;
|
|
730
|
+
export declare function isTelegramChannelAccount(account: ChannelAccount): account is TelegramChannelAccount;
|
|
731
|
+
export declare function isSlackChannelAccount(account: ChannelAccount): account is SlackChannelAccount;
|
|
732
|
+
export declare function isDiscordChannelAccount(account: ChannelAccount): account is DiscordChannelAccount;
|
|
733
|
+
export declare function isWhatsAppChannelAccount(account: ChannelAccount): account is WhatsAppChannelAccount;
|
|
734
|
+
export declare function isSignalChannelAccount(account: ChannelAccount): account is SignalChannelAccount;
|
|
735
|
+
export declare function isCustomChannelAccount(account: ChannelAccount): account is CustomChannelAccount;
|
|
736
|
+
export interface PendingPairing {
|
|
737
|
+
accountId?: string;
|
|
738
|
+
code: string;
|
|
739
|
+
senderId: string;
|
|
740
|
+
senderName?: string;
|
|
741
|
+
chatId: string;
|
|
742
|
+
createdAt: string;
|
|
743
|
+
expiresAt: string;
|
|
744
|
+
}
|
|
745
|
+
export interface ApprovedUser {
|
|
746
|
+
accountId?: string;
|
|
747
|
+
senderId: string;
|
|
748
|
+
senderName?: string;
|
|
749
|
+
approvedAt: string;
|
|
750
|
+
}
|
|
751
|
+
export interface PairingStore {
|
|
752
|
+
pending: PendingPairing[];
|
|
753
|
+
approved: ApprovedUser[];
|
|
754
|
+
}
|
|
755
|
+
export interface ChannelBindableTarget {
|
|
756
|
+
accountId?: string;
|
|
757
|
+
targetId: string;
|
|
758
|
+
targetType: "channel";
|
|
759
|
+
chatId: string;
|
|
760
|
+
label: string;
|
|
761
|
+
discoveredAt: string;
|
|
762
|
+
lastSeenAt: string;
|
|
763
|
+
lastMessageId?: string;
|
|
764
|
+
}
|
|
765
|
+
export {};
|
|
766
|
+
//# sourceMappingURL=types.d.ts.map
|