@letta-ai/letta-code 0.30.24 → 0.30.26

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.
Files changed (55) hide show
  1. package/dist/agent-presets.js +1 -339
  2. package/dist/agent-presets.js.map +2 -2
  3. package/dist/channels-slack.js +319 -41
  4. package/dist/channels-slack.js.map +4 -3
  5. package/dist/channels-telegram.js +424 -0
  6. package/dist/channels-telegram.js.map +14 -0
  7. package/dist/mcp-client.js +2 -2
  8. package/dist/mcp-client.js.map +1 -1
  9. package/dist/types/agent/client-skills-watcher.d.ts +23 -0
  10. package/dist/types/agent/client-skills-watcher.d.ts.map +1 -0
  11. package/dist/types/agent/client-skills.d.ts.map +1 -1
  12. package/dist/types/agent/modify.d.ts.map +1 -1
  13. package/dist/types/backend/dev/pi-model-factory.d.ts.map +1 -1
  14. package/dist/types/channels/slack/attachment-primitives.d.ts +69 -0
  15. package/dist/types/channels/slack/attachment-primitives.d.ts.map +1 -0
  16. package/dist/types/channels/telegram/debounce.d.ts +22 -0
  17. package/dist/types/channels/telegram/debounce.d.ts.map +1 -0
  18. package/dist/types/channels/telegram/ingress.d.ts +35 -0
  19. package/dist/types/channels/telegram/ingress.d.ts.map +1 -0
  20. package/dist/types/channels/telegram/message-action-contract.d.ts +16 -0
  21. package/dist/types/channels/telegram/message-action-contract.d.ts.map +1 -0
  22. package/dist/types/channels/telegram/message-shapes.d.ts +154 -0
  23. package/dist/types/channels/telegram/message-shapes.d.ts.map +1 -0
  24. package/dist/types/channels/telegram/outbound.d.ts +21 -0
  25. package/dist/types/channels/telegram/outbound.d.ts.map +1 -0
  26. package/dist/types/channels-slack.d.ts +2 -0
  27. package/dist/types/channels-slack.d.ts.map +1 -1
  28. package/dist/types/channels-telegram.d.ts +20 -0
  29. package/dist/types/channels-telegram.d.ts.map +1 -0
  30. package/dist/types/cli/helpers/stream-debug.d.ts +6 -0
  31. package/dist/types/cli/helpers/stream-debug.d.ts.map +1 -0
  32. package/dist/types/cli/helpers/stream-stall-reconciler.d.ts +16 -0
  33. package/dist/types/cli/helpers/stream-stall-reconciler.d.ts.map +1 -0
  34. package/dist/types/cli/helpers/stream.d.ts +1 -0
  35. package/dist/types/cli/helpers/stream.d.ts.map +1 -1
  36. package/dist/types/tools/impl/bash.d.ts.map +1 -1
  37. package/dist/types/tools/impl/exec-command.d.ts +1 -0
  38. package/dist/types/tools/impl/exec-command.d.ts.map +1 -1
  39. package/dist/types/tools/impl/github-pull-request-tracker.d.ts +2 -0
  40. package/dist/types/tools/impl/github-pull-request-tracker.d.ts.map +1 -1
  41. package/dist/types/tools/impl/monitor.d.ts.map +1 -1
  42. package/dist/types/tools/impl/process_manager.d.ts +7 -1
  43. package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
  44. package/dist/types/tools/impl/task.d.ts +2 -0
  45. package/dist/types/tools/impl/task.d.ts.map +1 -1
  46. package/dist/types/utils/openai-reasoning-effort.d.ts +6 -0
  47. package/dist/types/utils/openai-reasoning-effort.d.ts.map +1 -0
  48. package/dist/types/websocket/listener/constants.d.ts +0 -2
  49. package/dist/types/websocket/listener/constants.d.ts.map +1 -1
  50. package/dist/types/websocket/listener/types.d.ts +3 -0
  51. package/dist/types/websocket/listener/types.d.ts.map +1 -1
  52. package/letta.js +2741 -2642
  53. package/package.json +12 -1
  54. package/scripts/source-file-size-baseline.json +6 -7
  55. package/skills/teleporting-between-environments/SKILL.md +23 -9
