@letta-ai/letta-code 0.29.5 → 0.29.6
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/memory-confinement.js +363 -0
- package/dist/memory-confinement.js.map +18 -0
- package/dist/types/channels/plugin-types.d.ts +2 -2
- package/dist/types/channels/plugin-types.d.ts.map +1 -1
- package/dist/types/channels/types.d.ts +15 -1
- package/dist/types/channels/types.d.ts.map +1 -1
- package/dist/types/memory-confinement.d.ts +13 -0
- package/dist/types/memory-confinement.d.ts.map +1 -0
- package/dist/types/permissions/memory-confinement-launcher.d.ts +20 -0
- package/dist/types/permissions/memory-confinement-launcher.d.ts.map +1 -0
- package/dist/types/permissions/sandbox-policy.d.ts +138 -0
- package/dist/types/permissions/sandbox-policy.d.ts.map +1 -0
- package/dist/types/sandbox/availability.d.ts +60 -0
- package/dist/types/sandbox/availability.d.ts.map +1 -0
- package/dist/types/sandbox/bwrap.d.ts +36 -0
- package/dist/types/sandbox/bwrap.d.ts.map +1 -0
- package/dist/types/sandbox/policy.d.ts +79 -0
- package/dist/types/sandbox/policy.d.ts.map +1 -0
- package/dist/types/sandbox/seatbelt.d.ts +39 -0
- package/dist/types/sandbox/seatbelt.d.ts.map +1 -0
- package/dist/types/sandbox/wrap.d.ts +18 -0
- package/dist/types/sandbox/wrap.d.ts.map +1 -0
- package/dist/types/types/protocol_v2.d.ts +2 -0
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/utils/local-backend-paths.d.ts +23 -0
- package/dist/types/utils/local-backend-paths.d.ts.map +1 -0
- package/letta.js +500 -384
- package/package.json +11 -1
- package/scripts/source-file-size-baseline.json +1 -1
package/letta.js
CHANGED
|
@@ -5462,7 +5462,7 @@ var package_default;
|
|
|
5462
5462
|
var init_package = __esm(() => {
|
|
5463
5463
|
package_default = {
|
|
5464
5464
|
name: "@letta-ai/letta-code",
|
|
5465
|
-
version: "0.29.
|
|
5465
|
+
version: "0.29.6",
|
|
5466
5466
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5467
5467
|
type: "module",
|
|
5468
5468
|
packageManager: "bun@1.3.0",
|
|
@@ -5482,6 +5482,8 @@ var init_package = __esm(() => {
|
|
|
5482
5482
|
"dist/app-server-client.js.map",
|
|
5483
5483
|
"dist/app-server-client.cjs",
|
|
5484
5484
|
"dist/app-server-client.cjs.map",
|
|
5485
|
+
"dist/memory-confinement.js",
|
|
5486
|
+
"dist/memory-confinement.js.map",
|
|
5485
5487
|
"dist/agent-presets.js",
|
|
5486
5488
|
"dist/agent-presets.js.map",
|
|
5487
5489
|
"dist/channels-public.js",
|
|
@@ -5503,6 +5505,11 @@ var init_package = __esm(() => {
|
|
|
5503
5505
|
require: "./dist/app-server-client.cjs",
|
|
5504
5506
|
default: "./dist/app-server-client.js"
|
|
5505
5507
|
},
|
|
5508
|
+
"./memory-confinement": {
|
|
5509
|
+
types: "./dist/types/memory-confinement.d.ts",
|
|
5510
|
+
import: "./dist/memory-confinement.js",
|
|
5511
|
+
default: "./dist/memory-confinement.js"
|
|
5512
|
+
},
|
|
5506
5513
|
"./protocol": {
|
|
5507
5514
|
types: "./dist/types/types/protocol.d.ts"
|
|
5508
5515
|
},
|
|
@@ -5622,6 +5629,9 @@ var init_package = __esm(() => {
|
|
|
5622
5629
|
"app-server-client": [
|
|
5623
5630
|
"./dist/types/app-server-client.d.ts"
|
|
5624
5631
|
],
|
|
5632
|
+
"memory-confinement": [
|
|
5633
|
+
"./dist/types/memory-confinement.d.ts"
|
|
5634
|
+
],
|
|
5625
5635
|
channels: [
|
|
5626
5636
|
"./dist/types/channels-public.d.ts"
|
|
5627
5637
|
],
|
|
@@ -145938,6 +145948,32 @@ var init_mode = __esm(() => {
|
|
|
145938
145948
|
permissionMode = new PermissionModeManager;
|
|
145939
145949
|
});
|
|
145940
145950
|
|
|
145951
|
+
// src/channels/discord/bot-policy.ts
|
|
145952
|
+
function isNonEmptyString(value) {
|
|
145953
|
+
return typeof value === "string" && value.length > 0;
|
|
145954
|
+
}
|
|
145955
|
+
function isValidDiscordAllowBotsConfigValue(value) {
|
|
145956
|
+
return value === undefined || value === false || value === "mentions";
|
|
145957
|
+
}
|
|
145958
|
+
function normalizeDiscordAllowBotsMode(value) {
|
|
145959
|
+
return value === "mentions" ? "mentions" : false;
|
|
145960
|
+
}
|
|
145961
|
+
function hasExplicitDiscordUserMention(message, userId) {
|
|
145962
|
+
if (!isNonEmptyString(userId) || typeof message.content !== "string") {
|
|
145963
|
+
return false;
|
|
145964
|
+
}
|
|
145965
|
+
return message.content.includes(`<@${userId}>`) || message.content.includes(`<@!${userId}>`);
|
|
145966
|
+
}
|
|
145967
|
+
function shouldAcceptDiscordInboundBotMessage(input) {
|
|
145968
|
+
const author = input.message.author;
|
|
145969
|
+
if (author?.bot !== true)
|
|
145970
|
+
return true;
|
|
145971
|
+
if (isNonEmptyString(input.botUserId) && author.id === input.botUserId) {
|
|
145972
|
+
return false;
|
|
145973
|
+
}
|
|
145974
|
+
return input.allowBots === "mentions" && input.wasExplicitlyMentioned;
|
|
145975
|
+
}
|
|
145976
|
+
|
|
145941
145977
|
// src/channels/slack/bot-policy.ts
|
|
145942
145978
|
function isValidSlackAllowBotsConfigValue(value) {
|
|
145943
145979
|
return value === undefined || value === false || value === "mentions";
|
|
@@ -145952,14 +145988,14 @@ function resolveSlackAllowBotsMode(value) {
|
|
|
145952
145988
|
return "mentions";
|
|
145953
145989
|
return "off";
|
|
145954
145990
|
}
|
|
145955
|
-
function
|
|
145991
|
+
function isNonEmptyString2(value) {
|
|
145956
145992
|
return typeof value === "string" && value.length > 0;
|
|
145957
145993
|
}
|
|
145958
145994
|
function isSlackBotAuthoredInboundMessage(message) {
|
|
145959
|
-
return
|
|
145995
|
+
return isNonEmptyString2(message.bot_id) || message.subtype === "bot_message";
|
|
145960
145996
|
}
|
|
145961
145997
|
function isOwnSlackBotInboundMessage(params) {
|
|
145962
|
-
return
|
|
145998
|
+
return isNonEmptyString2(params.botUserId) && params.message.user === params.botUserId || isNonEmptyString2(params.botId) && params.message.bot_id === params.botId;
|
|
145963
145999
|
}
|
|
145964
146000
|
function shouldAcceptSlackInboundBotMessage(params) {
|
|
145965
146001
|
if (isOwnSlackBotInboundMessage({
|
|
@@ -146125,6 +146161,9 @@ var init_config2 = __esm(() => {
|
|
|
146125
146161
|
};
|
|
146126
146162
|
discordConfigCodec = {
|
|
146127
146163
|
parse(parsed) {
|
|
146164
|
+
if (!isValidDiscordAllowBotsConfigValue(parsed.allow_bots)) {
|
|
146165
|
+
throw new Error("Invalid Discord allow_bots config");
|
|
146166
|
+
}
|
|
146128
146167
|
const rawAllowedChannels = parsed.allowed_channels;
|
|
146129
146168
|
let allowedChannels;
|
|
146130
146169
|
if (Array.isArray(rawAllowedChannels)) {
|
|
@@ -146140,6 +146179,7 @@ var init_config2 = __esm(() => {
|
|
|
146140
146179
|
dmPolicy: parsed.dm_policy ?? "pairing",
|
|
146141
146180
|
allowedUsers: parsed.allowed_users ?? [],
|
|
146142
146181
|
allowedChannels,
|
|
146182
|
+
allowBots: normalizeDiscordAllowBotsMode(parsed.allow_bots),
|
|
146143
146183
|
transcribeVoice: parsed.transcribe_voice === true,
|
|
146144
146184
|
autoThreadOnMention: typeof parsed.auto_thread_on_mention === "boolean" ? parsed.auto_thread_on_mention : undefined,
|
|
146145
146185
|
threadPolicyByChannel: typeof parsed.thread_policy_by_channel === "object" && !Array.isArray(parsed.thread_policy_by_channel) ? parsed.thread_policy_by_channel : undefined,
|
|
@@ -146373,7 +146413,7 @@ var init_plugin = __esm(() => {
|
|
|
146373
146413
|
});
|
|
146374
146414
|
|
|
146375
146415
|
// src/channels/schema-config.ts
|
|
146376
|
-
function
|
|
146416
|
+
function isNonEmptyString3(value) {
|
|
146377
146417
|
return typeof value === "string" && value.length > 0;
|
|
146378
146418
|
}
|
|
146379
146419
|
function parseSelectOptions(value) {
|
|
@@ -146386,7 +146426,7 @@ function parseSelectOptions(value) {
|
|
|
146386
146426
|
if (!isRecord(entry)) {
|
|
146387
146427
|
return null;
|
|
146388
146428
|
}
|
|
146389
|
-
if (!
|
|
146429
|
+
if (!isNonEmptyString3(entry.value) || !isNonEmptyString3(entry.label)) {
|
|
146390
146430
|
return null;
|
|
146391
146431
|
}
|
|
146392
146432
|
if (seen.has(entry.value)) {
|
|
@@ -146405,10 +146445,10 @@ function parseField(value) {
|
|
|
146405
146445
|
if (typeof type3 !== "string" || !FIELD_TYPES.has(type3)) {
|
|
146406
146446
|
return null;
|
|
146407
146447
|
}
|
|
146408
|
-
if (!
|
|
146448
|
+
if (!isNonEmptyString3(value.key) || !FIELD_KEY_PATTERN.test(value.key)) {
|
|
146409
146449
|
return null;
|
|
146410
146450
|
}
|
|
146411
|
-
if (!
|
|
146451
|
+
if (!isNonEmptyString3(value.label)) {
|
|
146412
146452
|
return null;
|
|
146413
146453
|
}
|
|
146414
146454
|
if (value.description !== undefined && typeof value.description !== "string") {
|
|
@@ -148130,11 +148170,7 @@ function resolveTelegramInputFileConstructor(mod) {
|
|
|
148130
148170
|
return InputFile;
|
|
148131
148171
|
}
|
|
148132
148172
|
function resolveTelegramOutboundThreadId(msg) {
|
|
148133
|
-
|
|
148134
|
-
if (!threadId) {
|
|
148135
|
-
return null;
|
|
148136
|
-
}
|
|
148137
|
-
return msg.chatId.trim().startsWith("-") ? threadId : null;
|
|
148173
|
+
return msg.threadId?.trim() || null;
|
|
148138
148174
|
}
|
|
148139
148175
|
function buildTelegramReplyOptions(msg) {
|
|
148140
148176
|
const options3 = {};
|
|
@@ -149408,7 +149444,7 @@ function createTelegramAdapter(config3) {
|
|
|
149408
149444
|
}
|
|
149409
149445
|
const telegramBot = await ensureBot();
|
|
149410
149446
|
const threadId = resolveTelegramOutboundThreadId(source2);
|
|
149411
|
-
const replyToMessageId =
|
|
149447
|
+
const replyToMessageId = source2.messageId;
|
|
149412
149448
|
let reply_parameters;
|
|
149413
149449
|
if (replyToMessageId) {
|
|
149414
149450
|
const numericReplyToMessageId = Number(replyToMessageId);
|
|
@@ -149582,10 +149618,16 @@ function createTelegramAdapter(config3) {
|
|
|
149582
149618
|
},
|
|
149583
149619
|
async sendDirectReply(chatId, text, options3) {
|
|
149584
149620
|
const telegramBot = await ensureBot();
|
|
149621
|
+
const threadId = resolveTelegramOutboundThreadId({
|
|
149622
|
+
threadId: options3?.threadId
|
|
149623
|
+
});
|
|
149585
149624
|
const reply_parameters = options3?.replyToMessageId ? {
|
|
149586
149625
|
message_id: Number(options3.replyToMessageId)
|
|
149587
149626
|
} : undefined;
|
|
149588
|
-
await telegramBot.api.sendMessage(chatId, text,
|
|
149627
|
+
await telegramBot.api.sendMessage(chatId, text, {
|
|
149628
|
+
...threadId ? { message_thread_id: Number(threadId) } : {},
|
|
149629
|
+
...reply_parameters ? { reply_parameters } : {}
|
|
149630
|
+
});
|
|
149589
149631
|
},
|
|
149590
149632
|
async handleTurnLifecycleEvent(event2) {
|
|
149591
149633
|
if (!running)
|
|
@@ -149624,7 +149666,7 @@ function createTelegramAdapter(config3) {
|
|
|
149624
149666
|
async handleControlRequestEvent(event2) {
|
|
149625
149667
|
const telegramBot = await ensureBot();
|
|
149626
149668
|
const threadId = resolveTelegramOutboundThreadId(event2.source);
|
|
149627
|
-
const replyToMessageId =
|
|
149669
|
+
const replyToMessageId = event2.source.messageId;
|
|
149628
149670
|
const reply_parameters = replyToMessageId ? { message_id: Number(replyToMessageId) } : undefined;
|
|
149629
149671
|
await telegramBot.api.sendMessage(event2.source.chatId, formatChannelControlRequestPrompt(event2), {
|
|
149630
149672
|
...threadId ? { message_thread_id: Number(threadId) } : {},
|
|
@@ -149901,6 +149943,7 @@ function normalizeLoadedAccount(account) {
|
|
|
149901
149943
|
if (isDiscordChannelAccount(next)) {
|
|
149902
149944
|
const migrated = migratePermissionMode(next.defaultPermissionMode ?? "standard");
|
|
149903
149945
|
next.defaultPermissionMode = migrated ?? "standard";
|
|
149946
|
+
next.allowBots = normalizeDiscordAllowBotsMode(next.allowBots);
|
|
149904
149947
|
if (!("auto_thread_on_mention" in raw) && !("autoThreadOnMention" in raw)) {
|
|
149905
149948
|
next.autoThreadOnMention = true;
|
|
149906
149949
|
}
|
|
@@ -149963,6 +150006,7 @@ function makeDefaultLegacyAccount(channelId) {
|
|
|
149963
150006
|
allowedChannels: config3.allowedChannels ? Array.isArray(config3.allowedChannels) ? [...config3.allowedChannels] : { ...config3.allowedChannels } : undefined,
|
|
149964
150007
|
autoThreadOnMention: config3.autoThreadOnMention ?? true,
|
|
149965
150008
|
threadPolicyByChannel: config3.threadPolicyByChannel,
|
|
150009
|
+
allowBots: config3.allowBots ?? false,
|
|
149966
150010
|
agentId: null,
|
|
149967
150011
|
defaultPermissionMode: config3.defaultPermissionMode ?? "standard",
|
|
149968
150012
|
createdAt: now,
|
|
@@ -150249,15 +150293,18 @@ function shouldSendTelegramRichMessage(params) {
|
|
|
150249
150293
|
return params.request.action === "send" && params.route.chatType === "direct" && richPrivateChatDefaultEnabled(params.route) && !params.request.mediaPath?.trim();
|
|
150250
150294
|
}
|
|
150251
150295
|
function resolveTelegramRouteThreadId(ctx) {
|
|
150252
|
-
const
|
|
150253
|
-
|
|
150254
|
-
|
|
150255
|
-
return null;
|
|
150296
|
+
const requestThreadId = ctx.request.threadId?.trim();
|
|
150297
|
+
if (requestThreadId) {
|
|
150298
|
+
return requestThreadId;
|
|
150256
150299
|
}
|
|
150257
150300
|
if (ctx.route.chatType === "direct") {
|
|
150258
150301
|
return null;
|
|
150259
150302
|
}
|
|
150260
|
-
|
|
150303
|
+
const routeThreadId = ctx.route.threadId?.trim();
|
|
150304
|
+
if (!routeThreadId) {
|
|
150305
|
+
return null;
|
|
150306
|
+
}
|
|
150307
|
+
return ctx.route.chatId.trim().startsWith("-") ? routeThreadId : null;
|
|
150261
150308
|
}
|
|
150262
150309
|
var telegramMessageActions;
|
|
150263
150310
|
var init_message_actions = __esm(() => {
|
|
@@ -150511,11 +150558,11 @@ function resolveSlackAppConstructor(mod) {
|
|
|
150511
150558
|
}
|
|
150512
150559
|
return App;
|
|
150513
150560
|
}
|
|
150514
|
-
function
|
|
150561
|
+
function isNonEmptyString4(value) {
|
|
150515
150562
|
return typeof value === "string" && value.length > 0;
|
|
150516
150563
|
}
|
|
150517
150564
|
function firstNonEmptyString(...values2) {
|
|
150518
|
-
return values2.find(
|
|
150565
|
+
return values2.find(isNonEmptyString4);
|
|
150519
150566
|
}
|
|
150520
150567
|
function asRecord2(value) {
|
|
150521
150568
|
return value && typeof value === "object" ? value : null;
|
|
@@ -150593,7 +150640,7 @@ function resolveSlackUserDisplayName(userInfo) {
|
|
|
150593
150640
|
return firstNonEmptyString(profile?.display_name, profile?.real_name, user?.name);
|
|
150594
150641
|
}
|
|
150595
150642
|
function isSlackFlatChannelThreadOpener(source2) {
|
|
150596
|
-
return source2.chatType === "channel" &&
|
|
150643
|
+
return source2.chatType === "channel" && isNonEmptyString4(source2.messageId) && (!isNonEmptyString4(source2.threadId) || source2.threadId === source2.messageId);
|
|
150597
150644
|
}
|
|
150598
150645
|
var IGNORED_SLACK_MESSAGE_SUBTYPES, WRAPPER_SLACK_MESSAGE_SUBTYPES;
|
|
150599
150646
|
var init_utils5 = __esm(() => {
|
|
@@ -150640,7 +150687,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
|
|
|
150640
150687
|
socketMode: true
|
|
150641
150688
|
});
|
|
150642
150689
|
const auth = await app.client.auth.test({ token: botToken });
|
|
150643
|
-
if (
|
|
150690
|
+
if (isNonEmptyString4(auth.user_id)) {
|
|
150644
150691
|
try {
|
|
150645
150692
|
const userInfo = await app.client.users.info({
|
|
150646
150693
|
token: botToken,
|
|
@@ -150652,7 +150699,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
|
|
|
150652
150699
|
}
|
|
150653
150700
|
} catch {}
|
|
150654
150701
|
}
|
|
150655
|
-
return
|
|
150702
|
+
return isNonEmptyString4(auth.user) ? auth.user : undefined;
|
|
150656
150703
|
}
|
|
150657
150704
|
var init_account_display2 = __esm(() => {
|
|
150658
150705
|
init_runtime2();
|
|
@@ -151353,7 +151400,7 @@ var init_feedback2 = __esm(() => {
|
|
|
151353
151400
|
init_plugin_registry();
|
|
151354
151401
|
});
|
|
151355
151402
|
|
|
151356
|
-
// src/channels/
|
|
151403
|
+
// src/channels/registry-presentation.ts
|
|
151357
151404
|
function channelDisplayName3(channelId) {
|
|
151358
151405
|
try {
|
|
151359
151406
|
return getChannelDisplayName(channelId);
|
|
@@ -151361,6 +151408,168 @@ function channelDisplayName3(channelId) {
|
|
|
151361
151408
|
return channelId;
|
|
151362
151409
|
}
|
|
151363
151410
|
}
|
|
151411
|
+
function normalizeAgentId(agentId) {
|
|
151412
|
+
const normalized = agentId?.trim();
|
|
151413
|
+
return normalized ? normalized : null;
|
|
151414
|
+
}
|
|
151415
|
+
function getConfiguredAgentId(config3) {
|
|
151416
|
+
if (!config3 || typeof config3 !== "object")
|
|
151417
|
+
return null;
|
|
151418
|
+
const source2 = config3;
|
|
151419
|
+
return normalizeAgentId(source2.agentId) ?? normalizeAgentId(source2.binding?.agentId);
|
|
151420
|
+
}
|
|
151421
|
+
function buildPairingInstructions(channelId, code2, options3 = {}) {
|
|
151422
|
+
const displayName = channelDisplayName3(channelId);
|
|
151423
|
+
const configuredAgentId = normalizeAgentId(options3.agentId);
|
|
151424
|
+
const pairingCommand = `letta channels pair --channel ${channelId} --code ${code2} --agent ${configuredAgentId ?? "<agent-id>"}`;
|
|
151425
|
+
const agentLookupLines = configuredAgentId ? [] : ["Find the target agent with: letta agents list"];
|
|
151426
|
+
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
151427
|
+
return [
|
|
151428
|
+
"Connect this chat to a Letta agent.",
|
|
151429
|
+
"",
|
|
151430
|
+
`Pairing code: ${code2}`,
|
|
151431
|
+
"",
|
|
151432
|
+
"CLI on the listener machine:",
|
|
151433
|
+
pairingCommand,
|
|
151434
|
+
...agentLookupLines,
|
|
151435
|
+
"",
|
|
151436
|
+
"This code expires in 15 minutes."
|
|
151437
|
+
].join(`
|
|
151438
|
+
`);
|
|
151439
|
+
}
|
|
151440
|
+
return [
|
|
151441
|
+
"Connect this chat to a Letta agent.",
|
|
151442
|
+
"",
|
|
151443
|
+
`Pairing code: ${code2}`,
|
|
151444
|
+
"",
|
|
151445
|
+
`In Letta Code: open Channels > ${displayName} and approve this pending chat.`,
|
|
151446
|
+
"",
|
|
151447
|
+
"CLI on the listener machine:",
|
|
151448
|
+
pairingCommand,
|
|
151449
|
+
...agentLookupLines,
|
|
151450
|
+
"",
|
|
151451
|
+
"This code expires in 15 minutes."
|
|
151452
|
+
].join(`
|
|
151453
|
+
`);
|
|
151454
|
+
}
|
|
151455
|
+
function buildUnboundRouteInstructions(channelId, chatId) {
|
|
151456
|
+
const displayName = channelDisplayName3(channelId);
|
|
151457
|
+
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
151458
|
+
return `This chat isn't connected to a Letta agent yet.
|
|
151459
|
+
|
|
151460
|
+
` + `On the machine where your listener runs:
|
|
151461
|
+
|
|
151462
|
+
` + `letta channels route add --channel ${channelId} --chat-id ${chatId} --agent <agent-id>
|
|
151463
|
+
|
|
151464
|
+
` + `Find your agent id with letta agents list.`;
|
|
151465
|
+
}
|
|
151466
|
+
return `This chat isn't connected to a Letta agent yet.
|
|
151467
|
+
|
|
151468
|
+
` + `Open Channels > ${displayName} in Letta Code and connect this chat there.
|
|
151469
|
+
|
|
151470
|
+
` + `Chat ID: ${chatId}`;
|
|
151471
|
+
}
|
|
151472
|
+
function buildSlackAppSetupInstructions() {
|
|
151473
|
+
return `This Slack app isn't connected to a Letta agent yet.
|
|
151474
|
+
|
|
151475
|
+
` + "Open Channels > Slack in Letta Code, choose which agent this app should represent, and try again.";
|
|
151476
|
+
}
|
|
151477
|
+
function truncateChannelSummaryPreview(text, maxLength3 = 72) {
|
|
151478
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
151479
|
+
if (!normalized)
|
|
151480
|
+
return null;
|
|
151481
|
+
if (normalized.length <= maxLength3)
|
|
151482
|
+
return normalized;
|
|
151483
|
+
return `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
|
|
151484
|
+
}
|
|
151485
|
+
function buildSlackConversationSummary(msg) {
|
|
151486
|
+
if (msg.chatType === "direct") {
|
|
151487
|
+
if (msg.threadId?.trim()) {
|
|
151488
|
+
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
151489
|
+
return preview2 ? `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}: ${preview2}` : `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151490
|
+
}
|
|
151491
|
+
return `[Slack] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151492
|
+
}
|
|
151493
|
+
const preview = truncateChannelSummaryPreview(msg.text);
|
|
151494
|
+
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
151495
|
+
if (preview)
|
|
151496
|
+
return `[Slack] Thread${channelLabel}: ${preview}`;
|
|
151497
|
+
return `[Slack] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
151498
|
+
}
|
|
151499
|
+
function buildDiscordConversationSummary(msg) {
|
|
151500
|
+
if (msg.chatType === "direct") {
|
|
151501
|
+
return `[Discord] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151502
|
+
}
|
|
151503
|
+
const preview = truncateChannelSummaryPreview(msg.text);
|
|
151504
|
+
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
151505
|
+
if (preview)
|
|
151506
|
+
return `[Discord] Thread${channelLabel}: ${preview}`;
|
|
151507
|
+
return `[Discord] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
151508
|
+
}
|
|
151509
|
+
function buildTelegramConversationSummary(msg) {
|
|
151510
|
+
if (msg.chatType === "direct") {
|
|
151511
|
+
return `[Telegram] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151512
|
+
}
|
|
151513
|
+
const preview = truncateChannelSummaryPreview(msg.text);
|
|
151514
|
+
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
151515
|
+
if (preview)
|
|
151516
|
+
return `[Telegram] Topic${channelLabel}: ${preview}`;
|
|
151517
|
+
return `[Telegram] Topic${channelLabel || ` ${msg.chatId}`}`;
|
|
151518
|
+
}
|
|
151519
|
+
function buildWhatsAppConversationSummary(msg) {
|
|
151520
|
+
if (msg.chatType === "direct") {
|
|
151521
|
+
return `[WhatsApp] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151522
|
+
}
|
|
151523
|
+
const preview = truncateChannelSummaryPreview(msg.text);
|
|
151524
|
+
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
151525
|
+
if (preview)
|
|
151526
|
+
return `[WhatsApp] Group${channelLabel}: ${preview}`;
|
|
151527
|
+
return `[WhatsApp] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
151528
|
+
}
|
|
151529
|
+
function buildSignalConversationSummary(msg) {
|
|
151530
|
+
if (msg.chatType === "direct") {
|
|
151531
|
+
return `[Signal] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
151532
|
+
}
|
|
151533
|
+
const preview = truncateChannelSummaryPreview(msg.text);
|
|
151534
|
+
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
151535
|
+
if (preview)
|
|
151536
|
+
return `[Signal] Group${channelLabel}: ${preview}`;
|
|
151537
|
+
return `[Signal] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
151538
|
+
}
|
|
151539
|
+
function buildChannelTurnSource(route, msg) {
|
|
151540
|
+
return {
|
|
151541
|
+
channel: msg.channel,
|
|
151542
|
+
accountId: msg.accountId,
|
|
151543
|
+
chatId: msg.chatId,
|
|
151544
|
+
chatType: msg.chatType,
|
|
151545
|
+
senderId: msg.senderId,
|
|
151546
|
+
senderTeamId: msg.senderTeamId,
|
|
151547
|
+
messageId: msg.messageId,
|
|
151548
|
+
threadId: msg.threadId,
|
|
151549
|
+
agentId: route.agentId,
|
|
151550
|
+
conversationId: route.conversationId
|
|
151551
|
+
};
|
|
151552
|
+
}
|
|
151553
|
+
function buildDirectReplyOptions(msg) {
|
|
151554
|
+
if (!msg.messageId && !msg.threadId)
|
|
151555
|
+
return;
|
|
151556
|
+
return {
|
|
151557
|
+
replyToMessageId: msg.messageId ?? undefined,
|
|
151558
|
+
threadId: msg.threadId ?? null
|
|
151559
|
+
};
|
|
151560
|
+
}
|
|
151561
|
+
var init_registry_presentation = __esm(() => {
|
|
151562
|
+
init_plugin_registry();
|
|
151563
|
+
});
|
|
151564
|
+
|
|
151565
|
+
// src/channels/commands.ts
|
|
151566
|
+
function channelDisplayName4(channelId) {
|
|
151567
|
+
try {
|
|
151568
|
+
return getChannelDisplayName(channelId);
|
|
151569
|
+
} catch {
|
|
151570
|
+
return channelId;
|
|
151571
|
+
}
|
|
151572
|
+
}
|
|
151364
151573
|
function listChannelSlashCommands() {
|
|
151365
151574
|
return CHANNEL_SLASH_COMMANDS.map((definition) => ({
|
|
151366
151575
|
...definition,
|
|
@@ -151437,7 +151646,7 @@ function isSlackMentionControlCommand(msg, command) {
|
|
|
151437
151646
|
return command.raw.startsWith("!") || isSlackMentionSlashCommand(msg, command);
|
|
151438
151647
|
}
|
|
151439
151648
|
function buildChannelHelpMessage(channelId) {
|
|
151440
|
-
const displayName =
|
|
151649
|
+
const displayName = channelDisplayName4(channelId);
|
|
151441
151650
|
if (channelId === "slack") {
|
|
151442
151651
|
return [
|
|
151443
151652
|
`${displayName} is connected to Letta Code.`,
|
|
@@ -151469,7 +151678,7 @@ function buildChannelHelpMessage(channelId) {
|
|
|
151469
151678
|
`);
|
|
151470
151679
|
}
|
|
151471
151680
|
function buildUnsupportedChannelCommandMessage(channelId, command) {
|
|
151472
|
-
const displayName =
|
|
151681
|
+
const displayName = channelDisplayName4(channelId);
|
|
151473
151682
|
const isBang = command.raw.startsWith("!");
|
|
151474
151683
|
const commandKind = isBang ? "bang" : "slash";
|
|
151475
151684
|
const supportedCommands = isBang ? supportedBangCommandsText() : channelId === "slack" ? supportedSlackMentionSlashCommandsText() : supportedCommandsText();
|
|
@@ -151483,7 +151692,7 @@ function buildUnsupportedChannelCommandMessage(channelId, command) {
|
|
|
151483
151692
|
`);
|
|
151484
151693
|
}
|
|
151485
151694
|
function buildChannelStatusMessage(msg, context3) {
|
|
151486
|
-
const displayName =
|
|
151695
|
+
const displayName = channelDisplayName4(msg.channel);
|
|
151487
151696
|
const route = context3.route;
|
|
151488
151697
|
const routeStatus = route ? "Connected to a Letta agent conversation." : "No route is connected for this chat yet.";
|
|
151489
151698
|
const accountStatus = !context3.accountConfigured ? "No channel account is configured for this receiver." : context3.accountEnabled === false ? "Channel account is configured but disabled." : "Channel account is configured and enabled.";
|
|
@@ -151511,7 +151720,7 @@ function buildChannelStatusMessage(msg, context3) {
|
|
|
151511
151720
|
`);
|
|
151512
151721
|
}
|
|
151513
151722
|
function buildChannelNoRouteMessage(channelId) {
|
|
151514
|
-
const displayName =
|
|
151723
|
+
const displayName = channelDisplayName4(channelId);
|
|
151515
151724
|
return [
|
|
151516
151725
|
`${displayName} could not find an existing route for this chat.`,
|
|
151517
151726
|
"Send a normal message first and follow the pairing instructions, then try again."
|
|
@@ -151520,23 +151729,23 @@ function buildChannelNoRouteMessage(channelId) {
|
|
|
151520
151729
|
`);
|
|
151521
151730
|
}
|
|
151522
151731
|
function buildChannelPausedMessage(channelId, route) {
|
|
151523
|
-
const displayName =
|
|
151732
|
+
const displayName = channelDisplayName4(channelId);
|
|
151524
151733
|
const conversation = route.conversationId ? ` Conversation: ${route.conversationId}.` : "";
|
|
151525
151734
|
return `${displayName} paused agent routing for this chat.${conversation} Send /resume here to turn replies back on.`;
|
|
151526
151735
|
}
|
|
151527
151736
|
function buildChannelAlreadyPausedMessage(channelId) {
|
|
151528
|
-
return `${
|
|
151737
|
+
return `${channelDisplayName4(channelId)} agent routing is already paused for this chat. Send /resume here to turn replies back on.`;
|
|
151529
151738
|
}
|
|
151530
151739
|
function buildChannelResumedMessage(channelId, route) {
|
|
151531
|
-
const displayName =
|
|
151740
|
+
const displayName = channelDisplayName4(channelId);
|
|
151532
151741
|
const conversation = route.conversationId ? ` Conversation: ${route.conversationId}.` : "";
|
|
151533
151742
|
return `${displayName} resumed agent routing for this chat.${conversation} Normal messages here will go to the connected agent again.`;
|
|
151534
151743
|
}
|
|
151535
151744
|
function buildChannelAlreadyActiveMessage(channelId) {
|
|
151536
|
-
return `${
|
|
151745
|
+
return `${channelDisplayName4(channelId)} agent routing is already active for this chat.`;
|
|
151537
151746
|
}
|
|
151538
151747
|
function buildChannelCancelUnavailableMessage(channelId) {
|
|
151539
|
-
const displayName =
|
|
151748
|
+
const displayName = channelDisplayName4(channelId);
|
|
151540
151749
|
return [
|
|
151541
151750
|
`${displayName} received /cancel, but this chat is not connected to an active Letta Code conversation yet.`,
|
|
151542
151751
|
"Send a normal message first to connect this chat to an agent."
|
|
@@ -151545,15 +151754,15 @@ function buildChannelCancelUnavailableMessage(channelId) {
|
|
|
151545
151754
|
`);
|
|
151546
151755
|
}
|
|
151547
151756
|
function buildChannelCancelNoActiveTurnMessage(channelId) {
|
|
151548
|
-
const displayName =
|
|
151757
|
+
const displayName = channelDisplayName4(channelId);
|
|
151549
151758
|
return `${displayName} received /cancel, but there is no in-progress agent turn to cancel for this chat.`;
|
|
151550
151759
|
}
|
|
151551
151760
|
function buildChannelCancelAcceptedMessage(channelId) {
|
|
151552
|
-
const displayName =
|
|
151761
|
+
const displayName = channelDisplayName4(channelId);
|
|
151553
151762
|
return `${displayName} cancelled the in-progress agent turn for this chat.`;
|
|
151554
151763
|
}
|
|
151555
151764
|
function buildChannelChatLinkMessage(channelId, route, chatUrl) {
|
|
151556
|
-
const displayName =
|
|
151765
|
+
const displayName = channelDisplayName4(channelId);
|
|
151557
151766
|
return [
|
|
151558
151767
|
`${displayName} chat for this route: ${chatUrl}`,
|
|
151559
151768
|
`Agent: ${route.agentId}.`,
|
|
@@ -151562,27 +151771,27 @@ function buildChannelChatLinkMessage(channelId, route, chatUrl) {
|
|
|
151562
151771
|
`);
|
|
151563
151772
|
}
|
|
151564
151773
|
function buildChannelChatUnavailableMessage(channelId, route) {
|
|
151565
|
-
const displayName =
|
|
151774
|
+
const displayName = channelDisplayName4(channelId);
|
|
151566
151775
|
return `${displayName} chat UI is not available for local backend agent ${route.agentId}.`;
|
|
151567
151776
|
}
|
|
151568
151777
|
function buildChannelDetachUnsupportedMessage(channelId) {
|
|
151569
|
-
const displayName =
|
|
151778
|
+
const displayName = channelDisplayName4(channelId);
|
|
151570
151779
|
return `${displayName} can only detach Slack channel threads.`;
|
|
151571
151780
|
}
|
|
151572
151781
|
function buildChannelDetachedMessage(channelId) {
|
|
151573
|
-
const displayName =
|
|
151782
|
+
const displayName = channelDisplayName4(channelId);
|
|
151574
151783
|
return `${displayName} detached this thread. I will ignore follow-up replies here until someone mentions the app again.`;
|
|
151575
151784
|
}
|
|
151576
151785
|
function buildChannelAlreadyDetachedMessage(channelId) {
|
|
151577
|
-
const displayName =
|
|
151786
|
+
const displayName = channelDisplayName4(channelId);
|
|
151578
151787
|
return `${displayName} is already detached from this thread. Mention the app again to reattach.`;
|
|
151579
151788
|
}
|
|
151580
151789
|
function buildChannelNewConversationMessage(channelId, route) {
|
|
151581
|
-
const displayName =
|
|
151790
|
+
const displayName = channelDisplayName4(channelId);
|
|
151582
151791
|
return `${displayName} started a new conversation for this chat. Conversation: ${route.conversationId}.`;
|
|
151583
151792
|
}
|
|
151584
151793
|
function buildChannelNewConversationUnavailableMessage(channelId) {
|
|
151585
|
-
const displayName =
|
|
151794
|
+
const displayName = channelDisplayName4(channelId);
|
|
151586
151795
|
return `${displayName} cannot start a new conversation for this chat because no agent is configured.`;
|
|
151587
151796
|
}
|
|
151588
151797
|
function getModelEntryRank(entry) {
|
|
@@ -151641,7 +151850,7 @@ function buildChannelModelNotFoundText(channelId) {
|
|
|
151641
151850
|
return `Model not found. Use ${modelCommandPrefix(channelId)} list to see available models.`;
|
|
151642
151851
|
}
|
|
151643
151852
|
function buildChannelCurrentModelMessage(channelId, params) {
|
|
151644
|
-
const displayName =
|
|
151853
|
+
const displayName = channelDisplayName4(channelId);
|
|
151645
151854
|
const scope = params.scope === "agent" ? "agent" : "conversation";
|
|
151646
151855
|
const handleText = params.modelHandle && params.modelHandle !== params.modelLabel ? ` (${params.modelHandle})` : "";
|
|
151647
151856
|
const switchCommand = modelCommandPrefix(channelId);
|
|
@@ -151669,7 +151878,7 @@ function appendModelEntrySection(lines, channelId, title, entries, limit3) {
|
|
|
151669
151878
|
}
|
|
151670
151879
|
}
|
|
151671
151880
|
function buildChannelModelListMessage(channelId, params) {
|
|
151672
|
-
const displayName =
|
|
151881
|
+
const displayName = channelDisplayName4(channelId);
|
|
151673
151882
|
const limit3 = params.limit ?? DEFAULT_CHANNEL_MODEL_LIST_LIMIT;
|
|
151674
151883
|
const entries = params.entries;
|
|
151675
151884
|
const byHandle = buildModelEntriesByHandle(entries);
|
|
@@ -151702,33 +151911,33 @@ function buildChannelModelListMessage(channelId, params) {
|
|
|
151702
151911
|
`);
|
|
151703
151912
|
}
|
|
151704
151913
|
function buildChannelModelListUnavailableMessage(channelId, error54) {
|
|
151705
|
-
const displayName =
|
|
151914
|
+
const displayName = channelDisplayName4(channelId);
|
|
151706
151915
|
return `${displayName} could not load the model list: ${error54}`;
|
|
151707
151916
|
}
|
|
151708
151917
|
function buildChannelCurrentModelUnavailableMessage(channelId, error54) {
|
|
151709
|
-
const displayName =
|
|
151918
|
+
const displayName = channelDisplayName4(channelId);
|
|
151710
151919
|
return `${displayName} could not load the current model: ${error54}`;
|
|
151711
151920
|
}
|
|
151712
151921
|
function buildChannelModelUpdatedMessage(channelId, params) {
|
|
151713
|
-
const displayName =
|
|
151922
|
+
const displayName = channelDisplayName4(channelId);
|
|
151714
151923
|
const scope = params.appliedTo === "agent" ? "agent" : "conversation";
|
|
151715
151924
|
const handleText = params.modelHandle === params.modelLabel ? "" : ` (${params.modelHandle})`;
|
|
151716
151925
|
return `${displayName} updated this ${scope}'s model to ${params.modelLabel}${handleText}.`;
|
|
151717
151926
|
}
|
|
151718
151927
|
function buildChannelModelUpdateFailedMessage(channelId, identifier2, error54) {
|
|
151719
|
-
const displayName =
|
|
151928
|
+
const displayName = channelDisplayName4(channelId);
|
|
151720
151929
|
return `${displayName} could not switch this chat's routed model to ${identifier2}: ${error54}`;
|
|
151721
151930
|
}
|
|
151722
151931
|
function buildChannelModelUnavailableMessage(channelId) {
|
|
151723
|
-
const displayName =
|
|
151932
|
+
const displayName = channelDisplayName4(channelId);
|
|
151724
151933
|
return `${displayName} cannot use /model because the listener is not ready yet. Try again in a moment.`;
|
|
151725
151934
|
}
|
|
151726
151935
|
function buildChannelReflectionUnavailableMessage(channelId) {
|
|
151727
|
-
const displayName =
|
|
151936
|
+
const displayName = channelDisplayName4(channelId);
|
|
151728
151937
|
return `${displayName} cannot start reflection for this chat because the listener is not ready yet. Try again in a moment.`;
|
|
151729
151938
|
}
|
|
151730
151939
|
function buildChannelReloadUnavailableMessage(channelId) {
|
|
151731
|
-
const displayName =
|
|
151940
|
+
const displayName = channelDisplayName4(channelId);
|
|
151732
151941
|
return `${displayName} cannot reload listener settings for this chat because the listener is not ready yet. Try again in a moment.`;
|
|
151733
151942
|
}
|
|
151734
151943
|
async function handleScopedCommand(params) {
|
|
@@ -151762,12 +151971,12 @@ async function tryHandleChannelSlashCommand(adapter, msg, options3 = {}) {
|
|
|
151762
151971
|
const isBangCommand = command.raw.startsWith("!");
|
|
151763
151972
|
const isSlackMentionControl = isSlackMentionControlCommand(msg, command);
|
|
151764
151973
|
if (isBangCommand && !isSupportedSlackMentionCommand(command.name)) {
|
|
151765
|
-
await adapter.sendDirectReply(msg.chatId, buildUnsupportedChannelCommandMessage(msg.channel, command), msg
|
|
151974
|
+
await adapter.sendDirectReply(msg.chatId, buildUnsupportedChannelCommandMessage(msg.channel, command), buildDirectReplyOptions(msg));
|
|
151766
151975
|
return true;
|
|
151767
151976
|
}
|
|
151768
151977
|
const canonicalName = canonicalizeChannelCommandName(command.name);
|
|
151769
151978
|
if (options3.commandGate && !canRunChannelCommand(options3.commandGate, canonicalName)) {
|
|
151770
|
-
await adapter.sendDirectReply(msg.chatId, buildChannelCommandDeniedMessage(msg.channel, canonicalName, options3.commandGate), msg
|
|
151979
|
+
await adapter.sendDirectReply(msg.chatId, buildChannelCommandDeniedMessage(msg.channel, canonicalName, options3.commandGate), buildDirectReplyOptions(msg));
|
|
151771
151980
|
return true;
|
|
151772
151981
|
}
|
|
151773
151982
|
const reply = normalizeDirectReplyPayload(await (async () => {
|
|
@@ -151872,6 +152081,7 @@ var init_commands = __esm(() => {
|
|
|
151872
152081
|
init_access_control();
|
|
151873
152082
|
init_feedback2();
|
|
151874
152083
|
init_plugin_registry();
|
|
152084
|
+
init_registry_presentation();
|
|
151875
152085
|
CHANNEL_SLASH_COMMANDS = [
|
|
151876
152086
|
{
|
|
151877
152087
|
name: "help",
|
|
@@ -152525,11 +152735,11 @@ var init_progress_formatting = __esm(() => {
|
|
|
152525
152735
|
});
|
|
152526
152736
|
|
|
152527
152737
|
// src/channels/slack/public-utils.ts
|
|
152528
|
-
function
|
|
152738
|
+
function isNonEmptyString5(value) {
|
|
152529
152739
|
return typeof value === "string" && value.length > 0;
|
|
152530
152740
|
}
|
|
152531
152741
|
function firstNonEmptyString3(...values2) {
|
|
152532
|
-
return values2.find(
|
|
152742
|
+
return values2.find(isNonEmptyString5);
|
|
152533
152743
|
}
|
|
152534
152744
|
function normalizeSlackText(text) {
|
|
152535
152745
|
return text.replace(/^(?:\s*<@[A-Z0-9]+>\s*)+/, "").trim();
|
|
@@ -152565,14 +152775,14 @@ function formatSlackToolNameForDisplay(toolName) {
|
|
|
152565
152775
|
return toolName;
|
|
152566
152776
|
}
|
|
152567
152777
|
function resolveSlackConcreteActivity(event2) {
|
|
152568
|
-
if (event2.kind === "command" &&
|
|
152778
|
+
if (event2.kind === "command" && isNonEmptyString5(event2.command)) {
|
|
152569
152779
|
return sanitizeSlackStatusText(formatSlackToolNameForDisplay(event2.command), SLACK_STATUS_TEXT_MAX);
|
|
152570
152780
|
}
|
|
152571
|
-
if (event2.kind !== "tool" || !
|
|
152781
|
+
if (event2.kind !== "tool" || !isNonEmptyString5(event2.toolName) || event2.toolName.toLowerCase() === "messagechannel") {
|
|
152572
152782
|
return null;
|
|
152573
152783
|
}
|
|
152574
152784
|
for (const description of [event2.toolTitle, event2.toolDetails]) {
|
|
152575
|
-
if (!
|
|
152785
|
+
if (!isNonEmptyString5(description)) {
|
|
152576
152786
|
continue;
|
|
152577
152787
|
}
|
|
152578
152788
|
const sanitized = sanitizeSlackStatusText(description, SLACK_STATUS_TEXT_MAX);
|
|
@@ -152674,12 +152884,12 @@ Run \`${toolName}\`?`
|
|
|
152674
152884
|
];
|
|
152675
152885
|
}
|
|
152676
152886
|
function parseSlackApprovalActionPayload(value) {
|
|
152677
|
-
if (!
|
|
152887
|
+
if (!isNonEmptyString4(value)) {
|
|
152678
152888
|
return null;
|
|
152679
152889
|
}
|
|
152680
152890
|
try {
|
|
152681
152891
|
const parsed = JSON.parse(value);
|
|
152682
|
-
if (!
|
|
152892
|
+
if (!isNonEmptyString4(parsed.requestId) || parsed.decision !== "allow" && parsed.decision !== "deny") {
|
|
152683
152893
|
return null;
|
|
152684
152894
|
}
|
|
152685
152895
|
return { requestId: parsed.requestId, decision: parsed.decision };
|
|
@@ -152902,16 +153112,16 @@ async function mapSlackThreadMessage(message, attachmentOptions, sourceThreadId)
|
|
|
152902
153112
|
const attachments = await resolveSlackMessageAttachments(message, attachmentOptions, sourceThreadId);
|
|
152903
153113
|
return {
|
|
152904
153114
|
text: resolveSlackThreadMessageText(message),
|
|
152905
|
-
userId:
|
|
152906
|
-
botId:
|
|
152907
|
-
ts:
|
|
153115
|
+
userId: isNonEmptyString6(message.user) ? message.user : undefined,
|
|
153116
|
+
botId: isNonEmptyString6(message.bot_id) ? message.bot_id : undefined,
|
|
153117
|
+
ts: isNonEmptyString6(message.ts) ? message.ts : undefined,
|
|
152908
153118
|
...attachments.length > 0 ? { attachments } : {}
|
|
152909
153119
|
};
|
|
152910
153120
|
}
|
|
152911
153121
|
function asRecord4(value) {
|
|
152912
153122
|
return value && typeof value === "object" ? value : null;
|
|
152913
153123
|
}
|
|
152914
|
-
function
|
|
153124
|
+
function isNonEmptyString6(value) {
|
|
152915
153125
|
return typeof value === "string" && value.trim().length > 0;
|
|
152916
153126
|
}
|
|
152917
153127
|
function normalizeSlackFileLike(value) {
|
|
@@ -152920,12 +153130,12 @@ function normalizeSlackFileLike(value) {
|
|
|
152920
153130
|
return null;
|
|
152921
153131
|
}
|
|
152922
153132
|
return {
|
|
152923
|
-
id:
|
|
152924
|
-
name:
|
|
152925
|
-
mimetype:
|
|
153133
|
+
id: isNonEmptyString6(record5.id) ? record5.id : undefined,
|
|
153134
|
+
name: isNonEmptyString6(record5.name) ? record5.name : undefined,
|
|
153135
|
+
mimetype: isNonEmptyString6(record5.mimetype) ? record5.mimetype : undefined,
|
|
152926
153136
|
size: typeof record5.size === "number" ? record5.size : undefined,
|
|
152927
|
-
url_private:
|
|
152928
|
-
url_private_download:
|
|
153137
|
+
url_private: isNonEmptyString6(record5.url_private) ? record5.url_private : undefined,
|
|
153138
|
+
url_private_download: isNonEmptyString6(record5.url_private_download) ? record5.url_private_download : undefined
|
|
152929
153139
|
};
|
|
152930
153140
|
}
|
|
152931
153141
|
function normalizeSlackAttachmentLike(value) {
|
|
@@ -152935,12 +153145,12 @@ function normalizeSlackAttachmentLike(value) {
|
|
|
152935
153145
|
}
|
|
152936
153146
|
const files = Array.isArray(record5.files) ? record5.files.map((entry) => normalizeSlackFileLike(entry)).filter((entry) => Boolean(entry)) : undefined;
|
|
152937
153147
|
return {
|
|
152938
|
-
text:
|
|
152939
|
-
fallback:
|
|
152940
|
-
pretext:
|
|
152941
|
-
author_name:
|
|
152942
|
-
title:
|
|
152943
|
-
image_url:
|
|
153148
|
+
text: isNonEmptyString6(record5.text) ? record5.text : undefined,
|
|
153149
|
+
fallback: isNonEmptyString6(record5.fallback) ? record5.fallback : undefined,
|
|
153150
|
+
pretext: isNonEmptyString6(record5.pretext) ? record5.pretext : undefined,
|
|
153151
|
+
author_name: isNonEmptyString6(record5.author_name) ? record5.author_name : undefined,
|
|
153152
|
+
title: isNonEmptyString6(record5.title) ? record5.title : undefined,
|
|
153153
|
+
image_url: isNonEmptyString6(record5.image_url) ? record5.image_url : undefined,
|
|
152944
153154
|
files
|
|
152945
153155
|
};
|
|
152946
153156
|
}
|
|
@@ -152973,7 +153183,7 @@ function resolveSlackThreadMessageText(message) {
|
|
|
152973
153183
|
if (text) {
|
|
152974
153184
|
return text;
|
|
152975
153185
|
}
|
|
152976
|
-
const attachmentTexts = Array.isArray(message.attachments) ? message.attachments.map((entry) => normalizeSlackAttachmentLike(entry)).filter((entry) => Boolean(entry)).map((attachment) => resolveSlackAttachmentText(attachment)).filter(
|
|
153186
|
+
const attachmentTexts = Array.isArray(message.attachments) ? message.attachments.map((entry) => normalizeSlackAttachmentLike(entry)).filter((entry) => Boolean(entry)).map((attachment) => resolveSlackAttachmentText(attachment)).filter(isNonEmptyString6) : [];
|
|
152977
153187
|
if (attachmentTexts.length > 0) {
|
|
152978
153188
|
return attachmentTexts.join(`
|
|
152979
153189
|
|
|
@@ -153280,7 +153490,7 @@ async function resolveSlackFilesAsAttachments(params) {
|
|
|
153280
153490
|
return resolved;
|
|
153281
153491
|
}
|
|
153282
153492
|
function resolveSlackThreadAttachmentOptions(params) {
|
|
153283
|
-
if (!
|
|
153493
|
+
if (!isNonEmptyString6(params.accountId) || !isNonEmptyString6(params.token)) {
|
|
153284
153494
|
return;
|
|
153285
153495
|
}
|
|
153286
153496
|
return {
|
|
@@ -153307,7 +153517,7 @@ async function resolveSlackMessageAttachments(message, attachmentOptions, source
|
|
|
153307
153517
|
token: attachmentOptions.token,
|
|
153308
153518
|
files: collectSlackFiles(message),
|
|
153309
153519
|
sourceMessageId: message.ts,
|
|
153310
|
-
sourceThreadId: sourceThreadId ?? (
|
|
153520
|
+
sourceThreadId: sourceThreadId ?? (isNonEmptyString6(message.thread_ts) ? message.thread_ts : null),
|
|
153311
153521
|
transcribeVoice: attachmentOptions.transcribeVoice
|
|
153312
153522
|
});
|
|
153313
153523
|
}
|
|
@@ -153317,8 +153527,8 @@ async function resolveSlackInboundAttachments(params) {
|
|
|
153317
153527
|
accountId: params.accountId,
|
|
153318
153528
|
token: params.token,
|
|
153319
153529
|
files: collectSlackFiles(params.rawEvent),
|
|
153320
|
-
sourceMessageId:
|
|
153321
|
-
sourceThreadId:
|
|
153530
|
+
sourceMessageId: isNonEmptyString6(rawEvent?.ts) ? rawEvent.ts : undefined,
|
|
153531
|
+
sourceThreadId: isNonEmptyString6(rawEvent?.thread_ts) ? rawEvent.thread_ts : null,
|
|
153322
153532
|
transcribeVoice: params.transcribeVoice
|
|
153323
153533
|
});
|
|
153324
153534
|
}
|
|
@@ -153391,7 +153601,7 @@ async function resolveSlackThreadHistory(params) {
|
|
|
153391
153601
|
...cursor ? { cursor } : {}
|
|
153392
153602
|
});
|
|
153393
153603
|
for (const message of response.messages ?? []) {
|
|
153394
|
-
if (params.include === "bot" && !
|
|
153604
|
+
if (params.include === "bot" && !isNonEmptyString6(message.bot_id)) {
|
|
153395
153605
|
continue;
|
|
153396
153606
|
}
|
|
153397
153607
|
if (!hasSlackThreadMessageContent(message, attachmentOptions)) {
|
|
@@ -153455,11 +153665,11 @@ var init_media2 = __esm(() => {
|
|
|
153455
153665
|
});
|
|
153456
153666
|
|
|
153457
153667
|
// src/channels/slack/attachment-download.ts
|
|
153458
|
-
function
|
|
153668
|
+
function isNonEmptyString7(value) {
|
|
153459
153669
|
return typeof value === "string" && value.trim().length > 0;
|
|
153460
153670
|
}
|
|
153461
153671
|
async function resolveCanonicalSlackMessage(params) {
|
|
153462
|
-
if (
|
|
153672
|
+
if (isNonEmptyString7(params.threadTs)) {
|
|
153463
153673
|
let cursor;
|
|
153464
153674
|
do {
|
|
153465
153675
|
const response2 = await params.client.conversations.replies({
|
|
@@ -153474,7 +153684,7 @@ async function resolveCanonicalSlackMessage(params) {
|
|
|
153474
153684
|
return message;
|
|
153475
153685
|
}
|
|
153476
153686
|
const nextCursor = response2.response_metadata?.next_cursor;
|
|
153477
|
-
cursor =
|
|
153687
|
+
cursor = isNonEmptyString7(nextCursor) ? nextCursor.trim() : undefined;
|
|
153478
153688
|
} while (cursor);
|
|
153479
153689
|
return null;
|
|
153480
153690
|
}
|
|
@@ -153626,7 +153836,7 @@ function createSlackInboundDebounceController(params) {
|
|
|
153626
153836
|
const deduped = [];
|
|
153627
153837
|
for (const entry of entries) {
|
|
153628
153838
|
const messageId = entry.inbound.messageId;
|
|
153629
|
-
const messageKey =
|
|
153839
|
+
const messageKey = isNonEmptyString4(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
|
|
153630
153840
|
if (!messageKey) {
|
|
153631
153841
|
deduped.push(entry);
|
|
153632
153842
|
continue;
|
|
@@ -153661,7 +153871,7 @@ function createSlackInboundDebounceController(params) {
|
|
|
153661
153871
|
if (pending?.size === 0)
|
|
153662
153872
|
pendingTopLevelKeys.delete(conversationKey);
|
|
153663
153873
|
}
|
|
153664
|
-
if (
|
|
153874
|
+
if (isNonEmptyString4(last.inbound.messageId)) {
|
|
153665
153875
|
const seenKey = `${last.inbound.chatId}:${last.inbound.messageId}`;
|
|
153666
153876
|
pruneAppMentionMaps(Date.now());
|
|
153667
153877
|
if (last.opts.source === "app_mention") {
|
|
@@ -153740,13 +153950,13 @@ function hasRecordValue(value) {
|
|
|
153740
153950
|
return value !== null && typeof value === "object";
|
|
153741
153951
|
}
|
|
153742
153952
|
function hasSlackMention(text, userId) {
|
|
153743
|
-
return
|
|
153953
|
+
return isNonEmptyString5(text) && isNonEmptyString5(userId) && (text.includes(`<@${userId}>`) || text.includes(`<@${userId}|`));
|
|
153744
153954
|
}
|
|
153745
153955
|
function isBotAuthoredMessage(message) {
|
|
153746
|
-
return
|
|
153956
|
+
return isNonEmptyString5(message.bot_id) || message.subtype === "bot_message";
|
|
153747
153957
|
}
|
|
153748
153958
|
function resolveMessageSubtypeIgnoreReason(message) {
|
|
153749
|
-
const subtype =
|
|
153959
|
+
const subtype = isNonEmptyString5(message.subtype) ? message.subtype : null;
|
|
153750
153960
|
if (!subtype) {
|
|
153751
153961
|
return null;
|
|
153752
153962
|
}
|
|
@@ -153760,14 +153970,14 @@ function resolveMessageSubtypeIgnoreReason(message) {
|
|
|
153760
153970
|
}
|
|
153761
153971
|
function resolveSlackMessageIngressPolicy(params) {
|
|
153762
153972
|
const { message } = params;
|
|
153763
|
-
if (!
|
|
153973
|
+
if (!isNonEmptyString5(message.channel)) {
|
|
153764
153974
|
return { shouldRoute: false, reason: "missing_channel" };
|
|
153765
153975
|
}
|
|
153766
153976
|
const senderId = firstNonEmptyString3(message.user, message.bot_id);
|
|
153767
153977
|
if (!senderId) {
|
|
153768
153978
|
return { shouldRoute: false, reason: "missing_sender" };
|
|
153769
153979
|
}
|
|
153770
|
-
if (!
|
|
153980
|
+
if (!isNonEmptyString5(message.ts)) {
|
|
153771
153981
|
return { shouldRoute: false, reason: "missing_timestamp" };
|
|
153772
153982
|
}
|
|
153773
153983
|
if (message.hidden === true) {
|
|
@@ -153779,10 +153989,10 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153779
153989
|
}
|
|
153780
153990
|
const chatType = resolveSlackChatType2(message.channel);
|
|
153781
153991
|
const threadId = chatType === "direct" ? firstNonEmptyString3(message.thread_ts) ?? null : firstNonEmptyString3(message.thread_ts, message.ts) ?? null;
|
|
153782
|
-
if (chatType === "channel" && !
|
|
153992
|
+
if (chatType === "channel" && !isNonEmptyString5(message.thread_ts)) {
|
|
153783
153993
|
return { shouldRoute: false, reason: "top_level_channel_message" };
|
|
153784
153994
|
}
|
|
153785
|
-
const rawText =
|
|
153995
|
+
const rawText = isNonEmptyString5(message.text) ? message.text : "";
|
|
153786
153996
|
const wasMentioned = hasSlackMention(rawText, params.botUserId);
|
|
153787
153997
|
const isAgentThread = params.isAgentThread === true;
|
|
153788
153998
|
const effectiveMention = isBotAuthoredMessage(message) ? wasMentioned : wasMentioned || isAgentThread;
|
|
@@ -153790,8 +154000,8 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153790
154000
|
shouldRoute: true,
|
|
153791
154001
|
channelId: message.channel,
|
|
153792
154002
|
senderId,
|
|
153793
|
-
...
|
|
153794
|
-
...
|
|
154003
|
+
...isNonEmptyString5(message.user) ? { senderUserId: message.user } : {},
|
|
154004
|
+
...isNonEmptyString5(message.bot_id) ? { senderBotId: message.bot_id } : {},
|
|
153795
154005
|
messageId: message.ts,
|
|
153796
154006
|
threadId,
|
|
153797
154007
|
chatType,
|
|
@@ -153804,23 +154014,23 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153804
154014
|
}
|
|
153805
154015
|
function resolveSlackAppMentionIngressPolicy(params) {
|
|
153806
154016
|
const { event: event2 } = params;
|
|
153807
|
-
if (!
|
|
154017
|
+
if (!isNonEmptyString5(event2.channel)) {
|
|
153808
154018
|
return { shouldRoute: false, reason: "missing_channel" };
|
|
153809
154019
|
}
|
|
153810
154020
|
const senderId = firstNonEmptyString3(event2.user, event2.bot_id);
|
|
153811
154021
|
if (!senderId) {
|
|
153812
154022
|
return { shouldRoute: false, reason: "missing_sender" };
|
|
153813
154023
|
}
|
|
153814
|
-
if (!
|
|
154024
|
+
if (!isNonEmptyString5(event2.ts)) {
|
|
153815
154025
|
return { shouldRoute: false, reason: "missing_timestamp" };
|
|
153816
154026
|
}
|
|
153817
|
-
const rawText =
|
|
154027
|
+
const rawText = isNonEmptyString5(event2.text) ? event2.text : "";
|
|
153818
154028
|
return {
|
|
153819
154029
|
shouldRoute: true,
|
|
153820
154030
|
channelId: event2.channel,
|
|
153821
154031
|
senderId,
|
|
153822
|
-
...
|
|
153823
|
-
...
|
|
154032
|
+
...isNonEmptyString5(event2.user) ? { senderUserId: event2.user } : {},
|
|
154033
|
+
...isNonEmptyString5(event2.bot_id) ? { senderBotId: event2.bot_id } : {},
|
|
153824
154034
|
messageId: event2.ts,
|
|
153825
154035
|
threadId: firstNonEmptyString3(event2.thread_ts, event2.ts) ?? event2.ts,
|
|
153826
154036
|
chatType: "channel",
|
|
@@ -153888,7 +154098,7 @@ function createSlackIngressController(params) {
|
|
|
153888
154098
|
}
|
|
153889
154099
|
}
|
|
153890
154100
|
function markIngressMessageSeen(channelId, messageId) {
|
|
153891
|
-
if (!
|
|
154101
|
+
if (!isNonEmptyString4(channelId) || !isNonEmptyString4(messageId)) {
|
|
153892
154102
|
return false;
|
|
153893
154103
|
}
|
|
153894
154104
|
const key = `${channelId}:${messageId}`;
|
|
@@ -153899,12 +154109,12 @@ function createSlackIngressController(params) {
|
|
|
153899
154109
|
return false;
|
|
153900
154110
|
}
|
|
153901
154111
|
function rememberMessageThread(messageId, threadId) {
|
|
153902
|
-
if (
|
|
154112
|
+
if (isNonEmptyString4(messageId)) {
|
|
153903
154113
|
knownThreadIdsByMessageId.set(messageId, threadId);
|
|
153904
154114
|
}
|
|
153905
154115
|
}
|
|
153906
154116
|
async function resolveUserName(app, userId) {
|
|
153907
|
-
if (!
|
|
154117
|
+
if (!isNonEmptyString4(userId))
|
|
153908
154118
|
return;
|
|
153909
154119
|
const cached2 = knownUserDisplayNames.get(userId);
|
|
153910
154120
|
if (cached2)
|
|
@@ -153920,10 +154130,10 @@ function createSlackIngressController(params) {
|
|
|
153920
154130
|
return userId;
|
|
153921
154131
|
}
|
|
153922
154132
|
async function resolveInboundSenderName(app, userId, botId) {
|
|
153923
|
-
if (
|
|
154133
|
+
if (isNonEmptyString4(userId)) {
|
|
153924
154134
|
return resolveUserName(app, userId);
|
|
153925
154135
|
}
|
|
153926
|
-
return
|
|
154136
|
+
return isNonEmptyString4(botId) ? `Bot (${botId})` : undefined;
|
|
153927
154137
|
}
|
|
153928
154138
|
function shouldAcceptInboundMessageByBotPolicy(input) {
|
|
153929
154139
|
return shouldAcceptSlackInboundBotMessage({
|
|
@@ -153951,7 +154161,7 @@ function createSlackIngressController(params) {
|
|
|
153951
154161
|
return;
|
|
153952
154162
|
const rawMessage = asRecord2(message);
|
|
153953
154163
|
const channelId = rawMessage?.channel;
|
|
153954
|
-
if (!rawMessage || !
|
|
154164
|
+
if (!rawMessage || !isNonEmptyString4(channelId)) {
|
|
153955
154165
|
return;
|
|
153956
154166
|
}
|
|
153957
154167
|
const basePolicy = resolveSlackMessageIngressPolicy({
|
|
@@ -153973,7 +154183,7 @@ function createSlackIngressController(params) {
|
|
|
153973
154183
|
transcribeVoice: config3.transcribeVoice === true
|
|
153974
154184
|
});
|
|
153975
154185
|
const senderName = await resolveInboundSenderName(app, basePolicy.senderUserId, basePolicy.senderBotId);
|
|
153976
|
-
const isAgentThread = basePolicy.chatType === "channel" &&
|
|
154186
|
+
const isAgentThread = basePolicy.chatType === "channel" && isNonEmptyString4(basePolicy.threadId) && params.agentThreadTracker.has(channelId, basePolicy.threadId);
|
|
153977
154187
|
const policy = resolveSlackMessageIngressPolicy({
|
|
153978
154188
|
message: rawMessage,
|
|
153979
154189
|
botUserId: params.getBotUserId(),
|
|
@@ -154076,10 +154286,10 @@ function createSlackIngressController(params) {
|
|
|
154076
154286
|
}) => {
|
|
154077
154287
|
await ack();
|
|
154078
154288
|
const adapter = params.getAdapter();
|
|
154079
|
-
if (!adapter.onMessage || !
|
|
154289
|
+
if (!adapter.onMessage || !isNonEmptyString4(command.command) || !isNonEmptyString4(command.channel_id) || !isNonEmptyString4(command.user_id)) {
|
|
154080
154290
|
return;
|
|
154081
154291
|
}
|
|
154082
|
-
const args =
|
|
154292
|
+
const args = isNonEmptyString4(command.text) ? command.text.trim() : "";
|
|
154083
154293
|
try {
|
|
154084
154294
|
await adapter.onMessage({
|
|
154085
154295
|
channel: "slack",
|
|
@@ -154143,7 +154353,7 @@ function createSlackIngressController(params) {
|
|
|
154143
154353
|
const item = asRecord2(event2.item);
|
|
154144
154354
|
const chatId = item?.channel;
|
|
154145
154355
|
const targetMessageId = item?.ts;
|
|
154146
|
-
if (!adapter.onMessage || item?.type !== "message" || !
|
|
154356
|
+
if (!adapter.onMessage || item?.type !== "message" || !isNonEmptyString4(chatId) || !isNonEmptyString4(targetMessageId) || !isNonEmptyString4(event2.user) || !isNonEmptyString4(event2.reaction) || event2.user === params.getBotUserId()) {
|
|
154147
154357
|
return;
|
|
154148
154358
|
}
|
|
154149
154359
|
const chatType = resolveSlackChatType(chatId);
|
|
@@ -154167,7 +154377,7 @@ function createSlackIngressController(params) {
|
|
|
154167
154377
|
action: action3,
|
|
154168
154378
|
emoji: event2.reaction,
|
|
154169
154379
|
targetMessageId,
|
|
154170
|
-
targetSenderId:
|
|
154380
|
+
targetSenderId: isNonEmptyString4(event2.item_user) ? event2.item_user : undefined
|
|
154171
154381
|
},
|
|
154172
154382
|
raw: event2
|
|
154173
154383
|
});
|
|
@@ -154213,22 +154423,22 @@ function createSlackStatusController(params) {
|
|
|
154213
154423
|
const keepaliveByConversation = new Map;
|
|
154214
154424
|
const clearedStaleReplyKeys = new Set;
|
|
154215
154425
|
function getConversationKey(source2) {
|
|
154216
|
-
return source2.channel === "slack" &&
|
|
154426
|
+
return source2.channel === "slack" && isNonEmptyString5(source2.agentId) && isNonEmptyString5(source2.conversationId) ? `${source2.agentId}:${source2.conversationId}` : null;
|
|
154217
154427
|
}
|
|
154218
154428
|
function getLifecycleReplyKey(source2) {
|
|
154219
|
-
if (source2.channel !== "slack" || !
|
|
154429
|
+
if (source2.channel !== "slack" || !isNonEmptyString5(source2.chatId)) {
|
|
154220
154430
|
return null;
|
|
154221
154431
|
}
|
|
154222
154432
|
const replyToMessageId = resolveSlackProgressThreadTs(source2);
|
|
154223
|
-
return
|
|
154433
|
+
return isNonEmptyString5(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : null;
|
|
154224
154434
|
}
|
|
154225
154435
|
function getLifecycleErrorReplyKey(source2) {
|
|
154226
|
-
if (source2.channel !== "slack" || !
|
|
154436
|
+
if (source2.channel !== "slack" || !isNonEmptyString5(source2.chatId)) {
|
|
154227
154437
|
return null;
|
|
154228
154438
|
}
|
|
154229
154439
|
if (source2.chatType === "direct" || resolveSlackChatType2(source2.chatId) === "direct") {
|
|
154230
154440
|
const replyToMessageId = resolveSlackSourceThreadTs2(source2);
|
|
154231
|
-
return
|
|
154441
|
+
return isNonEmptyString5(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : `${source2.chatId}:direct`;
|
|
154232
154442
|
}
|
|
154233
154443
|
return getLifecycleReplyKey(source2);
|
|
154234
154444
|
}
|
|
@@ -154387,7 +154597,7 @@ ${loadingText}`;
|
|
|
154387
154597
|
markAutoClearedByKey(key);
|
|
154388
154598
|
},
|
|
154389
154599
|
markAutoClearedForMessage(msg) {
|
|
154390
|
-
if (
|
|
154600
|
+
if (isNonEmptyString5(msg.agentId) && isNonEmptyString5(msg.conversationId)) {
|
|
154391
154601
|
markAutoClearedByKey(`${msg.agentId}:${msg.conversationId}`);
|
|
154392
154602
|
return;
|
|
154393
154603
|
}
|
|
@@ -154435,7 +154645,7 @@ function truncateThreadLabel(text, maxLength3 = 80) {
|
|
|
154435
154645
|
return normalized.length <= maxLength3 ? normalized : `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
|
|
154436
154646
|
}
|
|
154437
154647
|
function buildThreadLabel(msg, starterText) {
|
|
154438
|
-
const roomLabel = msg.chatType === "channel" &&
|
|
154648
|
+
const roomLabel = msg.chatType === "channel" && isNonEmptyString4(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
154439
154649
|
const preview = truncateThreadLabel(starterText ?? msg.text);
|
|
154440
154650
|
const threadLabel = msg.chatType === "direct" ? "Slack DM thread" : "Slack thread";
|
|
154441
154651
|
if (preview)
|
|
@@ -154445,12 +154655,12 @@ function buildThreadLabel(msg, starterText) {
|
|
|
154445
154655
|
function buildChannelContextLabel(msg) {
|
|
154446
154656
|
if (msg.chatType !== "channel")
|
|
154447
154657
|
return;
|
|
154448
|
-
const roomLabel =
|
|
154658
|
+
const roomLabel = isNonEmptyString4(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
154449
154659
|
return roomLabel ? `Slack channel context${roomLabel} before thread start` : "Slack channel context before thread start";
|
|
154450
154660
|
}
|
|
154451
154661
|
async function prepareSlackInboundMessage(params) {
|
|
154452
154662
|
const { msg, config: config3 } = params;
|
|
154453
|
-
if (msg.channel !== "slack" || !
|
|
154663
|
+
if (msg.channel !== "slack" || !isNonEmptyString4(msg.threadId) || !isNonEmptyString4(msg.messageId)) {
|
|
154454
154664
|
return msg;
|
|
154455
154665
|
}
|
|
154456
154666
|
const isFirstRouteTurn = params.options?.isFirstRouteTurn === true;
|
|
@@ -154499,18 +154709,18 @@ async function prepareSlackInboundMessage(params) {
|
|
|
154499
154709
|
return msg;
|
|
154500
154710
|
}
|
|
154501
154711
|
const userIds = new Set;
|
|
154502
|
-
if (
|
|
154712
|
+
if (isNonEmptyString4(starter?.userId))
|
|
154503
154713
|
userIds.add(starter.userId);
|
|
154504
154714
|
for (const entry of history) {
|
|
154505
|
-
if (
|
|
154715
|
+
if (isNonEmptyString4(entry.userId))
|
|
154506
154716
|
userIds.add(entry.userId);
|
|
154507
154717
|
}
|
|
154508
154718
|
await Promise.all(Array.from(userIds).map((userId) => params.resolveUserName(app, userId)));
|
|
154509
154719
|
const resolveSenderName = (userId, botId) => {
|
|
154510
|
-
if (
|
|
154720
|
+
if (isNonEmptyString4(userId)) {
|
|
154511
154721
|
return params.getKnownUserDisplayName(userId) ?? userId;
|
|
154512
154722
|
}
|
|
154513
|
-
return
|
|
154723
|
+
return isNonEmptyString4(botId) ? `Bot (${botId})` : undefined;
|
|
154514
154724
|
};
|
|
154515
154725
|
return {
|
|
154516
154726
|
...msg,
|
|
@@ -154669,7 +154879,7 @@ function createSlackAdapter(config3) {
|
|
|
154669
154879
|
if (!running)
|
|
154670
154880
|
return;
|
|
154671
154881
|
if (event2.type === "queued") {
|
|
154672
|
-
if (isSlackFlatChannelThreadOpener(event2.source) &&
|
|
154882
|
+
if (isSlackFlatChannelThreadOpener(event2.source) && isNonEmptyString4(event2.source.messageId) && !agentThreadTracker.has(event2.source.chatId, event2.source.messageId)) {
|
|
154673
154883
|
await status.activate(event2.source, SLACK_ASSISTANT_STARTUP_STATUS, SLACK_ASSISTANT_STARTUP_STATUS);
|
|
154674
154884
|
}
|
|
154675
154885
|
return;
|
|
@@ -154731,7 +154941,7 @@ function createSlackAdapter(config3) {
|
|
|
154731
154941
|
if (msg.mediaPath) {
|
|
154732
154942
|
const result = await uploadSlackFile(client, msg);
|
|
154733
154943
|
const threadId = msg.threadId ?? msg.replyToMessageId ?? null;
|
|
154734
|
-
if (resolveSlackChatType(msg.chatId) === "channel" &&
|
|
154944
|
+
if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString4(threadId)) {
|
|
154735
154945
|
agentThreadTracker.remember(msg.chatId, threadId);
|
|
154736
154946
|
}
|
|
154737
154947
|
status.markAutoClearedForMessage(msg);
|
|
@@ -154742,7 +154952,7 @@ function createSlackAdapter(config3) {
|
|
|
154742
154952
|
threadId: msg.threadId,
|
|
154743
154953
|
replyToMessageId: msg.replyToMessageId
|
|
154744
154954
|
});
|
|
154745
|
-
const footnote =
|
|
154955
|
+
const footnote = isNonEmptyString4(msg.agentId) && isNonEmptyString4(msg.conversationId) ? buildSlackChatFootnote({
|
|
154746
154956
|
agentId: msg.agentId,
|
|
154747
154957
|
conversationId: msg.conversationId
|
|
154748
154958
|
}) : "";
|
|
@@ -154755,7 +154965,7 @@ function createSlackAdapter(config3) {
|
|
|
154755
154965
|
});
|
|
154756
154966
|
const outboundThreadId = threadTs ?? (resolveSlackChatType(msg.chatId) === "channel" ? response.ts ?? null : null);
|
|
154757
154967
|
ingress.rememberMessageThread(response.ts, outboundThreadId);
|
|
154758
|
-
if (resolveSlackChatType(msg.chatId) === "channel" &&
|
|
154968
|
+
if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154759
154969
|
agentThreadTracker.remember(msg.chatId, outboundThreadId);
|
|
154760
154970
|
}
|
|
154761
154971
|
status.markAutoClearedForMessage(msg);
|
|
@@ -154778,7 +154988,7 @@ function createSlackAdapter(config3) {
|
|
|
154778
154988
|
});
|
|
154779
154989
|
const outboundThreadId = threadTs ?? (resolveSlackChatType(chatId) === "channel" ? response.ts ?? null : null);
|
|
154780
154990
|
ingress.rememberMessageThread(response.ts, outboundThreadId);
|
|
154781
|
-
if (resolveSlackChatType(chatId) === "channel" &&
|
|
154991
|
+
if (resolveSlackChatType(chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154782
154992
|
agentThreadTracker.remember(chatId, outboundThreadId);
|
|
154783
154993
|
}
|
|
154784
154994
|
status.markAutoClearedForMessage({
|
|
@@ -154804,7 +155014,7 @@ function createSlackAdapter(config3) {
|
|
|
154804
155014
|
if (event2.kind === "generic_tool_approval" && response.ts) {
|
|
154805
155015
|
approvals.rememberPrompt(event2, response.ts);
|
|
154806
155016
|
}
|
|
154807
|
-
if (resolveSlackChatType(event2.source.chatId) === "channel" &&
|
|
155017
|
+
if (resolveSlackChatType(event2.source.chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154808
155018
|
agentThreadTracker.remember(event2.source.chatId, outboundThreadId);
|
|
154809
155019
|
}
|
|
154810
155020
|
status.markAutoCleared(event2.source);
|
|
@@ -154820,8 +155030,8 @@ function createSlackAdapter(config3) {
|
|
|
154820
155030
|
const slackApp = await ensureApp();
|
|
154821
155031
|
const auth = await slackApp.client.auth.test();
|
|
154822
155032
|
const authRecord = auth;
|
|
154823
|
-
botUserId =
|
|
154824
|
-
botId =
|
|
155033
|
+
botUserId = isNonEmptyString4(authRecord.user_id) ? authRecord.user_id : null;
|
|
155034
|
+
botId = isNonEmptyString4(authRecord.bot_id) ? authRecord.bot_id : null;
|
|
154825
155035
|
await slackApp.start();
|
|
154826
155036
|
running = true;
|
|
154827
155037
|
console.log(`[Slack] App started for workspace ${auth.team ?? "unknown"} (dm_policy: ${config3.dmPolicy})`);
|
|
@@ -156044,7 +156254,7 @@ function formatDiscordDeliveryError(error54) {
|
|
|
156044
156254
|
}
|
|
156045
156255
|
|
|
156046
156256
|
// src/channels/discord/utils.ts
|
|
156047
|
-
function
|
|
156257
|
+
function isNonEmptyString8(value) {
|
|
156048
156258
|
return typeof value === "string" && value.length > 0;
|
|
156049
156259
|
}
|
|
156050
156260
|
function isDiscordTextChannel(channel) {
|
|
@@ -156111,7 +156321,7 @@ function shouldAutoThreadOnDiscordMention(account, channelId) {
|
|
|
156111
156321
|
return account.autoThreadOnMention ?? false;
|
|
156112
156322
|
}
|
|
156113
156323
|
function buildDiscordIngressMessageKey(accountId, messageId) {
|
|
156114
|
-
if (!
|
|
156324
|
+
if (!isNonEmptyString8(accountId) || !isNonEmptyString8(messageId)) {
|
|
156115
156325
|
return null;
|
|
156116
156326
|
}
|
|
156117
156327
|
return `${accountId}:${messageId}`;
|
|
@@ -156195,13 +156405,13 @@ function createDiscordAdapter(config3) {
|
|
|
156195
156405
|
return false;
|
|
156196
156406
|
}
|
|
156197
156407
|
function getLifecycleMessageKey(source2) {
|
|
156198
|
-
if (source2.channel !== "discord" || !
|
|
156408
|
+
if (source2.channel !== "discord" || !isNonEmptyString8(source2.chatId) || !isNonEmptyString8(source2.messageId)) {
|
|
156199
156409
|
return null;
|
|
156200
156410
|
}
|
|
156201
156411
|
return `${source2.chatId}:${source2.messageId}`;
|
|
156202
156412
|
}
|
|
156203
156413
|
function getLifecycleReplyKey(source2) {
|
|
156204
|
-
if (source2.channel !== "discord" || !
|
|
156414
|
+
if (source2.channel !== "discord" || !isNonEmptyString8(source2.chatId)) {
|
|
156205
156415
|
return null;
|
|
156206
156416
|
}
|
|
156207
156417
|
return [
|
|
@@ -156214,7 +156424,7 @@ function createDiscordAdapter(config3) {
|
|
|
156214
156424
|
if (source2.channel !== "discord")
|
|
156215
156425
|
return null;
|
|
156216
156426
|
const channelId = source2.threadId ?? source2.chatId;
|
|
156217
|
-
return
|
|
156427
|
+
return isNonEmptyString8(channelId) ? channelId : null;
|
|
156218
156428
|
}
|
|
156219
156429
|
function getTypingSourceKey(source2) {
|
|
156220
156430
|
const channelId = getTypingChannelId(source2);
|
|
@@ -156266,7 +156476,7 @@ function createDiscordAdapter(config3) {
|
|
|
156266
156476
|
return true;
|
|
156267
156477
|
}
|
|
156268
156478
|
async function sendLifecycleReaction(source2, emoji3, remove = false) {
|
|
156269
|
-
if (!client || !
|
|
156479
|
+
if (!client || !isNonEmptyString8(source2.messageId))
|
|
156270
156480
|
return;
|
|
156271
156481
|
try {
|
|
156272
156482
|
const channel = await client.channels.fetch(source2.chatId);
|
|
@@ -156507,15 +156717,23 @@ function createDiscordAdapter(config3) {
|
|
|
156507
156717
|
client.on("messageCreate", async (message) => {
|
|
156508
156718
|
if (!adapter.onMessage)
|
|
156509
156719
|
return;
|
|
156510
|
-
if (message.author.bot)
|
|
156511
|
-
return;
|
|
156512
156720
|
const content = (message.content ?? "").trim();
|
|
156513
156721
|
const userId = message.author.id;
|
|
156514
156722
|
if (!userId)
|
|
156515
156723
|
return;
|
|
156724
|
+
const effectiveBotUserId = botUserId ?? client?.user?.id ?? null;
|
|
156516
156725
|
const chatType = resolveDiscordChatType(message.guildId);
|
|
156517
156726
|
const isThread = isThreadMessage(message);
|
|
156518
|
-
const
|
|
156727
|
+
const hasParsedBotMention = hasBotMention(message);
|
|
156728
|
+
const wasMentioned = chatType === "channel" && hasParsedBotMention;
|
|
156729
|
+
if (!shouldAcceptDiscordInboundBotMessage({
|
|
156730
|
+
message,
|
|
156731
|
+
allowBots: config3.allowBots,
|
|
156732
|
+
botUserId: effectiveBotUserId,
|
|
156733
|
+
wasExplicitlyMentioned: hasParsedBotMention && hasExplicitDiscordUserMention(message, effectiveBotUserId)
|
|
156734
|
+
})) {
|
|
156735
|
+
return;
|
|
156736
|
+
}
|
|
156519
156737
|
if (chatType === "direct") {
|
|
156520
156738
|
if (markIngressMessageSeen(message.id))
|
|
156521
156739
|
return;
|
|
@@ -156541,7 +156759,9 @@ function createDiscordAdapter(config3) {
|
|
|
156541
156759
|
await adapter.onMessage(inbound2);
|
|
156542
156760
|
} catch (error54) {
|
|
156543
156761
|
console.error("[Discord] Error handling DM:", error54);
|
|
156544
|
-
|
|
156762
|
+
if (!message.author.bot) {
|
|
156763
|
+
await notifyDiscordDeliveryError(message, error54);
|
|
156764
|
+
}
|
|
156545
156765
|
}
|
|
156546
156766
|
return;
|
|
156547
156767
|
}
|
|
@@ -156596,7 +156816,9 @@ function createDiscordAdapter(config3) {
|
|
|
156596
156816
|
await adapter.onMessage(inbound);
|
|
156597
156817
|
} catch (error54) {
|
|
156598
156818
|
console.error("[Discord] Error handling guild message:", error54);
|
|
156599
|
-
|
|
156819
|
+
if (!message.author.bot) {
|
|
156820
|
+
await notifyDiscordDeliveryError(message, error54);
|
|
156821
|
+
}
|
|
156600
156822
|
}
|
|
156601
156823
|
});
|
|
156602
156824
|
const handleReactionEvent = async (reaction, user, action3) => {
|
|
@@ -156805,7 +157027,7 @@ function createDiscordAdapter(config3) {
|
|
|
156805
157027
|
clearTypingForChannel(chatId);
|
|
156806
157028
|
},
|
|
156807
157029
|
async prepareInboundMessage(msg, options3) {
|
|
156808
|
-
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !
|
|
157030
|
+
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString8(msg.threadId) || !client) {
|
|
156809
157031
|
return msg;
|
|
156810
157032
|
}
|
|
156811
157033
|
const starter = await resolveDiscordThreadStarter({
|
|
@@ -160858,168 +161080,6 @@ var init_app_urls = __esm(() => {
|
|
|
160858
161080
|
LETTA_CHAT_API_KEYS_URL = `${CHAT_BASE}/preferences/api-keys`;
|
|
160859
161081
|
});
|
|
160860
161082
|
|
|
160861
|
-
// src/channels/registry-presentation.ts
|
|
160862
|
-
function channelDisplayName4(channelId) {
|
|
160863
|
-
try {
|
|
160864
|
-
return getChannelDisplayName(channelId);
|
|
160865
|
-
} catch {
|
|
160866
|
-
return channelId;
|
|
160867
|
-
}
|
|
160868
|
-
}
|
|
160869
|
-
function normalizeAgentId(agentId) {
|
|
160870
|
-
const normalized = agentId?.trim();
|
|
160871
|
-
return normalized ? normalized : null;
|
|
160872
|
-
}
|
|
160873
|
-
function getConfiguredAgentId(config3) {
|
|
160874
|
-
if (!config3 || typeof config3 !== "object")
|
|
160875
|
-
return null;
|
|
160876
|
-
const source2 = config3;
|
|
160877
|
-
return normalizeAgentId(source2.agentId) ?? normalizeAgentId(source2.binding?.agentId);
|
|
160878
|
-
}
|
|
160879
|
-
function buildPairingInstructions(channelId, code2, options3 = {}) {
|
|
160880
|
-
const displayName = channelDisplayName4(channelId);
|
|
160881
|
-
const configuredAgentId = normalizeAgentId(options3.agentId);
|
|
160882
|
-
const pairingCommand = `letta channels pair --channel ${channelId} --code ${code2} --agent ${configuredAgentId ?? "<agent-id>"}`;
|
|
160883
|
-
const agentLookupLines = configuredAgentId ? [] : ["Find the target agent with: letta agents list"];
|
|
160884
|
-
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
160885
|
-
return [
|
|
160886
|
-
"Connect this chat to a Letta agent.",
|
|
160887
|
-
"",
|
|
160888
|
-
`Pairing code: ${code2}`,
|
|
160889
|
-
"",
|
|
160890
|
-
"CLI on the listener machine:",
|
|
160891
|
-
pairingCommand,
|
|
160892
|
-
...agentLookupLines,
|
|
160893
|
-
"",
|
|
160894
|
-
"This code expires in 15 minutes."
|
|
160895
|
-
].join(`
|
|
160896
|
-
`);
|
|
160897
|
-
}
|
|
160898
|
-
return [
|
|
160899
|
-
"Connect this chat to a Letta agent.",
|
|
160900
|
-
"",
|
|
160901
|
-
`Pairing code: ${code2}`,
|
|
160902
|
-
"",
|
|
160903
|
-
`In Letta Code: open Channels > ${displayName} and approve this pending chat.`,
|
|
160904
|
-
"",
|
|
160905
|
-
"CLI on the listener machine:",
|
|
160906
|
-
pairingCommand,
|
|
160907
|
-
...agentLookupLines,
|
|
160908
|
-
"",
|
|
160909
|
-
"This code expires in 15 minutes."
|
|
160910
|
-
].join(`
|
|
160911
|
-
`);
|
|
160912
|
-
}
|
|
160913
|
-
function buildUnboundRouteInstructions(channelId, chatId) {
|
|
160914
|
-
const displayName = channelDisplayName4(channelId);
|
|
160915
|
-
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
160916
|
-
return `This chat isn't connected to a Letta agent yet.
|
|
160917
|
-
|
|
160918
|
-
` + `On the machine where your listener runs:
|
|
160919
|
-
|
|
160920
|
-
` + `letta channels route add --channel ${channelId} --chat-id ${chatId} --agent <agent-id>
|
|
160921
|
-
|
|
160922
|
-
` + `Find your agent id with letta agents list.`;
|
|
160923
|
-
}
|
|
160924
|
-
return `This chat isn't connected to a Letta agent yet.
|
|
160925
|
-
|
|
160926
|
-
` + `Open Channels > ${displayName} in Letta Code and connect this chat there.
|
|
160927
|
-
|
|
160928
|
-
` + `Chat ID: ${chatId}`;
|
|
160929
|
-
}
|
|
160930
|
-
function buildSlackAppSetupInstructions() {
|
|
160931
|
-
return `This Slack app isn't connected to a Letta agent yet.
|
|
160932
|
-
|
|
160933
|
-
` + "Open Channels > Slack in Letta Code, choose which agent this app should represent, and try again.";
|
|
160934
|
-
}
|
|
160935
|
-
function truncateChannelSummaryPreview(text, maxLength3 = 72) {
|
|
160936
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
160937
|
-
if (!normalized)
|
|
160938
|
-
return null;
|
|
160939
|
-
if (normalized.length <= maxLength3)
|
|
160940
|
-
return normalized;
|
|
160941
|
-
return `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
|
|
160942
|
-
}
|
|
160943
|
-
function buildSlackConversationSummary(msg) {
|
|
160944
|
-
if (msg.chatType === "direct") {
|
|
160945
|
-
if (msg.threadId?.trim()) {
|
|
160946
|
-
const preview3 = truncateChannelSummaryPreview(msg.text);
|
|
160947
|
-
return preview3 ? `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}: ${preview3}` : `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160948
|
-
}
|
|
160949
|
-
return `[Slack] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160950
|
-
}
|
|
160951
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160952
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160953
|
-
if (preview2)
|
|
160954
|
-
return `[Slack] Thread${channelLabel}: ${preview2}`;
|
|
160955
|
-
return `[Slack] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
160956
|
-
}
|
|
160957
|
-
function buildDiscordConversationSummary(msg) {
|
|
160958
|
-
if (msg.chatType === "direct") {
|
|
160959
|
-
return `[Discord] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160960
|
-
}
|
|
160961
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160962
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160963
|
-
if (preview2)
|
|
160964
|
-
return `[Discord] Thread${channelLabel}: ${preview2}`;
|
|
160965
|
-
return `[Discord] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
160966
|
-
}
|
|
160967
|
-
function buildTelegramConversationSummary(msg) {
|
|
160968
|
-
if (msg.chatType === "direct") {
|
|
160969
|
-
return `[Telegram] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160970
|
-
}
|
|
160971
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160972
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160973
|
-
if (preview2)
|
|
160974
|
-
return `[Telegram] Topic${channelLabel}: ${preview2}`;
|
|
160975
|
-
return `[Telegram] Topic${channelLabel || ` ${msg.chatId}`}`;
|
|
160976
|
-
}
|
|
160977
|
-
function buildWhatsAppConversationSummary(msg) {
|
|
160978
|
-
if (msg.chatType === "direct") {
|
|
160979
|
-
return `[WhatsApp] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160980
|
-
}
|
|
160981
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160982
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160983
|
-
if (preview2)
|
|
160984
|
-
return `[WhatsApp] Group${channelLabel}: ${preview2}`;
|
|
160985
|
-
return `[WhatsApp] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
160986
|
-
}
|
|
160987
|
-
function buildSignalConversationSummary(msg) {
|
|
160988
|
-
if (msg.chatType === "direct") {
|
|
160989
|
-
return `[Signal] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160990
|
-
}
|
|
160991
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160992
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160993
|
-
if (preview2)
|
|
160994
|
-
return `[Signal] Group${channelLabel}: ${preview2}`;
|
|
160995
|
-
return `[Signal] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
160996
|
-
}
|
|
160997
|
-
function buildChannelTurnSource(route, msg) {
|
|
160998
|
-
return {
|
|
160999
|
-
channel: msg.channel,
|
|
161000
|
-
accountId: msg.accountId,
|
|
161001
|
-
chatId: msg.chatId,
|
|
161002
|
-
chatType: msg.chatType,
|
|
161003
|
-
senderId: msg.senderId,
|
|
161004
|
-
senderTeamId: msg.senderTeamId,
|
|
161005
|
-
messageId: msg.messageId,
|
|
161006
|
-
threadId: msg.threadId,
|
|
161007
|
-
agentId: route.agentId,
|
|
161008
|
-
conversationId: route.conversationId
|
|
161009
|
-
};
|
|
161010
|
-
}
|
|
161011
|
-
function buildDirectReplyOptions(msg) {
|
|
161012
|
-
if (!msg.messageId && !msg.threadId)
|
|
161013
|
-
return;
|
|
161014
|
-
return {
|
|
161015
|
-
replyToMessageId: msg.threadId ?? msg.messageId ?? undefined,
|
|
161016
|
-
threadId: msg.threadId ?? null
|
|
161017
|
-
};
|
|
161018
|
-
}
|
|
161019
|
-
var init_registry_presentation = __esm(() => {
|
|
161020
|
-
init_plugin_registry();
|
|
161021
|
-
});
|
|
161022
|
-
|
|
161023
161083
|
// src/channels/routing.ts
|
|
161024
161084
|
var exports_routing = {};
|
|
161025
161085
|
__export(exports_routing, {
|
|
@@ -161030,8 +161090,10 @@ __export(exports_routing, {
|
|
|
161030
161090
|
removeRouteInMemory: () => removeRouteInMemory,
|
|
161031
161091
|
removeRoute: () => removeRoute,
|
|
161032
161092
|
loadRoutes: () => loadRoutes,
|
|
161093
|
+
loadRouteForInboundMessage: () => loadRouteForInboundMessage,
|
|
161033
161094
|
getRoutesForChannel: () => getRoutesForChannel,
|
|
161034
161095
|
getRouteRaw: () => getRouteRaw,
|
|
161096
|
+
getRouteForInboundMessage: () => getRouteForInboundMessage,
|
|
161035
161097
|
getRoute: () => getRoute,
|
|
161036
161098
|
getAllRoutes: () => getAllRoutes,
|
|
161037
161099
|
clearAllRoutes: () => clearAllRoutes,
|
|
@@ -161134,6 +161196,28 @@ function getRoute(channel, chatId, accountId, threadId) {
|
|
|
161134
161196
|
function getRouteRaw(channel, chatId, accountId, threadId) {
|
|
161135
161197
|
return routesByKey.get(routeKey(channel, chatId, accountId, threadId));
|
|
161136
161198
|
}
|
|
161199
|
+
function selectRoute(route, includeDisabled) {
|
|
161200
|
+
if (!route || !includeDisabled && route.enabled === false)
|
|
161201
|
+
return null;
|
|
161202
|
+
return route;
|
|
161203
|
+
}
|
|
161204
|
+
function getRouteForInboundMessage(msg, accountId, options3 = {}) {
|
|
161205
|
+
const includeDisabled = options3.includeDisabled === true;
|
|
161206
|
+
const exactRoute = getRouteRaw(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
161207
|
+
if (exactRoute)
|
|
161208
|
+
return selectRoute(exactRoute, includeDisabled);
|
|
161209
|
+
if (msg.channel !== "telegram" || msg.chatType !== "direct" || !msg.threadId?.trim()) {
|
|
161210
|
+
return null;
|
|
161211
|
+
}
|
|
161212
|
+
return selectRoute(getRouteRaw(msg.channel, msg.chatId, accountId, null), includeDisabled);
|
|
161213
|
+
}
|
|
161214
|
+
function loadRouteForInboundMessage(msg, accountId, options3) {
|
|
161215
|
+
const route = getRouteForInboundMessage(msg, accountId, options3);
|
|
161216
|
+
if (route)
|
|
161217
|
+
return route;
|
|
161218
|
+
loadRoutes(msg.channel);
|
|
161219
|
+
return getRouteForInboundMessage(msg, accountId, options3);
|
|
161220
|
+
}
|
|
161137
161221
|
function getRoutesForChannel(channelId, accountId) {
|
|
161138
161222
|
const prefix = accountId === undefined ? `${channelId}:` : `${channelId}:${normalizeAccountId3(accountId)}:`;
|
|
161139
161223
|
const routes = [];
|
|
@@ -161215,16 +161299,10 @@ var init_routing = __esm(() => {
|
|
|
161215
161299
|
|
|
161216
161300
|
// src/channels/registry-commands.ts
|
|
161217
161301
|
function createChannelCommandRouter(deps) {
|
|
161218
|
-
function findRawRouteForMessage(msg) {
|
|
161219
|
-
return getRouteRaw(msg.channel, msg.chatId, msg.accountId, msg.threadId) ?? null;
|
|
161220
|
-
}
|
|
161221
161302
|
function loadAndFindRawRouteForMessage(msg) {
|
|
161222
|
-
|
|
161223
|
-
|
|
161224
|
-
|
|
161225
|
-
}
|
|
161226
|
-
loadRoutes(msg.channel);
|
|
161227
|
-
return findRawRouteForMessage(msg);
|
|
161303
|
+
return loadRouteForInboundMessage(msg, msg.accountId, {
|
|
161304
|
+
includeDisabled: true
|
|
161305
|
+
});
|
|
161228
161306
|
}
|
|
161229
161307
|
async function handlePauseResumeSlashCommand(commandName, msg) {
|
|
161230
161308
|
const route = loadAndFindRawRouteForMessage(msg);
|
|
@@ -161474,15 +161552,9 @@ function createChannelCommandRouter(deps) {
|
|
|
161474
161552
|
});
|
|
161475
161553
|
}
|
|
161476
161554
|
function getCancelRoute(msg) {
|
|
161477
|
-
|
|
161478
|
-
if (route)
|
|
161479
|
-
return route;
|
|
161480
|
-
}
|
|
161481
|
-
loadRoutes(msg.channel);
|
|
161482
|
-
route = deps.getRoute(msg.channel, msg.chatId, msg.accountId, msg.threadId);
|
|
161483
|
-
if (route) {
|
|
161555
|
+
const route = loadRouteForInboundMessage(msg, msg.accountId);
|
|
161556
|
+
if (route)
|
|
161484
161557
|
return route;
|
|
161485
|
-
}
|
|
161486
161558
|
if (msg.channel !== "slack" || msg.chatType !== "channel" || msg.threadId != null) {
|
|
161487
161559
|
return null;
|
|
161488
161560
|
}
|
|
@@ -162343,7 +162415,7 @@ function createChannelInboundRouter(deps) {
|
|
|
162343
162415
|
return;
|
|
162344
162416
|
}
|
|
162345
162417
|
if (resolveChannelAccessScope(msg.chatType) === "dm") {
|
|
162346
|
-
await adapter.sendDirectReply(msg.chatId, buildChannelAccessDeniedMessage(msg.channel));
|
|
162418
|
+
await adapter.sendDirectReply(msg.chatId, buildChannelAccessDeniedMessage(msg.channel), buildDirectReplyOptions(msg));
|
|
162347
162419
|
} else {
|
|
162348
162420
|
console.log(`[channels] Dropped ${msg.channel} group message from unauthorized sender ${msg.senderId} in chat ${msg.chatId}`);
|
|
162349
162421
|
}
|
|
@@ -162355,14 +162427,7 @@ function createChannelInboundRouter(deps) {
|
|
|
162355
162427
|
if (deps.commands.shouldDropUnroutedSlackThreadInput(msg, accountId, config3)) {
|
|
162356
162428
|
return;
|
|
162357
162429
|
}
|
|
162358
|
-
const getStatusRoute = () =>
|
|
162359
|
-
let statusRoute = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162360
|
-
if (!statusRoute) {
|
|
162361
|
-
loadRoutes(msg.channel);
|
|
162362
|
-
statusRoute = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162363
|
-
}
|
|
162364
|
-
return statusRoute;
|
|
162365
|
-
};
|
|
162430
|
+
const getStatusRoute = () => loadRouteForInboundMessage(msg, accountId);
|
|
162366
162431
|
if (await tryHandleChannelSlashCommand(adapter, msg, {
|
|
162367
162432
|
statusContext: {
|
|
162368
162433
|
adapterRunning: adapter.isRunning(),
|
|
@@ -162512,16 +162577,12 @@ function createChannelInboundRouter(deps) {
|
|
|
162512
162577
|
});
|
|
162513
162578
|
await adapter.sendDirectReply(msg.chatId, buildPairingInstructions(msg.channel, code2, {
|
|
162514
162579
|
agentId: getConfiguredAgentId(config3)
|
|
162515
|
-
}));
|
|
162580
|
+
}), buildDirectReplyOptions(msg));
|
|
162516
162581
|
return;
|
|
162517
162582
|
}
|
|
162518
|
-
|
|
162519
|
-
if (!route) {
|
|
162520
|
-
loadRoutes(msg.channel);
|
|
162521
|
-
route = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162522
|
-
}
|
|
162583
|
+
const route = loadRouteForInboundMessage(msg, accountId);
|
|
162523
162584
|
if (!route) {
|
|
162524
|
-
await adapter.sendDirectReply(msg.chatId, buildUnboundRouteInstructions(msg.channel, msg.chatId));
|
|
162585
|
+
await adapter.sendDirectReply(msg.chatId, buildUnboundRouteInstructions(msg.channel, msg.chatId), buildDirectReplyOptions(msg));
|
|
162525
162586
|
return;
|
|
162526
162587
|
}
|
|
162527
162588
|
const preparedMessage = adapter.prepareInboundMessage ? await adapter.prepareInboundMessage(msg, { isFirstRouteTurn: false }) : msg;
|
|
@@ -353079,10 +353140,7 @@ function inferAccountIdFromChannelTurnSources(params) {
|
|
|
353079
353140
|
}
|
|
353080
353141
|
const accountIds = new Set;
|
|
353081
353142
|
for (const source2 of params.channelTurnSources ?? []) {
|
|
353082
|
-
if (source2.channel !== params.input.channel || source2.chatId !== chatId || source2.agentId !== params.scope.agentId || source2.conversationId !== params.scope.conversationId) {
|
|
353083
|
-
continue;
|
|
353084
|
-
}
|
|
353085
|
-
if (params.input.threadId !== undefined && (source2.threadId ?? null) !== (params.input.threadId ?? null)) {
|
|
353143
|
+
if (source2.channel !== params.input.channel || source2.chatId !== chatId || source2.agentId !== params.scope.agentId || source2.conversationId !== params.scope.conversationId || params.input.threadId !== null && source2.threadId !== params.input.threadId) {
|
|
353086
353144
|
continue;
|
|
353087
353145
|
}
|
|
353088
353146
|
if (source2.accountId?.trim()) {
|
|
@@ -353185,7 +353243,7 @@ async function message_channel(args) {
|
|
|
353185
353243
|
accountId: resolvedAccountId,
|
|
353186
353244
|
channelTurnSources: args.channelTurnSources
|
|
353187
353245
|
});
|
|
353188
|
-
const requestThreadId = input.action === "download-file" ? input.threadId : inferredThreadId ?? route2.threadId ?? input.threadId;
|
|
353246
|
+
const requestThreadId = input.action === "download-file" ? input.threadId : inferredThreadId ?? (input.channel === "telegram" && route2.chatType === "direct" ? input.threadId : route2.threadId ?? input.threadId);
|
|
353189
353247
|
executionContext = {
|
|
353190
353248
|
request: buildMessageChannelRequest(input, input.chatId, requestThreadId),
|
|
353191
353249
|
route: route2,
|
|
@@ -381962,6 +382020,17 @@ var init_local_backend = __esm(() => {
|
|
|
381962
382020
|
|
|
381963
382021
|
// src/backend/backend.ts
|
|
381964
382022
|
import { homedir as homedir26 } from "node:os";
|
|
382023
|
+
function toApiConversationMessageListBody(body) {
|
|
382024
|
+
const order = body?.order ?? DEFAULT_CONVERSATION_MESSAGE_ORDER;
|
|
382025
|
+
if (!body || order !== "desc" || !body.before && !body.after) {
|
|
382026
|
+
return body;
|
|
382027
|
+
}
|
|
382028
|
+
return {
|
|
382029
|
+
...body,
|
|
382030
|
+
before: body.after,
|
|
382031
|
+
after: body.before
|
|
382032
|
+
};
|
|
382033
|
+
}
|
|
381965
382034
|
|
|
381966
382035
|
class APIBackend {
|
|
381967
382036
|
capabilities = {
|
|
@@ -382033,7 +382102,7 @@ class APIBackend {
|
|
|
382033
382102
|
}
|
|
382034
382103
|
async listConversationMessages(conversationId, body, options3) {
|
|
382035
382104
|
const client = await this.getClient();
|
|
382036
|
-
return client.conversations.messages.list(conversationId, body, options3);
|
|
382105
|
+
return client.conversations.messages.list(conversationId, toApiConversationMessageListBody(body), options3);
|
|
382037
382106
|
}
|
|
382038
382107
|
async compactConversationMessages(conversationId, body, options3) {
|
|
382039
382108
|
const client = await this.getClient();
|
|
@@ -382171,7 +382240,7 @@ async function configureDevBackend(name) {
|
|
|
382171
382240
|
function __testSetBackend(nextBackend) {
|
|
382172
382241
|
backend = nextBackend ?? createInitialBackend();
|
|
382173
382242
|
}
|
|
382174
|
-
var backend = null;
|
|
382243
|
+
var DEFAULT_CONVERSATION_MESSAGE_ORDER = "desc", backend = null;
|
|
382175
382244
|
var init_backend = __esm(() => {
|
|
382176
382245
|
init_backend_mode();
|
|
382177
382246
|
init_local_backend();
|
|
@@ -382190,6 +382259,7 @@ __export(exports_backend, {
|
|
|
382190
382259
|
configureDevBackend: () => configureDevBackend,
|
|
382191
382260
|
configureBackendMode: () => configureBackendMode,
|
|
382192
382261
|
__testSetBackend: () => __testSetBackend,
|
|
382262
|
+
DEFAULT_CONVERSATION_MESSAGE_ORDER: () => DEFAULT_CONVERSATION_MESSAGE_ORDER,
|
|
382193
382263
|
APIBackend: () => APIBackend
|
|
382194
382264
|
});
|
|
382195
382265
|
var init_backend2 = __esm(() => {
|
|
@@ -423955,6 +424025,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423955
424025
|
"token",
|
|
423956
424026
|
"agent_id",
|
|
423957
424027
|
"allowed_channels",
|
|
424028
|
+
"allow_bots",
|
|
423958
424029
|
"default_permission_mode",
|
|
423959
424030
|
"transcribe_voice",
|
|
423960
424031
|
"auto_thread_on_mention",
|
|
@@ -423970,7 +424041,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423970
424041
|
return false;
|
|
423971
424042
|
}
|
|
423972
424043
|
}
|
|
423973
|
-
return (config3.token === undefined || isString2(config3.token)) && (config3.agent_id === undefined || isNullableString2(config3.agent_id)) && (config3.allowed_channels === undefined || isAllowedChannels(config3.allowed_channels)) && (config3.default_permission_mode === undefined || isDefaultPermissionMode(config3.default_permission_mode)) && (config3.transcribe_voice === undefined || isBoolean(config3.transcribe_voice)) && (config3.auto_thread_on_mention === undefined || isBoolean(config3.auto_thread_on_mention)) && (config3.thread_policy_by_channel === undefined || typeof config3.thread_policy_by_channel === "object" && !Array.isArray(config3.thread_policy_by_channel) && config3.thread_policy_by_channel !== null && Object.values(config3.thread_policy_by_channel).every((v2) => v2 === true || v2 === false)) && (config3.acknowledge_message_reaction === undefined || isBoolean(config3.acknowledge_message_reaction)) && (config3.remove_stale_routes === undefined || isBoolean(config3.remove_stale_routes)) && (config3.inbound_debounce_ms === undefined || typeof config3.inbound_debounce_ms === "number" && Number.isFinite(config3.inbound_debounce_ms) && config3.inbound_debounce_ms >= 0 && config3.inbound_debounce_ms <= 1e4);
|
|
424044
|
+
return (config3.token === undefined || isString2(config3.token)) && (config3.agent_id === undefined || isNullableString2(config3.agent_id)) && (config3.allowed_channels === undefined || isAllowedChannels(config3.allowed_channels)) && (config3.allow_bots === undefined || isValidDiscordAllowBotsConfigValue(config3.allow_bots)) && (config3.default_permission_mode === undefined || isDefaultPermissionMode(config3.default_permission_mode)) && (config3.transcribe_voice === undefined || isBoolean(config3.transcribe_voice)) && (config3.auto_thread_on_mention === undefined || isBoolean(config3.auto_thread_on_mention)) && (config3.thread_policy_by_channel === undefined || typeof config3.thread_policy_by_channel === "object" && !Array.isArray(config3.thread_policy_by_channel) && config3.thread_policy_by_channel !== null && Object.values(config3.thread_policy_by_channel).every((v2) => v2 === true || v2 === false)) && (config3.acknowledge_message_reaction === undefined || isBoolean(config3.acknowledge_message_reaction)) && (config3.remove_stale_routes === undefined || isBoolean(config3.remove_stale_routes)) && (config3.inbound_debounce_ms === undefined || typeof config3.inbound_debounce_ms === "number" && Number.isFinite(config3.inbound_debounce_ms) && config3.inbound_debounce_ms >= 0 && config3.inbound_debounce_ms <= 1e4);
|
|
423974
424045
|
},
|
|
423975
424046
|
toAccountPatch(config3) {
|
|
423976
424047
|
const allowedChannels = isAllowedChannels(config3.allowed_channels) ? Array.isArray(config3.allowed_channels) ? [...config3.allowed_channels] : { ...config3.allowed_channels } : undefined;
|
|
@@ -423979,6 +424050,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423979
424050
|
agentId: isNullableString2(config3.agent_id) ? config3.agent_id : undefined,
|
|
423980
424051
|
defaultPermissionMode: isDefaultPermissionMode(config3.default_permission_mode) ? migratePermissionMode(config3.default_permission_mode) : undefined,
|
|
423981
424052
|
allowedChannels,
|
|
424053
|
+
allowBots: config3.allow_bots !== undefined && isValidDiscordAllowBotsConfigValue(config3.allow_bots) ? normalizeDiscordAllowBotsMode(config3.allow_bots) : undefined,
|
|
423982
424054
|
transcribeVoice: isBoolean(config3.transcribe_voice) ? config3.transcribe_voice : undefined,
|
|
423983
424055
|
autoThreadOnMention: isBoolean(config3.auto_thread_on_mention) ? config3.auto_thread_on_mention : undefined,
|
|
423984
424056
|
threadPolicyByChannel: typeof config3.thread_policy_by_channel === "object" && !Array.isArray(config3.thread_policy_by_channel) ? { ...config3.thread_policy_by_channel } : undefined,
|
|
@@ -423993,6 +424065,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423993
424065
|
agent_id: account.agentId,
|
|
423994
424066
|
default_permission_mode: account.defaultPermissionMode ?? "standard",
|
|
423995
424067
|
allowed_channels: serializeAllowedChannels(account.allowedChannels),
|
|
424068
|
+
allow_bots: account.allowBots ?? false,
|
|
423996
424069
|
transcribe_voice: account.transcribeVoice === true,
|
|
423997
424070
|
auto_thread_on_mention: account.autoThreadOnMention ?? false,
|
|
423998
424071
|
thread_policy_by_channel: account.threadPolicyByChannel ?? {},
|
|
@@ -424007,6 +424080,7 @@ var init_account_config2 = __esm(() => {
|
|
|
424007
424080
|
agent_id: account.agentId,
|
|
424008
424081
|
default_permission_mode: account.defaultPermissionMode ?? "standard",
|
|
424009
424082
|
allowed_channels: serializeAllowedChannels(account.allowedChannels),
|
|
424083
|
+
allow_bots: account.allowBots ?? false,
|
|
424010
424084
|
transcribe_voice: account.transcribeVoice === true,
|
|
424011
424085
|
auto_thread_on_mention: account.autoThreadOnMention ?? false,
|
|
424012
424086
|
thread_policy_by_channel: account.threadPolicyByChannel ?? {},
|
|
@@ -424572,6 +424646,7 @@ function createAccountFromPatch(channelId, accountId, patch2) {
|
|
|
424572
424646
|
allowedChannels: normalizedPatch.allowedChannels ?? [],
|
|
424573
424647
|
autoThreadOnMention: normalizedPatch.autoThreadOnMention ?? false,
|
|
424574
424648
|
threadPolicyByChannel: normalizedPatch.threadPolicyByChannel,
|
|
424649
|
+
allowBots: normalizedPatch.allowBots ?? false,
|
|
424575
424650
|
acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction,
|
|
424576
424651
|
removeStaleRoutes: normalizedPatch.removeStaleRoutes,
|
|
424577
424652
|
inboundDebounceMs: normalizedPatch.inboundDebounceMs,
|
|
@@ -424687,6 +424762,7 @@ function mergeAccountPatch(existing, patch2) {
|
|
|
424687
424762
|
allowedChannels: normalizedPatch.allowedChannels ?? existing.allowedChannels,
|
|
424688
424763
|
autoThreadOnMention: normalizedPatch.autoThreadOnMention ?? existing.autoThreadOnMention,
|
|
424689
424764
|
threadPolicyByChannel: normalizedPatch.threadPolicyByChannel ?? existing.threadPolicyByChannel,
|
|
424765
|
+
allowBots: normalizedPatch.allowBots ?? existing.allowBots ?? false,
|
|
424690
424766
|
acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction ?? existing.acknowledgeMessageReaction,
|
|
424691
424767
|
removeStaleRoutes: normalizedPatch.removeStaleRoutes ?? existing.removeStaleRoutes,
|
|
424692
424768
|
inboundDebounceMs: normalizedPatch.inboundDebounceMs ?? existing.inboundDebounceMs,
|
|
@@ -424852,6 +424928,7 @@ function toAccountSnapshot(account) {
|
|
|
424852
424928
|
autoThreadOnMention: account.autoThreadOnMention ?? false,
|
|
424853
424929
|
threadPolicyByChannel: account.threadPolicyByChannel ?? {},
|
|
424854
424930
|
acknowledgeMessageReaction: account.acknowledgeMessageReaction ?? false,
|
|
424931
|
+
allowBots: account.allowBots ?? false,
|
|
424855
424932
|
removeStaleRoutes: account.removeStaleRoutes ?? false,
|
|
424856
424933
|
inboundDebounceMs: account.inboundDebounceMs,
|
|
424857
424934
|
createdAt: account.createdAt,
|
|
@@ -425017,6 +425094,7 @@ function getChannelConfigSnapshot(channelId, accountId) {
|
|
|
425017
425094
|
autoThreadOnMention: account.autoThreadOnMention ?? false,
|
|
425018
425095
|
threadPolicyByChannel: account.threadPolicyByChannel ?? {},
|
|
425019
425096
|
acknowledgeMessageReaction: account.acknowledgeMessageReaction ?? false,
|
|
425097
|
+
allowBots: account.allowBots ?? false,
|
|
425020
425098
|
removeStaleRoutes: account.removeStaleRoutes ?? false,
|
|
425021
425099
|
inboundDebounceMs: account.inboundDebounceMs
|
|
425022
425100
|
};
|
|
@@ -446614,6 +446692,40 @@ function getPageItems(page) {
|
|
|
446614
446692
|
}
|
|
446615
446693
|
return [];
|
|
446616
446694
|
}
|
|
446695
|
+
function messageId(message) {
|
|
446696
|
+
if (!message || typeof message !== "object")
|
|
446697
|
+
return null;
|
|
446698
|
+
const id2 = message.id;
|
|
446699
|
+
return typeof id2 === "string" && id2.length > 0 ? id2 : null;
|
|
446700
|
+
}
|
|
446701
|
+
async function listConversationMessagePage(backend3, conversationId, query2 = {}) {
|
|
446702
|
+
const normalizedQuery = query2 ?? {};
|
|
446703
|
+
const limit3 = normalizedQuery.limit ?? 50;
|
|
446704
|
+
const order = normalizedQuery.order ?? DEFAULT_CONVERSATION_MESSAGE_ORDER;
|
|
446705
|
+
const page = await backend3.listConversationMessages(conversationId, normalizedQuery);
|
|
446706
|
+
const untrimmedMessages = getPageItems(page);
|
|
446707
|
+
const messages = untrimmedMessages.slice(0, limit3);
|
|
446708
|
+
const oldestMessage = order === "asc" ? messages[0] : messages[messages.length - 1];
|
|
446709
|
+
const nextBefore = messageId(oldestMessage);
|
|
446710
|
+
if (!nextBefore || messages.length < limit3) {
|
|
446711
|
+
return { messages, nextBefore, hasMore: false };
|
|
446712
|
+
}
|
|
446713
|
+
if (untrimmedMessages.length > limit3) {
|
|
446714
|
+
return { messages, nextBefore, hasMore: true };
|
|
446715
|
+
}
|
|
446716
|
+
const probe2 = await backend3.listConversationMessages(conversationId, {
|
|
446717
|
+
...normalizedQuery,
|
|
446718
|
+
after: undefined,
|
|
446719
|
+
before: nextBefore,
|
|
446720
|
+
order: "desc",
|
|
446721
|
+
limit: 1
|
|
446722
|
+
});
|
|
446723
|
+
return {
|
|
446724
|
+
messages,
|
|
446725
|
+
nextBefore,
|
|
446726
|
+
hasMore: getPageItems(probe2).length > 0
|
|
446727
|
+
};
|
|
446728
|
+
}
|
|
446617
446729
|
async function handleAgentConversationManagementCommand(parsed, socket, safeSocketSend) {
|
|
446618
446730
|
const backend3 = getBackend();
|
|
446619
446731
|
if (parsed.type === "agent_list") {
|
|
@@ -446846,12 +446958,14 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
446846
446958
|
}
|
|
446847
446959
|
if (parsed.type === "conversation_messages_list") {
|
|
446848
446960
|
try {
|
|
446849
|
-
const page = await backend3
|
|
446961
|
+
const page = await listConversationMessagePage(backend3, parsed.conversation_id, parsed.query);
|
|
446850
446962
|
safeSocketSend(socket, {
|
|
446851
446963
|
type: "conversation_messages_list_response",
|
|
446852
446964
|
request_id: parsed.request_id,
|
|
446853
446965
|
success: true,
|
|
446854
|
-
messages:
|
|
446966
|
+
messages: page.messages,
|
|
446967
|
+
next_before: page.nextBefore,
|
|
446968
|
+
has_more: page.hasMore
|
|
446855
446969
|
}, "listener_conversation_management_send_failed", "listener_conversation_management");
|
|
446856
446970
|
} catch (error54) {
|
|
446857
446971
|
safeSocketSend(socket, {
|
|
@@ -446859,6 +446973,8 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
446859
446973
|
request_id: parsed.request_id,
|
|
446860
446974
|
success: false,
|
|
446861
446975
|
messages: [],
|
|
446976
|
+
next_before: null,
|
|
446977
|
+
has_more: false,
|
|
446862
446978
|
error: getErrorMessage4(error54, "Failed to list conversation messages")
|
|
446863
446979
|
}, "listener_conversation_management_send_failed", "listener_conversation_management");
|
|
446864
446980
|
}
|
|
@@ -448795,7 +448911,7 @@ function normalizeCatalogSource(source2) {
|
|
|
448795
448911
|
return source2.trim().replace(/\/+$/, "");
|
|
448796
448912
|
}
|
|
448797
448913
|
}
|
|
448798
|
-
function
|
|
448914
|
+
function isNonEmptyString9(value) {
|
|
448799
448915
|
return typeof value === "string" && value.length > 0;
|
|
448800
448916
|
}
|
|
448801
448917
|
function isPositiveFiniteNumber(value) {
|
|
@@ -448816,13 +448932,13 @@ function isRecord9(value) {
|
|
|
448816
448932
|
function hasEntryIdentity(entry) {
|
|
448817
448933
|
if (!isRecord9(entry))
|
|
448818
448934
|
return false;
|
|
448819
|
-
return
|
|
448935
|
+
return isNonEmptyString9(entry.id) && isNonEmptyString9(entry.handle) && isNonEmptyString9(entry.label);
|
|
448820
448936
|
}
|
|
448821
448937
|
function isValidEntry(entry) {
|
|
448822
448938
|
if (!hasEntryIdentity(entry))
|
|
448823
448939
|
return false;
|
|
448824
448940
|
const candidate = entry;
|
|
448825
|
-
return
|
|
448941
|
+
return isNonEmptyString9(candidate.brand) && isPositiveFiniteNumber(candidate.maxContextWindow) && isOptionalString(candidate.description) && isOptionalString(candidate.shortLabel) && isOptionalBoolean(candidate.isFeatured) && isOptionalBoolean(candidate.isDefault) && isOptionalBoolean(candidate.free) && isOptionalPositiveFiniteNumber(candidate.contextWindow) && isOptionalPositiveFiniteNumber(candidate.maxOutputTokens) && (candidate.config === undefined || isRecord9(candidate.config));
|
|
448826
448942
|
}
|
|
448827
448943
|
function isValidCachedModel(entry) {
|
|
448828
448944
|
if (!hasEntryIdentity(entry))
|
|
@@ -451479,11 +451595,11 @@ function hasExistingOtidAlias(aliasMap, canonical, nextOtid) {
|
|
|
451479
451595
|
return false;
|
|
451480
451596
|
}
|
|
451481
451597
|
function resolveAssistantLineId(b3, chunk) {
|
|
451482
|
-
const
|
|
451598
|
+
const messageId2 = typeof chunk.id === "string" ? chunk.id : undefined;
|
|
451483
451599
|
const otid = typeof chunk.otid === "string" ? chunk.otid : undefined;
|
|
451484
|
-
const canonicalFromMessageId =
|
|
451600
|
+
const canonicalFromMessageId = messageId2 ? b3.assistantCanonicalByMessageId.get(messageId2) : undefined;
|
|
451485
451601
|
const canonicalFromOtid = otid ? b3.assistantCanonicalByOtid.get(otid) : undefined;
|
|
451486
|
-
let canonical = canonicalFromMessageId || canonicalFromOtid ||
|
|
451602
|
+
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId2 || otid;
|
|
451487
451603
|
if (!canonical)
|
|
451488
451604
|
return;
|
|
451489
451605
|
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
@@ -451506,27 +451622,27 @@ function resolveAssistantLineId(b3, chunk) {
|
|
|
451506
451622
|
}
|
|
451507
451623
|
debugLog("accumulator", `Assistant id/otid alias conflict resolved to ${canonical}`);
|
|
451508
451624
|
}
|
|
451509
|
-
if (
|
|
451510
|
-
b3.assistantCanonicalByMessageId.set(
|
|
451625
|
+
if (messageId2) {
|
|
451626
|
+
b3.assistantCanonicalByMessageId.set(messageId2, canonical);
|
|
451511
451627
|
}
|
|
451512
451628
|
if (otid) {
|
|
451513
451629
|
b3.assistantCanonicalByOtid.set(otid, canonical);
|
|
451514
451630
|
}
|
|
451515
451631
|
const lineId = resolveLineIdForKind(b3, canonical, "assistant");
|
|
451516
451632
|
if (lineId !== canonical) {
|
|
451517
|
-
if (
|
|
451518
|
-
b3.assistantCanonicalByMessageId.set(
|
|
451633
|
+
if (messageId2)
|
|
451634
|
+
b3.assistantCanonicalByMessageId.set(messageId2, lineId);
|
|
451519
451635
|
if (otid)
|
|
451520
451636
|
b3.assistantCanonicalByOtid.set(otid, lineId);
|
|
451521
451637
|
}
|
|
451522
451638
|
return lineId;
|
|
451523
451639
|
}
|
|
451524
451640
|
function resolveReasoningLineId(b3, chunk) {
|
|
451525
|
-
const
|
|
451641
|
+
const messageId2 = typeof chunk.id === "string" ? chunk.id : undefined;
|
|
451526
451642
|
const otid = typeof chunk.otid === "string" ? chunk.otid : undefined;
|
|
451527
|
-
const canonicalFromMessageId =
|
|
451643
|
+
const canonicalFromMessageId = messageId2 ? b3.reasoningCanonicalByMessageId.get(messageId2) : undefined;
|
|
451528
451644
|
const canonicalFromOtid = otid ? b3.reasoningCanonicalByOtid.get(otid) : undefined;
|
|
451529
|
-
let canonical = canonicalFromMessageId || canonicalFromOtid ||
|
|
451645
|
+
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId2 || otid;
|
|
451530
451646
|
if (!canonical)
|
|
451531
451647
|
return;
|
|
451532
451648
|
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
@@ -451549,16 +451665,16 @@ function resolveReasoningLineId(b3, chunk) {
|
|
|
451549
451665
|
}
|
|
451550
451666
|
debugLog("accumulator", `Reasoning id/otid alias conflict resolved to ${canonical}`);
|
|
451551
451667
|
}
|
|
451552
|
-
if (
|
|
451553
|
-
b3.reasoningCanonicalByMessageId.set(
|
|
451668
|
+
if (messageId2) {
|
|
451669
|
+
b3.reasoningCanonicalByMessageId.set(messageId2, canonical);
|
|
451554
451670
|
}
|
|
451555
451671
|
if (otid) {
|
|
451556
451672
|
b3.reasoningCanonicalByOtid.set(otid, canonical);
|
|
451557
451673
|
}
|
|
451558
451674
|
const lineId = resolveLineIdForKind(b3, canonical, "reasoning");
|
|
451559
451675
|
if (lineId !== canonical) {
|
|
451560
|
-
if (
|
|
451561
|
-
b3.reasoningCanonicalByMessageId.set(
|
|
451676
|
+
if (messageId2)
|
|
451677
|
+
b3.reasoningCanonicalByMessageId.set(messageId2, lineId);
|
|
451562
451678
|
if (otid)
|
|
451563
451679
|
b3.reasoningCanonicalByOtid.set(otid, lineId);
|
|
451564
451680
|
}
|
|
@@ -451616,13 +451732,13 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451616
451732
|
}
|
|
451617
451733
|
handleOtidTransition(b3, id2);
|
|
451618
451734
|
const delta2 = chunk.reasoning;
|
|
451619
|
-
const
|
|
451735
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451620
451736
|
const line = ensure(b3, id2, () => ({
|
|
451621
451737
|
kind: "reasoning",
|
|
451622
451738
|
id: id2,
|
|
451623
451739
|
text: "",
|
|
451624
451740
|
phase: "streaming",
|
|
451625
|
-
messageId
|
|
451741
|
+
messageId: messageId2
|
|
451626
451742
|
}));
|
|
451627
451743
|
if (delta2) {
|
|
451628
451744
|
const newText = normalizeReasoningSectionBoundaries(line.text + delta2);
|
|
@@ -451631,11 +451747,11 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451631
451747
|
b3.byId.set(id2, {
|
|
451632
451748
|
...line,
|
|
451633
451749
|
text: newText,
|
|
451634
|
-
messageId:
|
|
451750
|
+
messageId: messageId2 ?? line.messageId
|
|
451635
451751
|
});
|
|
451636
451752
|
}
|
|
451637
|
-
} else if (
|
|
451638
|
-
b3.byId.set(id2, { ...line, messageId });
|
|
451753
|
+
} else if (messageId2 && line.messageId !== messageId2) {
|
|
451754
|
+
b3.byId.set(id2, { ...line, messageId: messageId2 });
|
|
451639
451755
|
}
|
|
451640
451756
|
break;
|
|
451641
451757
|
}
|
|
@@ -451646,13 +451762,13 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451646
451762
|
break;
|
|
451647
451763
|
handleOtidTransition(b3, id2);
|
|
451648
451764
|
const delta2 = extractTextPart(chunk.content);
|
|
451649
|
-
const
|
|
451765
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451650
451766
|
const line = ensure(b3, id2, () => ({
|
|
451651
451767
|
kind: "assistant",
|
|
451652
451768
|
id: id2,
|
|
451653
451769
|
text: "",
|
|
451654
451770
|
phase: "streaming",
|
|
451655
|
-
messageId
|
|
451771
|
+
messageId: messageId2
|
|
451656
451772
|
}));
|
|
451657
451773
|
if (delta2) {
|
|
451658
451774
|
const newText = line.text + delta2;
|
|
@@ -451661,20 +451777,20 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451661
451777
|
b3.byId.set(id2, {
|
|
451662
451778
|
...line,
|
|
451663
451779
|
text: newText,
|
|
451664
|
-
messageId:
|
|
451780
|
+
messageId: messageId2 ?? line.messageId
|
|
451665
451781
|
});
|
|
451666
451782
|
}
|
|
451667
|
-
} else if (
|
|
451668
|
-
b3.byId.set(id2, { ...line, messageId });
|
|
451783
|
+
} else if (messageId2 && line.messageId !== messageId2) {
|
|
451784
|
+
b3.byId.set(id2, { ...line, messageId: messageId2 });
|
|
451669
451785
|
}
|
|
451670
451786
|
break;
|
|
451671
451787
|
}
|
|
451672
451788
|
case "user_message": {
|
|
451673
451789
|
const chunkWithIds = chunk;
|
|
451674
|
-
const
|
|
451790
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451675
451791
|
const otid = typeof chunkWithIds.otid === "string" ? chunkWithIds.otid : undefined;
|
|
451676
451792
|
const mappedLineId = otid ? b3.userLineIdByOtid.get(otid) : undefined;
|
|
451677
|
-
const lineId = mappedLineId || otid ||
|
|
451793
|
+
const lineId = mappedLineId || otid || messageId2;
|
|
451678
451794
|
if (!lineId)
|
|
451679
451795
|
break;
|
|
451680
451796
|
handleOtidTransition(b3, lineId);
|
|
@@ -451698,14 +451814,14 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451698
451814
|
kind: "user",
|
|
451699
451815
|
id: lineId,
|
|
451700
451816
|
text: rawText,
|
|
451701
|
-
messageId,
|
|
451817
|
+
messageId: messageId2,
|
|
451702
451818
|
otid
|
|
451703
451819
|
}));
|
|
451704
451820
|
if (line.kind === "user") {
|
|
451705
451821
|
b3.byId.set(lineId, {
|
|
451706
451822
|
...line,
|
|
451707
451823
|
text: line.text || rawText,
|
|
451708
|
-
messageId:
|
|
451824
|
+
messageId: messageId2 ?? line.messageId,
|
|
451709
451825
|
otid: otid ?? line.otid
|
|
451710
451826
|
});
|
|
451711
451827
|
}
|
|
@@ -541317,4 +541433,4 @@ function registerBunOAuthFlows() {
|
|
|
541317
541433
|
registerBunOAuthFlows();
|
|
541318
541434
|
await init_src5().then(() => exports_src2);
|
|
541319
541435
|
|
|
541320
|
-
//# debugId=
|
|
541436
|
+
//# debugId=EDD0BAA906B8C7B064756E2164756E21
|