@@ -0,0 +1,424 @@
1
+ // src/channels/telegram/debounce.ts
2
+ var TELEGRAM_DEBOUNCE_DEFAULT_MS = 0;
3
+ var TELEGRAM_DEBOUNCE_MAX_MS = 1e4;
4
+ function resolveTelegramInboundDebounceMs(config) {
5
+ const raw = typeof process === "undefined" ? undefined : process.env.LETTA_TELEGRAM_INBOUND_DEBOUNCE_MS;
6
+ if (typeof raw === "string" && raw.trim() !== "") {
7
+ const envOverride = Number(raw);
8
+ if (Number.isFinite(envOverride) && envOverride >= 0) {
9
+ return Math.trunc(Math.min(envOverride, TELEGRAM_DEBOUNCE_MAX_MS));
10
+ }
11
+ }
12
+ const fromConfig = config.inboundDebounceMs;
13
+ if (typeof fromConfig === "number" && Number.isFinite(fromConfig) && fromConfig >= 0) {
14
+ return Math.trunc(Math.min(fromConfig, TELEGRAM_DEBOUNCE_MAX_MS));
15
+ }
16
+ return TELEGRAM_DEBOUNCE_DEFAULT_MS;
17
+ }
18
+ function buildTelegramDebounceKey(input, accountId) {
19
+ if (!input.chatId.trim()) {
20
+ return null;
21
+ }
22
+ return `telegram:${accountId}:${input.chatId}:${input.threadId ?? "main"}`;
23
+ }
24
+ // src/channels/telegram/message-shapes.ts
25
+ function extractTelegramMessageText(message) {
26
+ if (typeof message.text === "string") {
27
+ return message.text;
28
+ }
29
+ if (typeof message.caption === "string") {
30
+ return message.caption;
31
+ }
32
+ return "";
33
+ }
34
+ function getTelegramSenderName(message) {
35
+ if (!message.from) {
36
+ return;
37
+ }
38
+ return message.from.username ?? ([message.from.first_name, message.from.last_name].filter(Boolean).join(" ") || undefined);
39
+ }
40
+
41
+ // src/channels/telegram/ingress.ts
42
+ function escapeRegExp(value) {
43
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
44
+ }
45
+ function getTelegramMessageEntities(message) {
46
+ return message.text !== undefined ? message.entities ?? [] : message.caption_entities ?? [];
47
+ }
48
+ function detectTelegramBotMention(message, botUsername, botDisplayName, text = extractTelegramMessageText(message)) {
49
+ const username = botUsername?.trim().replace(/^@/, "");
50
+ const displayName = botDisplayName?.trim();
51
+ if (!username && !displayName) {
52
+ return { isMention: false, text };
53
+ }
54
+ const mention = username ? `@${username}` : null;
55
+ const mentionRegex = mention ? new RegExp(`(^|\\s)${escapeRegExp(mention)}(?=$|\\s|[,.!?;:])`, "i") : null;
56
+ const entityMentioned = getTelegramMessageEntities(message).some((entity) => {
57
+ if (!mention)
58
+ return false;
59
+ if (entity.type !== "mention")
60
+ return false;
61
+ if (typeof entity.offset !== "number" || typeof entity.length !== "number" || entity.offset < 0 || entity.length <= 0) {
62
+ return false;
63
+ }
64
+ return text.slice(entity.offset, entity.offset + entity.length).toLowerCase() === mention.toLowerCase();
65
+ });
66
+ const regexMentioned = mentionRegex?.test(text) ?? false;
67
+ const leadingNameRegex = displayName ? new RegExp(`^\\s*${escapeRegExp(displayName)}(?:[:,]?\\s+|[,:]\\s*|$)`, "i") : null;
68
+ const leadingNameMentioned = leadingNameRegex?.test(text) ?? false;
69
+ const isMention = entityMentioned || regexMentioned || leadingNameMentioned;
70
+ if (!isMention) {
71
+ return { isMention: false, text };
72
+ }
73
+ const leadingMentionRegex = mention ? new RegExp(`^\\s*${escapeRegExp(mention)}(?:[:,]?\\s*|$)`, "i") : null;
74
+ const stripped = leadingMentionRegex ? text.replace(leadingMentionRegex, "") : text;
75
+ return {
76
+ isMention: true,
77
+ text: leadingNameRegex ? stripped.replace(leadingNameRegex, "").trimStart() : stripped.trimStart()
78
+ };
79
+ }
80
+ function getTelegramChatType(chat) {
81
+ return !chat.type || chat.type === "private" ? "direct" : "channel";
82
+ }
83
+ function getTelegramChatLabel(message) {
84
+ const title = message.chat.title?.trim();
85
+ if (title) {
86
+ return title;
87
+ }
88
+ const username = message.chat.username?.trim();
89
+ if (username) {
90
+ return username.startsWith("@") ? username : `@${username}`;
91
+ }
92
+ return;
93
+ }
94
+ function getTelegramMessageThreadId(message) {
95
+ return message.message_thread_id !== undefined ? String(message.message_thread_id) : null;
96
+ }
97
+ function getTelegramReplyContext(message) {
98
+ const replied = message.reply_to_message;
99
+ if (!replied) {
100
+ return;
101
+ }
102
+ const text = extractTelegramMessageText(replied).trim();
103
+ const context = {
104
+ messageId: String(replied.message_id)
105
+ };
106
+ if (replied.from?.id !== undefined) {
107
+ context.senderId = String(replied.from.id);
108
+ }
109
+ const senderName = getTelegramSenderName(replied);
110
+ if (senderName) {
111
+ context.senderName = senderName;
112
+ }
113
+ if (text) {
114
+ context.text = text;
115
+ }
116
+ return context;
117
+ }
118
+ function getTelegramReactionToken(reaction) {
119
+ switch (reaction.type) {
120
+ case "emoji":
121
+ return reaction.emoji?.trim() || null;
122
+ case "custom_emoji":
123
+ return reaction.custom_emoji_id?.trim() ? `custom_emoji:${reaction.custom_emoji_id.trim()}` : null;
124
+ case "paid":
125
+ return "paid";
126
+ default:
127
+ return null;
128
+ }
129
+ }
130
+ function getTelegramReactionSenderName(update) {
131
+ if (update.user) {
132
+ return getTelegramSenderName({
133
+ from: update.user
134
+ });
135
+ }
136
+ if (update.actor_chat?.username?.trim()) {
137
+ return update.actor_chat.username.trim();
138
+ }
139
+ if (update.actor_chat?.title?.trim()) {
140
+ return update.actor_chat.title.trim();
141
+ }
142
+ return;
143
+ }
144
+ function getTelegramReactionSenderId(update) {
145
+ if (update.user?.id !== undefined) {
146
+ return String(update.user.id);
147
+ }
148
+ if (update.actor_chat?.id !== undefined) {
149
+ return String(update.actor_chat.id);
150
+ }
151
+ return null;
152
+ }
153
+ function diffTelegramReactionUpdate(update) {
154
+ const oldTokens = new Set(update.old_reaction.map((reaction) => getTelegramReactionToken(reaction)).filter((value) => typeof value === "string"));
155
+ const newTokens = new Set(update.new_reaction.map((reaction) => getTelegramReactionToken(reaction)).filter((value) => typeof value === "string"));
156
+ const events = [];
157
+ for (const emoji of oldTokens) {
158
+ if (!newTokens.has(emoji)) {
159
+ events.push({ action: "removed", emoji });
160
+ }
161
+ }
162
+ for (const emoji of newTokens) {
163
+ if (!oldTokens.has(emoji)) {
164
+ events.push({ action: "added", emoji });
165
+ }
166
+ }
167
+ return events;
168
+ }
169
+ // src/channels/telegram/message-action-contract.ts
170
+ function shouldSendTelegramRichMessage(params) {
171
+ if (params.request.action === "send-rich") {
172
+ return true;
173
+ }
174
+ return params.request.action === "send" && params.route.chatType === "direct" && params.richPrivateChatDefaultEnabled(params.route) && !params.request.mediaPath?.trim();
175
+ }
176
+ function resolveTelegramRouteThreadId(ctx) {
177
+ const requestThreadId = ctx.request.threadId?.trim();
178
+ if (requestThreadId) {
179
+ return requestThreadId;
180
+ }
181
+ if (ctx.route.chatType === "direct") {
182
+ return null;
183
+ }
184
+ const routeThreadId = ctx.route.threadId?.trim();
185
+ if (!routeThreadId) {
186
+ return null;
187
+ }
188
+ return ctx.route.chatId.trim().startsWith("-") ? routeThreadId : null;
189
+ }
190
+ function createTelegramMessageActionAdapter(options = {}) {
191
+ const richPrivateChatDefaultEnabled = options.richPrivateChatDefaultEnabled ?? (() => true);
192
+ return {
193
+ describeMessageTool() {
194
+ return {
195
+ actions: ["send", "send-rich", "react", "upload-file"]
196
+ };
197
+ },
198
+ async handleAction(ctx) {
199
+ const { request, route, adapter, formatText } = ctx;
200
+ if (request.action !== "send" && request.action !== "send-rich" && request.action !== "react" && request.action !== "upload-file") {
201
+ return `Error: Action "${request.action}" is not supported on telegram.`;
202
+ }
203
+ if (request.action === "react") {
204
+ if (!request.emoji?.trim() && !request.remove) {
205
+ return "Error: Telegram react requires emoji.";
206
+ }
207
+ if (!request.messageId?.trim()) {
208
+ return "Error: Telegram react requires messageId.";
209
+ }
210
+ const result2 = await adapter.sendMessage({
211
+ channel: "telegram",
212
+ accountId: route.accountId,
213
+ chatId: request.chatId,
214
+ text: "",
215
+ targetMessageId: request.messageId,
216
+ reaction: request.emoji,
217
+ removeReaction: request.remove
218
+ });
219
+ return request.remove ? `Reaction removed on telegram (message_id: ${result2.messageId})` : `Reaction added on telegram (message_id: ${result2.messageId})`;
220
+ }
221
+ if (request.action === "send-rich") {
222
+ if (!request.message?.trim()) {
223
+ return "Error: Telegram send-rich requires message.";
224
+ }
225
+ if (request.mediaPath?.trim()) {
226
+ return "Error: Telegram send-rich does not support local media uploads; use upload-file instead.";
227
+ }
228
+ }
229
+ if (!request.message?.trim() && !request.mediaPath?.trim()) {
230
+ return "Error: Telegram send requires message or media.";
231
+ }
232
+ if (request.action === "upload-file" && !request.mediaPath?.trim()) {
233
+ return "Error: Telegram upload-file requires media.";
234
+ }
235
+ if (request.action === "send" && !request.message?.trim()) {
236
+ return "Error: Telegram send requires message.";
237
+ }
238
+ const formatted = formatText(request.message ?? "");
239
+ const sendRichMessage = shouldSendTelegramRichMessage({
240
+ request,
241
+ route,
242
+ richPrivateChatDefaultEnabled
243
+ });
244
+ const result = await adapter.sendMessage({
245
+ channel: "telegram",
246
+ accountId: route.accountId,
247
+ chatId: request.chatId,
248
+ text: formatted.text,
249
+ replyToMessageId: request.replyToMessageId,
250
+ threadId: resolveTelegramRouteThreadId(ctx),
251
+ mediaPath: request.mediaPath,
252
+ fileName: request.filename,
253
+ title: request.title,
254
+ parseMode: formatted.parseMode,
255
+ ...sendRichMessage ? { richMessage: { markdown: request.message ?? "" } } : {}
256
+ });
257
+ return request.mediaPath ? `Attachment sent to telegram (message_id: ${result.messageId})` : `Message sent to telegram (message_id: ${result.messageId})`;
258
+ }
259
+ };
260
+ }
261
+ // src/channels/telegram/outbound.ts
262
+ function resolveTelegramOutboundThreadId(msg) {
263
+ return msg.threadId?.trim() || null;
264
+ }
265
+ function buildTelegramReplyOptions(msg) {
266
+ const options = {};
267
+ const threadId = resolveTelegramOutboundThreadId(msg);
268
+ if (threadId) {
269
+ options.message_thread_id = Number(threadId);
270
+ }
271
+ if (msg.replyToMessageId) {
272
+ options.reply_parameters = {
273
+ message_id: Number(msg.replyToMessageId)
274
+ };
275
+ }
276
+ if (msg.text.trim().length > 0) {
277
+ options.caption = msg.text;
278
+ if (msg.parseMode) {
279
+ options.parse_mode = msg.parseMode;
280
+ }
281
+ }
282
+ if (msg.title?.trim()) {
283
+ options.title = msg.title.trim();
284
+ }
285
+ return options;
286
+ }
287
+ function toTelegramInputRichMessage(richMessage) {
288
+ const html = richMessage.html?.trim() ? richMessage.html : undefined;
289
+ const markdown = richMessage.markdown?.trim() ? richMessage.markdown : undefined;
290
+ if (!html && !markdown) {
291
+ throw new Error("Telegram rich messages require html or markdown content.");
292
+ }
293
+ if (html && markdown) {
294
+ throw new Error("Telegram rich messages require exactly one of html or markdown.");
295
+ }
296
+ const input = html ? { html } : { markdown };
297
+ if (richMessage.isRtl !== undefined) {
298
+ input.is_rtl = richMessage.isRtl;
299
+ }
300
+ if (richMessage.skipEntityDetection !== undefined) {
301
+ input.skip_entity_detection = richMessage.skipEntityDetection;
302
+ }
303
+ return input;
304
+ }
305
+ function buildTelegramRichMessagePayload(msg) {
306
+ if (!msg.richMessage) {
307
+ throw new Error("Telegram rich message payload missing richMessage.");
308
+ }
309
+ const payload = {
310
+ chat_id: msg.chatId,
311
+ rich_message: toTelegramInputRichMessage(msg.richMessage)
312
+ };
313
+ const threadId = resolveTelegramOutboundThreadId(msg);
314
+ if (threadId) {
315
+ payload.message_thread_id = Number(threadId);
316
+ }
317
+ if (msg.replyToMessageId) {
318
+ payload.reply_parameters = {
319
+ message_id: Number(msg.replyToMessageId)
320
+ };
321
+ }
322
+ return payload;
323
+ }
324
+ function buildTelegramRichMessageDraftPayload(draft) {
325
+ const payload = {
326
+ chat_id: draft.chatId,
327
+ draft_id: draft.draftId,
328
+ rich_message: toTelegramInputRichMessage(draft.richMessage)
329
+ };
330
+ const threadId = resolveTelegramOutboundThreadId(draft);
331
+ if (threadId) {
332
+ payload.message_thread_id = Number(threadId);
333
+ }
334
+ return payload;
335
+ }
336
+ function getTelegramErrorText(error) {
337
+ if (error instanceof Error) {
338
+ return error.message;
339
+ }
340
+ if (typeof error === "object" && error !== null) {
341
+ const maybeError = error;
342
+ if (typeof maybeError.description === "string") {
343
+ return maybeError.description;
344
+ }
345
+ if (typeof maybeError.message === "string") {
346
+ return maybeError.message;
347
+ }
348
+ }
349
+ return String(error);
350
+ }
351
+ function shouldFallbackTelegramRichMessage(error) {
352
+ const text = getTelegramErrorText(error).toLowerCase();
353
+ if (text.includes("message thread") || text.includes("thread not found")) {
354
+ return false;
355
+ }
356
+ const mentionsRichMessage = text.includes("sendrichmessage") || text.includes("rich message") || text.includes("rich_message");
357
+ const mentionsRichFormatting = mentionsRichMessage || text.includes("markdown") || text.includes("html") || text.includes("entity") || text.includes("entities");
358
+ if (text.includes("unsupported")) {
359
+ return true;
360
+ }
361
+ if (text.includes("not found") && (text.includes("404") || text.includes("method"))) {
362
+ return true;
363
+ }
364
+ if (text.includes("can't parse") || text.includes("cannot parse")) {
365
+ return true;
366
+ }
367
+ if (mentionsRichFormatting && text.includes("parse")) {
368
+ return true;
369
+ }
370
+ if (mentionsRichFormatting && text.includes("invalid")) {
371
+ return true;
372
+ }
373
+ return mentionsRichMessage && text.includes("bad request");
374
+ }
375
+ function parseTelegramReactionInput(reaction) {
376
+ const trimmed = reaction.trim();
377
+ if (!trimmed) {
378
+ return null;
379
+ }
380
+ const customEmojiPrefix = "custom_emoji:";
381
+ if (trimmed.startsWith(customEmojiPrefix)) {
382
+ const customEmojiId = trimmed.slice(customEmojiPrefix.length).trim();
383
+ if (!customEmojiId) {
384
+ return null;
385
+ }
386
+ return {
387
+ type: "custom_emoji",
388
+ custom_emoji_id: customEmojiId
389
+ };
390
+ }
391
+ return {
392
+ type: "emoji",
393
+ emoji: trimmed
394
+ };
395
+ }
396
+ export {
397
+ toTelegramInputRichMessage,
398
+ shouldFallbackTelegramRichMessage,
399
+ resolveTelegramOutboundThreadId,
400
+ resolveTelegramInboundDebounceMs,
401
+ parseTelegramReactionInput,
402
+ getTelegramSenderName,
403
+ getTelegramReplyContext,
404
+ getTelegramReactionToken,
405
+ getTelegramReactionSenderName,
406
+ getTelegramReactionSenderId,
407
+ getTelegramMessageThreadId,
408
+ getTelegramMessageEntities,
409
+ getTelegramErrorText,
410
+ getTelegramChatType,
411
+ getTelegramChatLabel,
412
+ extractTelegramMessageText,
413
+ diffTelegramReactionUpdate,
414
+ detectTelegramBotMention,
415
+ createTelegramMessageActionAdapter,
416
+ buildTelegramRichMessagePayload,
417
+ buildTelegramRichMessageDraftPayload,
418
+ buildTelegramReplyOptions,
419
+ buildTelegramDebounceKey,
420
+ TELEGRAM_DEBOUNCE_MAX_MS,
421
+ TELEGRAM_DEBOUNCE_DEFAULT_MS
422
+ };
423
+
424
+ //# debugId=1E88FAA2B557AA0264756E2164756E21
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/channels/telegram/debounce.ts", "../src/channels/telegram/message-shapes.ts", "../src/channels/telegram/ingress.ts", "../src/channels/telegram/message-action-contract.ts", "../src/channels/telegram/outbound.ts"],
4
+ "sourcesContent": [
5
+ "import type { TelegramChannelAccount } from \"@/channels/types\";\n\nconst TELEGRAM_DEBOUNCE_DEFAULT_MS = 0;\nconst TELEGRAM_DEBOUNCE_MAX_MS = 10000;\n\n/**\n * Resolve the inbound debounce window for Telegram.\n *\n * Priority: env var > account config > default (disabled).\n * Returns `0` to disable. Clamped to `0..10000`.\n */\nexport function resolveTelegramInboundDebounceMs(\n config: Pick<TelegramChannelAccount, \"inboundDebounceMs\">,\n): number {\n const raw =\n typeof process === \"undefined\"\n ? undefined\n : process.env.LETTA_TELEGRAM_INBOUND_DEBOUNCE_MS;\n if (typeof raw === \"string\" && raw.trim() !== \"\") {\n const envOverride = Number(raw);\n if (Number.isFinite(envOverride) && envOverride >= 0) {\n return Math.trunc(Math.min(envOverride, TELEGRAM_DEBOUNCE_MAX_MS));\n }\n }\n\n const fromConfig = config.inboundDebounceMs;\n if (\n typeof fromConfig === \"number\" &&\n Number.isFinite(fromConfig) &&\n fromConfig >= 0\n ) {\n return Math.trunc(Math.min(fromConfig, TELEGRAM_DEBOUNCE_MAX_MS));\n }\n\n return TELEGRAM_DEBOUNCE_DEFAULT_MS;\n}\n\nexport type TelegramDebounceInput = {\n chatId: string;\n threadId?: string | null;\n};\n\n/**\n * Group Telegram bursts by account + chat/topic. Unlike Slack DMs, Telegram\n * group chat bursts should merge across senders so the agent sees a coherent\n * slice of the room rather than three separate turns racing each other.\n */\nexport function buildTelegramDebounceKey(\n input: TelegramDebounceInput,\n accountId: string,\n): string | null {\n if (!input.chatId.trim()) {\n return null;\n }\n return `telegram:${accountId}:${input.chatId}:${input.threadId ?? \"main\"}`;\n}\n\nexport { TELEGRAM_DEBOUNCE_DEFAULT_MS, TELEGRAM_DEBOUNCE_MAX_MS };\n",
6
+ "/**\n * Pure Telegram wire shapes shared by the local grammY adapter and remote\n * hosts (for example Cloud webhook ingress) through the public\n * `@letta-ai/letta-code/channels/telegram` subpath.\n *\n * This module must stay free of grammY imports and node builtins so the\n * public bundle and its declaration files resolve for browser/node consumers\n * that do not install the Telegram runtime.\n */\n\nexport type TelegramLikeMessage = {\n media_group_id?: string;\n message_thread_id?: number | string;\n message_id: number | string;\n date: number;\n text?: string;\n caption?: string;\n entities?: Array<{\n type?: string;\n offset?: number;\n length?: number;\n }>;\n caption_entities?: Array<{\n type?: string;\n offset?: number;\n length?: number;\n }>;\n reply_to_message?: TelegramLikeMessage;\n chat: {\n id: number | string;\n type?: string;\n title?: string;\n username?: string;\n };\n from?: {\n id: number | string;\n username?: string;\n first_name?: string;\n last_name?: string;\n };\n photo?: Array<{\n file_id: string;\n file_unique_id?: string;\n file_size?: number;\n }>;\n document?: {\n file_id: string;\n file_name?: string;\n mime_type?: string;\n file_size?: number;\n };\n video?: {\n file_id: string;\n file_name?: string;\n file_unique_id?: string;\n mime_type?: string;\n file_size?: number;\n };\n audio?: {\n file_id: string;\n file_name?: string;\n file_unique_id?: string;\n mime_type?: string;\n file_size?: number;\n };\n voice?: {\n file_id: string;\n file_unique_id?: string;\n mime_type?: string;\n file_size?: number;\n };\n animation?: {\n file_id: string;\n file_name?: string;\n file_unique_id?: string;\n mime_type?: string;\n file_size?: number;\n };\n sticker?: {\n file_id: string;\n file_unique_id?: string;\n mime_type?: string;\n file_size?: number;\n is_animated?: boolean;\n is_video?: boolean;\n };\n};\n\nexport type TelegramMentionResult = {\n isMention: boolean;\n text: string;\n};\n\nexport type TelegramInputRichMessage = {\n html?: string;\n markdown?: string;\n is_rtl?: boolean;\n skip_entity_detection?: boolean;\n};\n\nexport type TelegramRichMessagePayload = {\n chat_id: string | number;\n message_thread_id?: number;\n reply_parameters?: { message_id: number };\n rich_message: TelegramInputRichMessage;\n};\n\nexport type TelegramRichMessageDraftPayload = Omit<\n TelegramRichMessagePayload,\n \"reply_parameters\"\n> & {\n draft_id: number;\n};\n\nexport type TelegramReactionType =\n | {\n type?: \"emoji\";\n emoji?: string;\n }\n | {\n type?: \"custom_emoji\";\n custom_emoji_id?: string;\n }\n | {\n type?: \"paid\";\n };\n\n/**\n * Structural reaction payload accepted by Bot API `setMessageReaction`.\n * Mirrors grammY's `ReactionType` without importing its types so the public\n * declaration files do not require `@grammyjs/types`.\n */\nexport type TelegramReactionInput =\n | {\n type: \"emoji\";\n emoji: string;\n }\n | {\n type: \"custom_emoji\";\n custom_emoji_id: string;\n };\n\nexport type TelegramReactionUpdate = {\n chat: {\n id: string | number;\n type?: string;\n title?: string;\n username?: string;\n };\n message_id: string | number;\n user?: {\n id: string | number;\n username?: string;\n first_name?: string;\n last_name?: string;\n };\n actor_chat?: {\n id: string | number;\n username?: string;\n title?: string;\n };\n date: number;\n old_reaction: TelegramReactionType[];\n new_reaction: TelegramReactionType[];\n};\n\nexport function extractTelegramMessageText(\n message: TelegramLikeMessage,\n): string {\n if (typeof message.text === \"string\") {\n return message.text;\n }\n if (typeof message.caption === \"string\") {\n return message.caption;\n }\n return \"\";\n}\n\nexport function getTelegramSenderName(\n message: TelegramLikeMessage,\n): string | undefined {\n if (!message.from) {\n return undefined;\n }\n\n return (\n message.from.username ??\n ([message.from.first_name, message.from.last_name]\n .filter(Boolean)\n .join(\" \") ||\n undefined)\n );\n}\n",
7
+ "/**\n * Pure Telegram inbound normalization shared by the local grammY adapter and\n * remote hosts (for example Cloud webhook ingress) through the public\n * `@letta-ai/letta-code/channels/telegram` subpath.\n *\n * Everything here operates on plain Bot API update shapes; no grammY import\n * and no node builtins so remote hosts reuse the exact local semantics.\n */\n\nimport type { ChannelReplyContext } from \"@/channels/types\";\nimport {\n extractTelegramMessageText,\n getTelegramSenderName,\n type TelegramLikeMessage,\n type TelegramMentionResult,\n type TelegramReactionType,\n type TelegramReactionUpdate,\n} from \"./message-shapes\";\n\nexport function escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport function getTelegramMessageEntities(\n message: TelegramLikeMessage,\n): Array<{\n type?: string;\n offset?: number;\n length?: number;\n}> {\n return message.text !== undefined\n ? (message.entities ?? [])\n : (message.caption_entities ?? []);\n}\n\nexport function detectTelegramBotMention(\n message: TelegramLikeMessage,\n botUsername: string | null | undefined,\n botDisplayName?: string | null | undefined,\n text: string = extractTelegramMessageText(message),\n): TelegramMentionResult {\n const username = botUsername?.trim().replace(/^@/, \"\");\n const displayName = botDisplayName?.trim();\n if (!username && !displayName) {\n return { isMention: false, text };\n }\n\n const mention = username ? `@${username}` : null;\n const mentionRegex = mention\n ? new RegExp(`(^|\\\\s)${escapeRegExp(mention)}(?=$|\\\\s|[,.!?;:])`, \"i\")\n : null;\n const entityMentioned = getTelegramMessageEntities(message).some((entity) => {\n if (!mention) return false;\n if (entity.type !== \"mention\") return false;\n if (\n typeof entity.offset !== \"number\" ||\n typeof entity.length !== \"number\" ||\n entity.offset < 0 ||\n entity.length <= 0\n ) {\n return false;\n }\n return (\n text.slice(entity.offset, entity.offset + entity.length).toLowerCase() ===\n mention.toLowerCase()\n );\n });\n const regexMentioned = mentionRegex?.test(text) ?? false;\n const leadingNameRegex = displayName\n ? new RegExp(\n `^\\\\s*${escapeRegExp(displayName)}(?:[:,]?\\\\s+|[,:]\\\\s*|$)`,\n \"i\",\n )\n : null;\n const leadingNameMentioned = leadingNameRegex?.test(text) ?? false;\n const isMention = entityMentioned || regexMentioned || leadingNameMentioned;\n if (!isMention) {\n return { isMention: false, text };\n }\n\n const leadingMentionRegex = mention\n ? new RegExp(`^\\\\s*${escapeRegExp(mention)}(?:[:,]?\\\\s*|$)`, \"i\")\n : null;\n const stripped = leadingMentionRegex\n ? text.replace(leadingMentionRegex, \"\")\n : text;\n return {\n isMention: true,\n text: leadingNameRegex\n ? stripped.replace(leadingNameRegex, \"\").trimStart()\n : stripped.trimStart(),\n };\n}\n\nexport function getTelegramChatType(chat: {\n type?: string;\n}): \"direct\" | \"channel\" {\n return !chat.type || chat.type === \"private\" ? \"direct\" : \"channel\";\n}\n\nexport function getTelegramChatLabel(\n message: TelegramLikeMessage,\n): string | undefined {\n const title = message.chat.title?.trim();\n if (title) {\n return title;\n }\n const username = message.chat.username?.trim();\n if (username) {\n return username.startsWith(\"@\") ? username : `@${username}`;\n }\n return undefined;\n}\n\nexport function getTelegramMessageThreadId(\n message: TelegramLikeMessage,\n): string | null {\n return message.message_thread_id !== undefined\n ? String(message.message_thread_id)\n : null;\n}\n\nexport function getTelegramReplyContext(\n message: TelegramLikeMessage,\n): ChannelReplyContext | undefined {\n const replied = message.reply_to_message;\n if (!replied) {\n return undefined;\n }\n\n const text = extractTelegramMessageText(replied).trim();\n const context: ChannelReplyContext = {\n messageId: String(replied.message_id),\n };\n if (replied.from?.id !== undefined) {\n context.senderId = String(replied.from.id);\n }\n const senderName = getTelegramSenderName(replied);\n if (senderName) {\n context.senderName = senderName;\n }\n if (text) {\n context.text = text;\n }\n return context;\n}\n\nexport function getTelegramReactionToken(\n reaction: TelegramReactionType,\n): string | null {\n switch (reaction.type) {\n case \"emoji\":\n return reaction.emoji?.trim() || null;\n case \"custom_emoji\":\n return reaction.custom_emoji_id?.trim()\n ? `custom_emoji:${reaction.custom_emoji_id.trim()}`\n : null;\n case \"paid\":\n return \"paid\";\n default:\n return null;\n }\n}\n\nexport function getTelegramReactionSenderName(\n update: TelegramReactionUpdate,\n): string | undefined {\n if (update.user) {\n return getTelegramSenderName({\n from: update.user,\n } as TelegramLikeMessage);\n }\n\n if (update.actor_chat?.username?.trim()) {\n return update.actor_chat.username.trim();\n }\n\n if (update.actor_chat?.title?.trim()) {\n return update.actor_chat.title.trim();\n }\n\n return undefined;\n}\n\nexport function getTelegramReactionSenderId(\n update: TelegramReactionUpdate,\n): string | null {\n if (update.user?.id !== undefined) {\n return String(update.user.id);\n }\n if (update.actor_chat?.id !== undefined) {\n return String(update.actor_chat.id);\n }\n return null;\n}\n\n/**\n * Diff a Bot API `message_reaction` update into discrete added/removed\n * reaction events, using the same token normalization the local adapter uses.\n */\nexport function diffTelegramReactionUpdate(\n update: Pick<TelegramReactionUpdate, \"old_reaction\" | \"new_reaction\">,\n): Array<{ action: \"added\" | \"removed\"; emoji: string }> {\n const oldTokens = new Set(\n update.old_reaction\n .map((reaction) => getTelegramReactionToken(reaction))\n .filter((value): value is string => typeof value === \"string\"),\n );\n const newTokens = new Set(\n update.new_reaction\n .map((reaction) => getTelegramReactionToken(reaction))\n .filter((value): value is string => typeof value === \"string\"),\n );\n\n const events: Array<{ action: \"added\" | \"removed\"; emoji: string }> = [];\n for (const emoji of oldTokens) {\n if (!newTokens.has(emoji)) {\n events.push({ action: \"removed\", emoji });\n }\n }\n for (const emoji of newTokens) {\n if (!oldTokens.has(emoji)) {\n events.push({ action: \"added\", emoji });\n }\n }\n return events;\n}\n",
8
+ "import type {\n ChannelMessageActionAdapter,\n ChannelMessageActionContext,\n ChannelMessageActionRequest,\n ChannelMessageActionRoute,\n} from \"@/channels/plugin-types\";\n\nexport interface CreateTelegramMessageActionAdapterOptions {\n /**\n * Host-owned lookup for the account-level \"rich private chat\" default.\n * The local plugin reads the channel accounts store; remote hosts supply\n * their own config source. Defaults to enabled when omitted.\n */\n richPrivateChatDefaultEnabled?: (route: ChannelMessageActionRoute) => boolean;\n}\n\nfunction shouldSendTelegramRichMessage(params: {\n request: ChannelMessageActionRequest;\n route: ChannelMessageActionRoute;\n richPrivateChatDefaultEnabled: (route: ChannelMessageActionRoute) => boolean;\n}): boolean {\n if (params.request.action === \"send-rich\") {\n return true;\n }\n return (\n params.request.action === \"send\" &&\n params.route.chatType === \"direct\" &&\n params.richPrivateChatDefaultEnabled(params.route) &&\n !params.request.mediaPath?.trim()\n );\n}\n\nfunction resolveTelegramRouteThreadId(\n ctx: ChannelMessageActionContext,\n): string | null {\n const requestThreadId = ctx.request.threadId?.trim();\n if (requestThreadId) {\n return requestThreadId;\n }\n\n if (ctx.route.chatType === \"direct\") {\n return null;\n }\n\n const routeThreadId = ctx.route.threadId?.trim();\n if (!routeThreadId) {\n return null;\n }\n\n return ctx.route.chatId.trim().startsWith(\"-\") ? routeThreadId : null;\n}\n\n/**\n * Build the canonical Telegram MessageChannel actions around a host-owned\n * transport (`ctx.adapter`). The local plugin and remote gateways share the\n * same request validation, rich-message defaulting, and thread resolution.\n */\nexport function createTelegramMessageActionAdapter(\n options: CreateTelegramMessageActionAdapterOptions = {},\n): ChannelMessageActionAdapter {\n const richPrivateChatDefaultEnabled =\n options.richPrivateChatDefaultEnabled ?? (() => true);\n\n return {\n describeMessageTool() {\n return {\n actions: [\"send\", \"send-rich\", \"react\", \"upload-file\"],\n };\n },\n\n async handleAction(ctx) {\n const { request, route, adapter, formatText } = ctx;\n\n if (\n request.action !== \"send\" &&\n request.action !== \"send-rich\" &&\n request.action !== \"react\" &&\n request.action !== \"upload-file\"\n ) {\n return `Error: Action \"${request.action}\" is not supported on telegram.`;\n }\n if (request.action === \"react\") {\n if (!request.emoji?.trim() && !request.remove) {\n return \"Error: Telegram react requires emoji.\";\n }\n if (!request.messageId?.trim()) {\n return \"Error: Telegram react requires messageId.\";\n }\n\n const result = await adapter.sendMessage({\n channel: \"telegram\",\n accountId: route.accountId,\n chatId: request.chatId,\n text: \"\",\n targetMessageId: request.messageId,\n reaction: request.emoji,\n removeReaction: request.remove,\n });\n\n return request.remove\n ? `Reaction removed on telegram (message_id: ${result.messageId})`\n : `Reaction added on telegram (message_id: ${result.messageId})`;\n }\n\n if (request.action === \"send-rich\") {\n if (!request.message?.trim()) {\n return \"Error: Telegram send-rich requires message.\";\n }\n if (request.mediaPath?.trim()) {\n return \"Error: Telegram send-rich does not support local media uploads; use upload-file instead.\";\n }\n }\n if (!request.message?.trim() && !request.mediaPath?.trim()) {\n return \"Error: Telegram send requires message or media.\";\n }\n if (request.action === \"upload-file\" && !request.mediaPath?.trim()) {\n return \"Error: Telegram upload-file requires media.\";\n }\n if (request.action === \"send\" && !request.message?.trim()) {\n return \"Error: Telegram send requires message.\";\n }\n\n const formatted = formatText(request.message ?? \"\");\n const sendRichMessage = shouldSendTelegramRichMessage({\n request,\n route,\n richPrivateChatDefaultEnabled,\n });\n const result = await adapter.sendMessage({\n channel: \"telegram\",\n accountId: route.accountId,\n chatId: request.chatId,\n text: formatted.text,\n replyToMessageId: request.replyToMessageId,\n threadId: resolveTelegramRouteThreadId(ctx),\n mediaPath: request.mediaPath,\n fileName: request.filename,\n title: request.title,\n parseMode: formatted.parseMode,\n ...(sendRichMessage\n ? { richMessage: { markdown: request.message ?? \"\" } }\n : {}),\n });\n\n return request.mediaPath\n ? `Attachment sent to telegram (message_id: ${result.messageId})`\n : `Message sent to telegram (message_id: ${result.messageId})`;\n },\n };\n}\n",
9
+ "/**\n * Pure Telegram outbound payload builders shared by the local grammY adapter\n * and remote hosts (for example Cloud Bot API senders) through the public\n * `@letta-ai/letta-code/channels/telegram` subpath.\n *\n * Everything here builds plain Bot API payload objects; no grammY import and\n * no node builtins.\n */\n\nimport type {\n ChannelRichMessage,\n OutboundChannelMessage,\n OutboundChannelRichMessageDraft,\n} from \"@/channels/types\";\nimport type {\n TelegramInputRichMessage,\n TelegramReactionInput,\n TelegramRichMessageDraftPayload,\n TelegramRichMessagePayload,\n} from \"./message-shapes\";\n\nexport function resolveTelegramOutboundThreadId(msg: {\n threadId?: string | null;\n}): string | null {\n return msg.threadId?.trim() || null;\n}\n\nexport function buildTelegramReplyOptions(\n msg: Pick<\n OutboundChannelMessage,\n \"chatId\" | \"replyToMessageId\" | \"threadId\" | \"parseMode\" | \"text\" | \"title\"\n >,\n): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n const threadId = resolveTelegramOutboundThreadId(msg);\n if (threadId) {\n options.message_thread_id = Number(threadId);\n }\n if (msg.replyToMessageId) {\n options.reply_parameters = {\n message_id: Number(msg.replyToMessageId),\n };\n }\n if (msg.text.trim().length > 0) {\n options.caption = msg.text;\n if (msg.parseMode) {\n options.parse_mode = msg.parseMode;\n }\n }\n if (msg.title?.trim()) {\n options.title = msg.title.trim();\n }\n return options;\n}\n\nexport function toTelegramInputRichMessage(\n richMessage: ChannelRichMessage,\n): TelegramInputRichMessage {\n const html = richMessage.html?.trim() ? richMessage.html : undefined;\n const markdown = richMessage.markdown?.trim()\n ? richMessage.markdown\n : undefined;\n\n if (!html && !markdown) {\n throw new Error(\"Telegram rich messages require html or markdown content.\");\n }\n if (html && markdown) {\n throw new Error(\n \"Telegram rich messages require exactly one of html or markdown.\",\n );\n }\n\n const input: TelegramInputRichMessage = html ? { html } : { markdown };\n if (richMessage.isRtl !== undefined) {\n input.is_rtl = richMessage.isRtl;\n }\n if (richMessage.skipEntityDetection !== undefined) {\n input.skip_entity_detection = richMessage.skipEntityDetection;\n }\n return input;\n}\n\nexport function buildTelegramRichMessagePayload(\n msg: Pick<\n OutboundChannelMessage,\n \"chatId\" | \"replyToMessageId\" | \"threadId\" | \"richMessage\"\n >,\n): TelegramRichMessagePayload {\n if (!msg.richMessage) {\n throw new Error(\"Telegram rich message payload missing richMessage.\");\n }\n\n const payload: TelegramRichMessagePayload = {\n chat_id: msg.chatId,\n rich_message: toTelegramInputRichMessage(msg.richMessage),\n };\n const threadId = resolveTelegramOutboundThreadId(msg);\n if (threadId) {\n payload.message_thread_id = Number(threadId);\n }\n if (msg.replyToMessageId) {\n payload.reply_parameters = {\n message_id: Number(msg.replyToMessageId),\n };\n }\n return payload;\n}\n\nexport function buildTelegramRichMessageDraftPayload(\n draft: Pick<\n OutboundChannelRichMessageDraft,\n \"chatId\" | \"threadId\" | \"draftId\" | \"richMessage\"\n >,\n): TelegramRichMessageDraftPayload {\n const payload: TelegramRichMessageDraftPayload = {\n chat_id: draft.chatId,\n draft_id: draft.draftId,\n rich_message: toTelegramInputRichMessage(draft.richMessage),\n };\n const threadId = resolveTelegramOutboundThreadId(draft);\n if (threadId) {\n payload.message_thread_id = Number(threadId);\n }\n return payload;\n}\n\nexport function getTelegramErrorText(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"object\" && error !== null) {\n const maybeError = error as { message?: unknown; description?: unknown };\n if (typeof maybeError.description === \"string\") {\n return maybeError.description;\n }\n if (typeof maybeError.message === \"string\") {\n return maybeError.message;\n }\n }\n return String(error);\n}\n\nexport function shouldFallbackTelegramRichMessage(error: unknown): boolean {\n const text = getTelegramErrorText(error).toLowerCase();\n if (text.includes(\"message thread\") || text.includes(\"thread not found\")) {\n return false;\n }\n const mentionsRichMessage =\n text.includes(\"sendrichmessage\") ||\n text.includes(\"rich message\") ||\n text.includes(\"rich_message\");\n const mentionsRichFormatting =\n mentionsRichMessage ||\n text.includes(\"markdown\") ||\n text.includes(\"html\") ||\n text.includes(\"entity\") ||\n text.includes(\"entities\");\n\n if (text.includes(\"unsupported\")) {\n return true;\n }\n if (\n text.includes(\"not found\") &&\n (text.includes(\"404\") || text.includes(\"method\"))\n ) {\n return true;\n }\n if (text.includes(\"can't parse\") || text.includes(\"cannot parse\")) {\n return true;\n }\n if (mentionsRichFormatting && text.includes(\"parse\")) {\n return true;\n }\n if (mentionsRichFormatting && text.includes(\"invalid\")) {\n return true;\n }\n return mentionsRichMessage && text.includes(\"bad request\");\n}\n\nexport function parseTelegramReactionInput(\n reaction: string,\n): TelegramReactionInput | null {\n const trimmed = reaction.trim();\n if (!trimmed) {\n return null;\n }\n\n const customEmojiPrefix = \"custom_emoji:\";\n if (trimmed.startsWith(customEmojiPrefix)) {\n const customEmojiId = trimmed.slice(customEmojiPrefix.length).trim();\n if (!customEmojiId) {\n return null;\n }\n return {\n type: \"custom_emoji\",\n custom_emoji_id: customEmojiId,\n };\n }\n\n return {\n type: \"emoji\",\n emoji: trimmed,\n };\n}\n"
10
+ ],
11
+ "mappings": ";AAEA,IAAM,+BAA+B;AACrC,IAAM,2BAA2B;AAQ1B,SAAS,gCAAgC,CAC9C,QACQ;AAAA,EACR,MAAM,MACJ,OAAO,YAAY,cACf,YACA,QAAQ,IAAI;AAAA,EAClB,IAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,MAAM,IAAI;AAAA,IAChD,MAAM,cAAc,OAAO,GAAG;AAAA,IAC9B,IAAI,OAAO,SAAS,WAAW,KAAK,eAAe,GAAG;AAAA,MACpD,OAAO,KAAK,MAAM,KAAK,IAAI,aAAa,wBAAwB,CAAC;AAAA,IACnE;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,OAAO;AAAA,EAC1B,IACE,OAAO,eAAe,YACtB,OAAO,SAAS,UAAU,KAC1B,cAAc,GACd;AAAA,IACA,OAAO,KAAK,MAAM,KAAK,IAAI,YAAY,wBAAwB,CAAC;AAAA,EAClE;AAAA,EAEA,OAAO;AAAA;AAaF,SAAS,wBAAwB,CACtC,OACA,WACe;AAAA,EACf,IAAI,CAAC,MAAM,OAAO,KAAK,GAAG;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EACA,OAAO,YAAY,aAAa,MAAM,UAAU,MAAM,YAAY;AAAA;;ACgH7D,SAAS,0BAA0B,CACxC,SACQ;AAAA,EACR,IAAI,OAAO,QAAQ,SAAS,UAAU;AAAA,IACpC,OAAO,QAAQ;AAAA,EACjB;AAAA,EACA,IAAI,OAAO,QAAQ,YAAY,UAAU;AAAA,IACvC,OAAO,QAAQ;AAAA,EACjB;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,qBAAqB,CACnC,SACoB;AAAA,EACpB,IAAI,CAAC,QAAQ,MAAM;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,OACE,QAAQ,KAAK,aACZ,CAAC,QAAQ,KAAK,YAAY,QAAQ,KAAK,SAAS,EAC9C,OAAO,OAAO,EACd,KAAK,GAAG,KACT;AAAA;;;AC3KC,SAAS,YAAY,CAAC,OAAuB;AAAA,EAClD,OAAO,MAAM,QAAQ,uBAAuB,MAAM;AAAA;AAG7C,SAAS,0BAA0B,CACxC,SAKC;AAAA,EACD,OAAO,QAAQ,SAAS,YACnB,QAAQ,YAAY,CAAC,IACrB,QAAQ,oBAAoB,CAAC;AAAA;AAG7B,SAAS,wBAAwB,CACtC,SACA,aACA,gBACA,OAAe,2BAA2B,OAAO,GAC1B;AAAA,EACvB,MAAM,WAAW,aAAa,KAAK,EAAE,QAAQ,MAAM,EAAE;AAAA,EACrD,MAAM,cAAc,gBAAgB,KAAK;AAAA,EACzC,IAAI,CAAC,YAAY,CAAC,aAAa;AAAA,IAC7B,OAAO,EAAE,WAAW,OAAO,KAAK;AAAA,EAClC;AAAA,EAEA,MAAM,UAAU,WAAW,IAAI,aAAa;AAAA,EAC5C,MAAM,eAAe,UACjB,IAAI,OAAO,UAAU,aAAa,OAAO,uBAAuB,GAAG,IACnE;AAAA,EACJ,MAAM,kBAAkB,2BAA2B,OAAO,EAAE,KAAK,CAAC,WAAW;AAAA,IAC3E,IAAI,CAAC;AAAA,MAAS,OAAO;AAAA,IACrB,IAAI,OAAO,SAAS;AAAA,MAAW,OAAO;AAAA,IACtC,IACE,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,WAAW,YACzB,OAAO,SAAS,KAChB,OAAO,UAAU,GACjB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,OACE,KAAK,MAAM,OAAO,QAAQ,OAAO,SAAS,OAAO,MAAM,EAAE,YAAY,MACrE,QAAQ,YAAY;AAAA,GAEvB;AAAA,EACD,MAAM,iBAAiB,cAAc,KAAK,IAAI,KAAK;AAAA,EACnD,MAAM,mBAAmB,cACrB,IAAI,OACF,QAAQ,aAAa,WAAW,6BAChC,GACF,IACA;AAAA,EACJ,MAAM,uBAAuB,kBAAkB,KAAK,IAAI,KAAK;AAAA,EAC7D,MAAM,YAAY,mBAAmB,kBAAkB;AAAA,EACvD,IAAI,CAAC,WAAW;AAAA,IACd,OAAO,EAAE,WAAW,OAAO,KAAK;AAAA,EAClC;AAAA,EAEA,MAAM,sBAAsB,UACxB,IAAI,OAAO,QAAQ,aAAa,OAAO,oBAAoB,GAAG,IAC9D;AAAA,EACJ,MAAM,WAAW,sBACb,KAAK,QAAQ,qBAAqB,EAAE,IACpC;AAAA,EACJ,OAAO;AAAA,IACL,WAAW;AAAA,IACX,MAAM,mBACF,SAAS,QAAQ,kBAAkB,EAAE,EAAE,UAAU,IACjD,SAAS,UAAU;AAAA,EACzB;AAAA;AAGK,SAAS,mBAAmB,CAAC,MAEX;AAAA,EACvB,OAAO,CAAC,KAAK,QAAQ,KAAK,SAAS,YAAY,WAAW;AAAA;AAGrD,SAAS,oBAAoB,CAClC,SACoB;AAAA,EACpB,MAAM,QAAQ,QAAQ,KAAK,OAAO,KAAK;AAAA,EACvC,IAAI,OAAO;AAAA,IACT,OAAO;AAAA,EACT;AAAA,EACA,MAAM,WAAW,QAAQ,KAAK,UAAU,KAAK;AAAA,EAC7C,IAAI,UAAU;AAAA,IACZ,OAAO,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI;AAAA,EACnD;AAAA,EACA;AAAA;AAGK,SAAS,0BAA0B,CACxC,SACe;AAAA,EACf,OAAO,QAAQ,sBAAsB,YACjC,OAAO,QAAQ,iBAAiB,IAChC;AAAA;AAGC,SAAS,uBAAuB,CACrC,SACiC;AAAA,EACjC,MAAM,UAAU,QAAQ;AAAA,EACxB,IAAI,CAAC,SAAS;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,2BAA2B,OAAO,EAAE,KAAK;AAAA,EACtD,MAAM,UAA+B;AAAA,IACnC,WAAW,OAAO,QAAQ,UAAU;AAAA,EACtC;AAAA,EACA,IAAI,QAAQ,MAAM,OAAO,WAAW;AAAA,IAClC,QAAQ,WAAW,OAAO,QAAQ,KAAK,EAAE;AAAA,EAC3C;AAAA,EACA,MAAM,aAAa,sBAAsB,OAAO;AAAA,EAChD,IAAI,YAAY;AAAA,IACd,QAAQ,aAAa;AAAA,EACvB;AAAA,EACA,IAAI,MAAM;AAAA,IACR,QAAQ,OAAO;AAAA,EACjB;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,wBAAwB,CACtC,UACe;AAAA,EACf,QAAQ,SAAS;AAAA,SACV;AAAA,MACH,OAAO,SAAS,OAAO,KAAK,KAAK;AAAA,SAC9B;AAAA,MACH,OAAO,SAAS,iBAAiB,KAAK,IAClC,gBAAgB,SAAS,gBAAgB,KAAK,MAC9C;AAAA,SACD;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAIN,SAAS,6BAA6B,CAC3C,QACoB;AAAA,EACpB,IAAI,OAAO,MAAM;AAAA,IACf,OAAO,sBAAsB;AAAA,MAC3B,MAAM,OAAO;AAAA,IACf,CAAwB;AAAA,EAC1B;AAAA,EAEA,IAAI,OAAO,YAAY,UAAU,KAAK,GAAG;AAAA,IACvC,OAAO,OAAO,WAAW,SAAS,KAAK;AAAA,EACzC;AAAA,EAEA,IAAI,OAAO,YAAY,OAAO,KAAK,GAAG;AAAA,IACpC,OAAO,OAAO,WAAW,MAAM,KAAK;AAAA,EACtC;AAAA,EAEA;AAAA;AAGK,SAAS,2BAA2B,CACzC,QACe;AAAA,EACf,IAAI,OAAO,MAAM,OAAO,WAAW;AAAA,IACjC,OAAO,OAAO,OAAO,KAAK,EAAE;AAAA,EAC9B;AAAA,EACA,IAAI,OAAO,YAAY,OAAO,WAAW;AAAA,IACvC,OAAO,OAAO,OAAO,WAAW,EAAE;AAAA,EACpC;AAAA,EACA,OAAO;AAAA;AAOF,SAAS,0BAA0B,CACxC,QACuD;AAAA,EACvD,MAAM,YAAY,IAAI,IACpB,OAAO,aACJ,IAAI,CAAC,aAAa,yBAAyB,QAAQ,CAAC,EACpD,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,CACjE;AAAA,EACA,MAAM,YAAY,IAAI,IACpB,OAAO,aACJ,IAAI,CAAC,aAAa,yBAAyB,QAAQ,CAAC,EACpD,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,CACjE;AAAA,EAEA,MAAM,SAAgE,CAAC;AAAA,EACvE,WAAW,SAAS,WAAW;AAAA,IAC7B,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG;AAAA,MACzB,OAAO,KAAK,EAAE,QAAQ,WAAW,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,WAAW,SAAS,WAAW;AAAA,IAC7B,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG;AAAA,MACzB,OAAO,KAAK,EAAE,QAAQ,SAAS,MAAM,CAAC;AAAA,IACxC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;ACjNT,SAAS,6BAA6B,CAAC,QAI3B;AAAA,EACV,IAAI,OAAO,QAAQ,WAAW,aAAa;AAAA,IACzC,OAAO;AAAA,EACT;AAAA,EACA,OACE,OAAO,QAAQ,WAAW,UAC1B,OAAO,MAAM,aAAa,YAC1B,OAAO,8BAA8B,OAAO,KAAK,KACjD,CAAC,OAAO,QAAQ,WAAW,KAAK;AAAA;AAIpC,SAAS,4BAA4B,CACnC,KACe;AAAA,EACf,MAAM,kBAAkB,IAAI,QAAQ,UAAU,KAAK;AAAA,EACnD,IAAI,iBAAiB;AAAA,IACnB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,IAAI,MAAM,aAAa,UAAU;AAAA,IACnC,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBAAgB,IAAI,MAAM,UAAU,KAAK;AAAA,EAC/C,IAAI,CAAC,eAAe;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EAEA,OAAO,IAAI,MAAM,OAAO,KAAK,EAAE,WAAW,GAAG,IAAI,gBAAgB;AAAA;AAQ5D,SAAS,kCAAkC,CAChD,UAAqD,CAAC,GACzB;AAAA,EAC7B,MAAM,gCACJ,QAAQ,kCAAkC,MAAM;AAAA,EAElD,OAAO;AAAA,IACL,mBAAmB,GAAG;AAAA,MACpB,OAAO;AAAA,QACL,SAAS,CAAC,QAAQ,aAAa,SAAS,aAAa;AAAA,MACvD;AAAA;AAAA,SAGI,aAAY,CAAC,KAAK;AAAA,MACtB,QAAQ,SAAS,OAAO,SAAS,eAAe;AAAA,MAEhD,IACE,QAAQ,WAAW,UACnB,QAAQ,WAAW,eACnB,QAAQ,WAAW,WACnB,QAAQ,WAAW,eACnB;AAAA,QACA,OAAO,kBAAkB,QAAQ;AAAA,MACnC;AAAA,MACA,IAAI,QAAQ,WAAW,SAAS;AAAA,QAC9B,IAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,QAAQ,QAAQ;AAAA,UAC7C,OAAO;AAAA,QACT;AAAA,QACA,IAAI,CAAC,QAAQ,WAAW,KAAK,GAAG;AAAA,UAC9B,OAAO;AAAA,QACT;AAAA,QAEA,MAAM,UAAS,MAAM,QAAQ,YAAY;AAAA,UACvC,SAAS;AAAA,UACT,WAAW,MAAM;AAAA,UACjB,QAAQ,QAAQ;AAAA,UAChB,MAAM;AAAA,UACN,iBAAiB,QAAQ;AAAA,UACzB,UAAU,QAAQ;AAAA,UAClB,gBAAgB,QAAQ;AAAA,QAC1B,CAAC;AAAA,QAED,OAAO,QAAQ,SACX,6CAA6C,QAAO,eACpD,2CAA2C,QAAO;AAAA,MACxD;AAAA,MAEA,IAAI,QAAQ,WAAW,aAAa;AAAA,QAClC,IAAI,CAAC,QAAQ,SAAS,KAAK,GAAG;AAAA,UAC5B,OAAO;AAAA,QACT;AAAA,QACA,IAAI,QAAQ,WAAW,KAAK,GAAG;AAAA,UAC7B,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA,IAAI,CAAC,QAAQ,SAAS,KAAK,KAAK,CAAC,QAAQ,WAAW,KAAK,GAAG;AAAA,QAC1D,OAAO;AAAA,MACT;AAAA,MACA,IAAI,QAAQ,WAAW,iBAAiB,CAAC,QAAQ,WAAW,KAAK,GAAG;AAAA,QAClE,OAAO;AAAA,MACT;AAAA,MACA,IAAI,QAAQ,WAAW,UAAU,CAAC,QAAQ,SAAS,KAAK,GAAG;AAAA,QACzD,OAAO;AAAA,MACT;AAAA,MAEA,MAAM,YAAY,WAAW,QAAQ,WAAW,EAAE;AAAA,MAClD,MAAM,kBAAkB,8BAA8B;AAAA,QACpD;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,MAAM,SAAS,MAAM,QAAQ,YAAY;AAAA,QACvC,SAAS;AAAA,QACT,WAAW,MAAM;AAAA,QACjB,QAAQ,QAAQ;AAAA,QAChB,MAAM,UAAU;AAAA,QAChB,kBAAkB,QAAQ;AAAA,QAC1B,UAAU,6BAA6B,GAAG;AAAA,QAC1C,WAAW,QAAQ;AAAA,QACnB,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,WAAW,UAAU;AAAA,WACjB,kBACA,EAAE,aAAa,EAAE,UAAU,QAAQ,WAAW,GAAG,EAAE,IACnD,CAAC;AAAA,MACP,CAAC;AAAA,MAED,OAAO,QAAQ,YACX,4CAA4C,OAAO,eACnD,yCAAyC,OAAO;AAAA;AAAA,EAExD;AAAA;;AC/HK,SAAS,+BAA+B,CAAC,KAE9B;AAAA,EAChB,OAAO,IAAI,UAAU,KAAK,KAAK;AAAA;AAG1B,SAAS,yBAAyB,CACvC,KAIyB;AAAA,EACzB,MAAM,UAAmC,CAAC;AAAA,EAC1C,MAAM,WAAW,gCAAgC,GAAG;AAAA,EACpD,IAAI,UAAU;AAAA,IACZ,QAAQ,oBAAoB,OAAO,QAAQ;AAAA,EAC7C;AAAA,EACA,IAAI,IAAI,kBAAkB;AAAA,IACxB,QAAQ,mBAAmB;AAAA,MACzB,YAAY,OAAO,IAAI,gBAAgB;AAAA,IACzC;AAAA,EACF;AAAA,EACA,IAAI,IAAI,KAAK,KAAK,EAAE,SAAS,GAAG;AAAA,IAC9B,QAAQ,UAAU,IAAI;AAAA,IACtB,IAAI,IAAI,WAAW;AAAA,MACjB,QAAQ,aAAa,IAAI;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,IAAI,IAAI,OAAO,KAAK,GAAG;AAAA,IACrB,QAAQ,QAAQ,IAAI,MAAM,KAAK;AAAA,EACjC;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,0BAA0B,CACxC,aAC0B;AAAA,EAC1B,MAAM,OAAO,YAAY,MAAM,KAAK,IAAI,YAAY,OAAO;AAAA,EAC3D,MAAM,WAAW,YAAY,UAAU,KAAK,IACxC,YAAY,WACZ;AAAA,EAEJ,IAAI,CAAC,QAAQ,CAAC,UAAU;AAAA,IACtB,MAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AAAA,EACA,IAAI,QAAQ,UAAU;AAAA,IACpB,MAAM,IAAI,MACR,iEACF;AAAA,EACF;AAAA,EAEA,MAAM,QAAkC,OAAO,EAAE,KAAK,IAAI,EAAE,SAAS;AAAA,EACrE,IAAI,YAAY,UAAU,WAAW;AAAA,IACnC,MAAM,SAAS,YAAY;AAAA,EAC7B;AAAA,EACA,IAAI,YAAY,wBAAwB,WAAW;AAAA,IACjD,MAAM,wBAAwB,YAAY;AAAA,EAC5C;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,+BAA+B,CAC7C,KAI4B;AAAA,EAC5B,IAAI,CAAC,IAAI,aAAa;AAAA,IACpB,MAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAAA,EAEA,MAAM,UAAsC;AAAA,IAC1C,SAAS,IAAI;AAAA,IACb,cAAc,2BAA2B,IAAI,WAAW;AAAA,EAC1D;AAAA,EACA,MAAM,WAAW,gCAAgC,GAAG;AAAA,EACpD,IAAI,UAAU;AAAA,IACZ,QAAQ,oBAAoB,OAAO,QAAQ;AAAA,EAC7C;AAAA,EACA,IAAI,IAAI,kBAAkB;AAAA,IACxB,QAAQ,mBAAmB;AAAA,MACzB,YAAY,OAAO,IAAI,gBAAgB;AAAA,IACzC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,oCAAoC,CAClD,OAIiC;AAAA,EACjC,MAAM,UAA2C;AAAA,IAC/C,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,cAAc,2BAA2B,MAAM,WAAW;AAAA,EAC5D;AAAA,EACA,MAAM,WAAW,gCAAgC,KAAK;AAAA,EACtD,IAAI,UAAU;AAAA,IACZ,QAAQ,oBAAoB,OAAO,QAAQ;AAAA,EAC7C;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,oBAAoB,CAAC,OAAwB;AAAA,EAC3D,IAAI,iBAAiB,OAAO;AAAA,IAC1B,OAAO,MAAM;AAAA,EACf;AAAA,EACA,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAAA,IAC/C,MAAM,aAAa;AAAA,IACnB,IAAI,OAAO,WAAW,gBAAgB,UAAU;AAAA,MAC9C,OAAO,WAAW;AAAA,IACpB;AAAA,IACA,IAAI,OAAO,WAAW,YAAY,UAAU;AAAA,MAC1C,OAAO,WAAW;AAAA,IACpB;AAAA,EACF;AAAA,EACA,OAAO,OAAO,KAAK;AAAA;AAGd,SAAS,iCAAiC,CAAC,OAAyB;AAAA,EACzE,MAAM,OAAO,qBAAqB,KAAK,EAAE,YAAY;AAAA,EACrD,IAAI,KAAK,SAAS,gBAAgB,KAAK,KAAK,SAAS,kBAAkB,GAAG;AAAA,IACxE,OAAO;AAAA,EACT;AAAA,EACA,MAAM,sBACJ,KAAK,SAAS,iBAAiB,KAC/B,KAAK,SAAS,cAAc,KAC5B,KAAK,SAAS,cAAc;AAAA,EAC9B,MAAM,yBACJ,uBACA,KAAK,SAAS,UAAU,KACxB,KAAK,SAAS,MAAM,KACpB,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,UAAU;AAAA,EAE1B,IAAI,KAAK,SAAS,aAAa,GAAG;AAAA,IAChC,OAAO;AAAA,EACT;AAAA,EACA,IACE,KAAK,SAAS,WAAW,MACxB,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,QAAQ,IAC/C;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EACA,IAAI,KAAK,SAAS,aAAa,KAAK,KAAK,SAAS,cAAc,GAAG;AAAA,IACjE,OAAO;AAAA,EACT;AAAA,EACA,IAAI,0BAA0B,KAAK,SAAS,OAAO,GAAG;AAAA,IACpD,OAAO;AAAA,EACT;AAAA,EACA,IAAI,0BAA0B,KAAK,SAAS,SAAS,GAAG;AAAA,IACtD,OAAO;AAAA,EACT;AAAA,EACA,OAAO,uBAAuB,KAAK,SAAS,aAAa;AAAA;AAGpD,SAAS,0BAA0B,CACxC,UAC8B;AAAA,EAC9B,MAAM,UAAU,SAAS,KAAK;AAAA,EAC9B,IAAI,CAAC,SAAS;AAAA,IACZ,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,oBAAoB;AAAA,EAC1B,IAAI,QAAQ,WAAW,iBAAiB,GAAG;AAAA,IACzC,MAAM,gBAAgB,QAAQ,MAAM,kBAAkB,MAAM,EAAE,KAAK;AAAA,IACnE,IAAI,CAAC,eAAe;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA;",
12
+ "debugId": "1E88FAA2B557AA0264756E2164756E21",
13
+ "names": []
14
+ }
@@ -16867,7 +16867,7 @@ class StreamableHTTPClientTransport {
16867
16867
  // src/mcp-client.ts
16868
16868
  var DEFAULT_CLIENT_INFO = {
16869
16869
  name: "letta-code",
16870
- version: "0.30.24"
16870
+ version: "0.30.26"
16871
16871
  };
16872
16872
  async function connectMcpServer(config2, options = {}) {
16873
16873
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -16992,4 +16992,4 @@ export {
16992
16992
  connectMcpServer
16993
16993
  };
16994
16994
 
16995
- //# debugId=59FF985EF14E3CCA64756E2164756E21
16995
+ //# debugId=6D6FF92E1FBE003764756E2164756E21