@letta-ai/letta-code 0.29.4 → 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 +523 -387
- package/package.json +11 -1
- package/scripts/isolated-unit-tests.json +5 -0
- package/scripts/source-file-size-baseline.json +5 -5
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
|
],
|
|
@@ -127383,6 +127393,9 @@ function validatePiProviderRegistration(providerName, config3) {
|
|
|
127383
127393
|
}
|
|
127384
127394
|
|
|
127385
127395
|
// src/backend/dev/pi-provider-mod-registry.ts
|
|
127396
|
+
function getPiProviderRegistryRevision() {
|
|
127397
|
+
return revisionCounter;
|
|
127398
|
+
}
|
|
127386
127399
|
function bumpProviderRevision(providerName) {
|
|
127387
127400
|
revisionCounter += 1;
|
|
127388
127401
|
providerRevisions.set(providerName, revisionCounter);
|
|
@@ -145935,6 +145948,32 @@ var init_mode = __esm(() => {
|
|
|
145935
145948
|
permissionMode = new PermissionModeManager;
|
|
145936
145949
|
});
|
|
145937
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
|
+
|
|
145938
145977
|
// src/channels/slack/bot-policy.ts
|
|
145939
145978
|
function isValidSlackAllowBotsConfigValue(value) {
|
|
145940
145979
|
return value === undefined || value === false || value === "mentions";
|
|
@@ -145949,14 +145988,14 @@ function resolveSlackAllowBotsMode(value) {
|
|
|
145949
145988
|
return "mentions";
|
|
145950
145989
|
return "off";
|
|
145951
145990
|
}
|
|
145952
|
-
function
|
|
145991
|
+
function isNonEmptyString2(value) {
|
|
145953
145992
|
return typeof value === "string" && value.length > 0;
|
|
145954
145993
|
}
|
|
145955
145994
|
function isSlackBotAuthoredInboundMessage(message) {
|
|
145956
|
-
return
|
|
145995
|
+
return isNonEmptyString2(message.bot_id) || message.subtype === "bot_message";
|
|
145957
145996
|
}
|
|
145958
145997
|
function isOwnSlackBotInboundMessage(params) {
|
|
145959
|
-
return
|
|
145998
|
+
return isNonEmptyString2(params.botUserId) && params.message.user === params.botUserId || isNonEmptyString2(params.botId) && params.message.bot_id === params.botId;
|
|
145960
145999
|
}
|
|
145961
146000
|
function shouldAcceptSlackInboundBotMessage(params) {
|
|
145962
146001
|
if (isOwnSlackBotInboundMessage({
|
|
@@ -146122,6 +146161,9 @@ var init_config2 = __esm(() => {
|
|
|
146122
146161
|
};
|
|
146123
146162
|
discordConfigCodec = {
|
|
146124
146163
|
parse(parsed) {
|
|
146164
|
+
if (!isValidDiscordAllowBotsConfigValue(parsed.allow_bots)) {
|
|
146165
|
+
throw new Error("Invalid Discord allow_bots config");
|
|
146166
|
+
}
|
|
146125
146167
|
const rawAllowedChannels = parsed.allowed_channels;
|
|
146126
146168
|
let allowedChannels;
|
|
146127
146169
|
if (Array.isArray(rawAllowedChannels)) {
|
|
@@ -146137,6 +146179,7 @@ var init_config2 = __esm(() => {
|
|
|
146137
146179
|
dmPolicy: parsed.dm_policy ?? "pairing",
|
|
146138
146180
|
allowedUsers: parsed.allowed_users ?? [],
|
|
146139
146181
|
allowedChannels,
|
|
146182
|
+
allowBots: normalizeDiscordAllowBotsMode(parsed.allow_bots),
|
|
146140
146183
|
transcribeVoice: parsed.transcribe_voice === true,
|
|
146141
146184
|
autoThreadOnMention: typeof parsed.auto_thread_on_mention === "boolean" ? parsed.auto_thread_on_mention : undefined,
|
|
146142
146185
|
threadPolicyByChannel: typeof parsed.thread_policy_by_channel === "object" && !Array.isArray(parsed.thread_policy_by_channel) ? parsed.thread_policy_by_channel : undefined,
|
|
@@ -146370,7 +146413,7 @@ var init_plugin = __esm(() => {
|
|
|
146370
146413
|
});
|
|
146371
146414
|
|
|
146372
146415
|
// src/channels/schema-config.ts
|
|
146373
|
-
function
|
|
146416
|
+
function isNonEmptyString3(value) {
|
|
146374
146417
|
return typeof value === "string" && value.length > 0;
|
|
146375
146418
|
}
|
|
146376
146419
|
function parseSelectOptions(value) {
|
|
@@ -146383,7 +146426,7 @@ function parseSelectOptions(value) {
|
|
|
146383
146426
|
if (!isRecord(entry)) {
|
|
146384
146427
|
return null;
|
|
146385
146428
|
}
|
|
146386
|
-
if (!
|
|
146429
|
+
if (!isNonEmptyString3(entry.value) || !isNonEmptyString3(entry.label)) {
|
|
146387
146430
|
return null;
|
|
146388
146431
|
}
|
|
146389
146432
|
if (seen.has(entry.value)) {
|
|
@@ -146402,10 +146445,10 @@ function parseField(value) {
|
|
|
146402
146445
|
if (typeof type3 !== "string" || !FIELD_TYPES.has(type3)) {
|
|
146403
146446
|
return null;
|
|
146404
146447
|
}
|
|
146405
|
-
if (!
|
|
146448
|
+
if (!isNonEmptyString3(value.key) || !FIELD_KEY_PATTERN.test(value.key)) {
|
|
146406
146449
|
return null;
|
|
146407
146450
|
}
|
|
146408
|
-
if (!
|
|
146451
|
+
if (!isNonEmptyString3(value.label)) {
|
|
146409
146452
|
return null;
|
|
146410
146453
|
}
|
|
146411
146454
|
if (value.description !== undefined && typeof value.description !== "string") {
|
|
@@ -148127,11 +148170,7 @@ function resolveTelegramInputFileConstructor(mod) {
|
|
|
148127
148170
|
return InputFile;
|
|
148128
148171
|
}
|
|
148129
148172
|
function resolveTelegramOutboundThreadId(msg) {
|
|
148130
|
-
|
|
148131
|
-
if (!threadId) {
|
|
148132
|
-
return null;
|
|
148133
|
-
}
|
|
148134
|
-
return msg.chatId.trim().startsWith("-") ? threadId : null;
|
|
148173
|
+
return msg.threadId?.trim() || null;
|
|
148135
148174
|
}
|
|
148136
148175
|
function buildTelegramReplyOptions(msg) {
|
|
148137
148176
|
const options3 = {};
|
|
@@ -149405,7 +149444,7 @@ function createTelegramAdapter(config3) {
|
|
|
149405
149444
|
}
|
|
149406
149445
|
const telegramBot = await ensureBot();
|
|
149407
149446
|
const threadId = resolveTelegramOutboundThreadId(source2);
|
|
149408
|
-
const replyToMessageId =
|
|
149447
|
+
const replyToMessageId = source2.messageId;
|
|
149409
149448
|
let reply_parameters;
|
|
149410
149449
|
if (replyToMessageId) {
|
|
149411
149450
|
const numericReplyToMessageId = Number(replyToMessageId);
|
|
@@ -149579,10 +149618,16 @@ function createTelegramAdapter(config3) {
|
|
|
149579
149618
|
},
|
|
149580
149619
|
async sendDirectReply(chatId, text, options3) {
|
|
149581
149620
|
const telegramBot = await ensureBot();
|
|
149621
|
+
const threadId = resolveTelegramOutboundThreadId({
|
|
149622
|
+
threadId: options3?.threadId
|
|
149623
|
+
});
|
|
149582
149624
|
const reply_parameters = options3?.replyToMessageId ? {
|
|
149583
149625
|
message_id: Number(options3.replyToMessageId)
|
|
149584
149626
|
} : undefined;
|
|
149585
|
-
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
|
+
});
|
|
149586
149631
|
},
|
|
149587
149632
|
async handleTurnLifecycleEvent(event2) {
|
|
149588
149633
|
if (!running)
|
|
@@ -149621,7 +149666,7 @@ function createTelegramAdapter(config3) {
|
|
|
149621
149666
|
async handleControlRequestEvent(event2) {
|
|
149622
149667
|
const telegramBot = await ensureBot();
|
|
149623
149668
|
const threadId = resolveTelegramOutboundThreadId(event2.source);
|
|
149624
|
-
const replyToMessageId =
|
|
149669
|
+
const replyToMessageId = event2.source.messageId;
|
|
149625
149670
|
const reply_parameters = replyToMessageId ? { message_id: Number(replyToMessageId) } : undefined;
|
|
149626
149671
|
await telegramBot.api.sendMessage(event2.source.chatId, formatChannelControlRequestPrompt(event2), {
|
|
149627
149672
|
...threadId ? { message_thread_id: Number(threadId) } : {},
|
|
@@ -149898,6 +149943,7 @@ function normalizeLoadedAccount(account) {
|
|
|
149898
149943
|
if (isDiscordChannelAccount(next)) {
|
|
149899
149944
|
const migrated = migratePermissionMode(next.defaultPermissionMode ?? "standard");
|
|
149900
149945
|
next.defaultPermissionMode = migrated ?? "standard";
|
|
149946
|
+
next.allowBots = normalizeDiscordAllowBotsMode(next.allowBots);
|
|
149901
149947
|
if (!("auto_thread_on_mention" in raw) && !("autoThreadOnMention" in raw)) {
|
|
149902
149948
|
next.autoThreadOnMention = true;
|
|
149903
149949
|
}
|
|
@@ -149960,6 +150006,7 @@ function makeDefaultLegacyAccount(channelId) {
|
|
|
149960
150006
|
allowedChannels: config3.allowedChannels ? Array.isArray(config3.allowedChannels) ? [...config3.allowedChannels] : { ...config3.allowedChannels } : undefined,
|
|
149961
150007
|
autoThreadOnMention: config3.autoThreadOnMention ?? true,
|
|
149962
150008
|
threadPolicyByChannel: config3.threadPolicyByChannel,
|
|
150009
|
+
allowBots: config3.allowBots ?? false,
|
|
149963
150010
|
agentId: null,
|
|
149964
150011
|
defaultPermissionMode: config3.defaultPermissionMode ?? "standard",
|
|
149965
150012
|
createdAt: now,
|
|
@@ -150246,15 +150293,18 @@ function shouldSendTelegramRichMessage(params) {
|
|
|
150246
150293
|
return params.request.action === "send" && params.route.chatType === "direct" && richPrivateChatDefaultEnabled(params.route) && !params.request.mediaPath?.trim();
|
|
150247
150294
|
}
|
|
150248
150295
|
function resolveTelegramRouteThreadId(ctx) {
|
|
150249
|
-
const
|
|
150250
|
-
|
|
150251
|
-
|
|
150252
|
-
return null;
|
|
150296
|
+
const requestThreadId = ctx.request.threadId?.trim();
|
|
150297
|
+
if (requestThreadId) {
|
|
150298
|
+
return requestThreadId;
|
|
150253
150299
|
}
|
|
150254
150300
|
if (ctx.route.chatType === "direct") {
|
|
150255
150301
|
return null;
|
|
150256
150302
|
}
|
|
150257
|
-
|
|
150303
|
+
const routeThreadId = ctx.route.threadId?.trim();
|
|
150304
|
+
if (!routeThreadId) {
|
|
150305
|
+
return null;
|
|
150306
|
+
}
|
|
150307
|
+
return ctx.route.chatId.trim().startsWith("-") ? routeThreadId : null;
|
|
150258
150308
|
}
|
|
150259
150309
|
var telegramMessageActions;
|
|
150260
150310
|
var init_message_actions = __esm(() => {
|
|
@@ -150508,11 +150558,11 @@ function resolveSlackAppConstructor(mod) {
|
|
|
150508
150558
|
}
|
|
150509
150559
|
return App;
|
|
150510
150560
|
}
|
|
150511
|
-
function
|
|
150561
|
+
function isNonEmptyString4(value) {
|
|
150512
150562
|
return typeof value === "string" && value.length > 0;
|
|
150513
150563
|
}
|
|
150514
150564
|
function firstNonEmptyString(...values2) {
|
|
150515
|
-
return values2.find(
|
|
150565
|
+
return values2.find(isNonEmptyString4);
|
|
150516
150566
|
}
|
|
150517
150567
|
function asRecord2(value) {
|
|
150518
150568
|
return value && typeof value === "object" ? value : null;
|
|
@@ -150590,7 +150640,7 @@ function resolveSlackUserDisplayName(userInfo) {
|
|
|
150590
150640
|
return firstNonEmptyString(profile?.display_name, profile?.real_name, user?.name);
|
|
150591
150641
|
}
|
|
150592
150642
|
function isSlackFlatChannelThreadOpener(source2) {
|
|
150593
|
-
return source2.chatType === "channel" &&
|
|
150643
|
+
return source2.chatType === "channel" && isNonEmptyString4(source2.messageId) && (!isNonEmptyString4(source2.threadId) || source2.threadId === source2.messageId);
|
|
150594
150644
|
}
|
|
150595
150645
|
var IGNORED_SLACK_MESSAGE_SUBTYPES, WRAPPER_SLACK_MESSAGE_SUBTYPES;
|
|
150596
150646
|
var init_utils5 = __esm(() => {
|
|
@@ -150637,7 +150687,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
|
|
|
150637
150687
|
socketMode: true
|
|
150638
150688
|
});
|
|
150639
150689
|
const auth = await app.client.auth.test({ token: botToken });
|
|
150640
|
-
if (
|
|
150690
|
+
if (isNonEmptyString4(auth.user_id)) {
|
|
150641
150691
|
try {
|
|
150642
150692
|
const userInfo = await app.client.users.info({
|
|
150643
150693
|
token: botToken,
|
|
@@ -150649,7 +150699,7 @@ async function resolveSlackAccountDisplayName(botToken, appToken) {
|
|
|
150649
150699
|
}
|
|
150650
150700
|
} catch {}
|
|
150651
150701
|
}
|
|
150652
|
-
return
|
|
150702
|
+
return isNonEmptyString4(auth.user) ? auth.user : undefined;
|
|
150653
150703
|
}
|
|
150654
150704
|
var init_account_display2 = __esm(() => {
|
|
150655
150705
|
init_runtime2();
|
|
@@ -151350,7 +151400,7 @@ var init_feedback2 = __esm(() => {
|
|
|
151350
151400
|
init_plugin_registry();
|
|
151351
151401
|
});
|
|
151352
151402
|
|
|
151353
|
-
// src/channels/
|
|
151403
|
+
// src/channels/registry-presentation.ts
|
|
151354
151404
|
function channelDisplayName3(channelId) {
|
|
151355
151405
|
try {
|
|
151356
151406
|
return getChannelDisplayName(channelId);
|
|
@@ -151358,6 +151408,168 @@ function channelDisplayName3(channelId) {
|
|
|
151358
151408
|
return channelId;
|
|
151359
151409
|
}
|
|
151360
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
|
+
}
|
|
151361
151573
|
function listChannelSlashCommands() {
|
|
151362
151574
|
return CHANNEL_SLASH_COMMANDS.map((definition) => ({
|
|
151363
151575
|
...definition,
|
|
@@ -151434,7 +151646,7 @@ function isSlackMentionControlCommand(msg, command) {
|
|
|
151434
151646
|
return command.raw.startsWith("!") || isSlackMentionSlashCommand(msg, command);
|
|
151435
151647
|
}
|
|
151436
151648
|
function buildChannelHelpMessage(channelId) {
|
|
151437
|
-
const displayName =
|
|
151649
|
+
const displayName = channelDisplayName4(channelId);
|
|
151438
151650
|
if (channelId === "slack") {
|
|
151439
151651
|
return [
|
|
151440
151652
|
`${displayName} is connected to Letta Code.`,
|
|
@@ -151466,7 +151678,7 @@ function buildChannelHelpMessage(channelId) {
|
|
|
151466
151678
|
`);
|
|
151467
151679
|
}
|
|
151468
151680
|
function buildUnsupportedChannelCommandMessage(channelId, command) {
|
|
151469
|
-
const displayName =
|
|
151681
|
+
const displayName = channelDisplayName4(channelId);
|
|
151470
151682
|
const isBang = command.raw.startsWith("!");
|
|
151471
151683
|
const commandKind = isBang ? "bang" : "slash";
|
|
151472
151684
|
const supportedCommands = isBang ? supportedBangCommandsText() : channelId === "slack" ? supportedSlackMentionSlashCommandsText() : supportedCommandsText();
|
|
@@ -151480,7 +151692,7 @@ function buildUnsupportedChannelCommandMessage(channelId, command) {
|
|
|
151480
151692
|
`);
|
|
151481
151693
|
}
|
|
151482
151694
|
function buildChannelStatusMessage(msg, context3) {
|
|
151483
|
-
const displayName =
|
|
151695
|
+
const displayName = channelDisplayName4(msg.channel);
|
|
151484
151696
|
const route = context3.route;
|
|
151485
151697
|
const routeStatus = route ? "Connected to a Letta agent conversation." : "No route is connected for this chat yet.";
|
|
151486
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.";
|
|
@@ -151508,7 +151720,7 @@ function buildChannelStatusMessage(msg, context3) {
|
|
|
151508
151720
|
`);
|
|
151509
151721
|
}
|
|
151510
151722
|
function buildChannelNoRouteMessage(channelId) {
|
|
151511
|
-
const displayName =
|
|
151723
|
+
const displayName = channelDisplayName4(channelId);
|
|
151512
151724
|
return [
|
|
151513
151725
|
`${displayName} could not find an existing route for this chat.`,
|
|
151514
151726
|
"Send a normal message first and follow the pairing instructions, then try again."
|
|
@@ -151517,23 +151729,23 @@ function buildChannelNoRouteMessage(channelId) {
|
|
|
151517
151729
|
`);
|
|
151518
151730
|
}
|
|
151519
151731
|
function buildChannelPausedMessage(channelId, route) {
|
|
151520
|
-
const displayName =
|
|
151732
|
+
const displayName = channelDisplayName4(channelId);
|
|
151521
151733
|
const conversation = route.conversationId ? ` Conversation: ${route.conversationId}.` : "";
|
|
151522
151734
|
return `${displayName} paused agent routing for this chat.${conversation} Send /resume here to turn replies back on.`;
|
|
151523
151735
|
}
|
|
151524
151736
|
function buildChannelAlreadyPausedMessage(channelId) {
|
|
151525
|
-
return `${
|
|
151737
|
+
return `${channelDisplayName4(channelId)} agent routing is already paused for this chat. Send /resume here to turn replies back on.`;
|
|
151526
151738
|
}
|
|
151527
151739
|
function buildChannelResumedMessage(channelId, route) {
|
|
151528
|
-
const displayName =
|
|
151740
|
+
const displayName = channelDisplayName4(channelId);
|
|
151529
151741
|
const conversation = route.conversationId ? ` Conversation: ${route.conversationId}.` : "";
|
|
151530
151742
|
return `${displayName} resumed agent routing for this chat.${conversation} Normal messages here will go to the connected agent again.`;
|
|
151531
151743
|
}
|
|
151532
151744
|
function buildChannelAlreadyActiveMessage(channelId) {
|
|
151533
|
-
return `${
|
|
151745
|
+
return `${channelDisplayName4(channelId)} agent routing is already active for this chat.`;
|
|
151534
151746
|
}
|
|
151535
151747
|
function buildChannelCancelUnavailableMessage(channelId) {
|
|
151536
|
-
const displayName =
|
|
151748
|
+
const displayName = channelDisplayName4(channelId);
|
|
151537
151749
|
return [
|
|
151538
151750
|
`${displayName} received /cancel, but this chat is not connected to an active Letta Code conversation yet.`,
|
|
151539
151751
|
"Send a normal message first to connect this chat to an agent."
|
|
@@ -151542,15 +151754,15 @@ function buildChannelCancelUnavailableMessage(channelId) {
|
|
|
151542
151754
|
`);
|
|
151543
151755
|
}
|
|
151544
151756
|
function buildChannelCancelNoActiveTurnMessage(channelId) {
|
|
151545
|
-
const displayName =
|
|
151757
|
+
const displayName = channelDisplayName4(channelId);
|
|
151546
151758
|
return `${displayName} received /cancel, but there is no in-progress agent turn to cancel for this chat.`;
|
|
151547
151759
|
}
|
|
151548
151760
|
function buildChannelCancelAcceptedMessage(channelId) {
|
|
151549
|
-
const displayName =
|
|
151761
|
+
const displayName = channelDisplayName4(channelId);
|
|
151550
151762
|
return `${displayName} cancelled the in-progress agent turn for this chat.`;
|
|
151551
151763
|
}
|
|
151552
151764
|
function buildChannelChatLinkMessage(channelId, route, chatUrl) {
|
|
151553
|
-
const displayName =
|
|
151765
|
+
const displayName = channelDisplayName4(channelId);
|
|
151554
151766
|
return [
|
|
151555
151767
|
`${displayName} chat for this route: ${chatUrl}`,
|
|
151556
151768
|
`Agent: ${route.agentId}.`,
|
|
@@ -151559,27 +151771,27 @@ function buildChannelChatLinkMessage(channelId, route, chatUrl) {
|
|
|
151559
151771
|
`);
|
|
151560
151772
|
}
|
|
151561
151773
|
function buildChannelChatUnavailableMessage(channelId, route) {
|
|
151562
|
-
const displayName =
|
|
151774
|
+
const displayName = channelDisplayName4(channelId);
|
|
151563
151775
|
return `${displayName} chat UI is not available for local backend agent ${route.agentId}.`;
|
|
151564
151776
|
}
|
|
151565
151777
|
function buildChannelDetachUnsupportedMessage(channelId) {
|
|
151566
|
-
const displayName =
|
|
151778
|
+
const displayName = channelDisplayName4(channelId);
|
|
151567
151779
|
return `${displayName} can only detach Slack channel threads.`;
|
|
151568
151780
|
}
|
|
151569
151781
|
function buildChannelDetachedMessage(channelId) {
|
|
151570
|
-
const displayName =
|
|
151782
|
+
const displayName = channelDisplayName4(channelId);
|
|
151571
151783
|
return `${displayName} detached this thread. I will ignore follow-up replies here until someone mentions the app again.`;
|
|
151572
151784
|
}
|
|
151573
151785
|
function buildChannelAlreadyDetachedMessage(channelId) {
|
|
151574
|
-
const displayName =
|
|
151786
|
+
const displayName = channelDisplayName4(channelId);
|
|
151575
151787
|
return `${displayName} is already detached from this thread. Mention the app again to reattach.`;
|
|
151576
151788
|
}
|
|
151577
151789
|
function buildChannelNewConversationMessage(channelId, route) {
|
|
151578
|
-
const displayName =
|
|
151790
|
+
const displayName = channelDisplayName4(channelId);
|
|
151579
151791
|
return `${displayName} started a new conversation for this chat. Conversation: ${route.conversationId}.`;
|
|
151580
151792
|
}
|
|
151581
151793
|
function buildChannelNewConversationUnavailableMessage(channelId) {
|
|
151582
|
-
const displayName =
|
|
151794
|
+
const displayName = channelDisplayName4(channelId);
|
|
151583
151795
|
return `${displayName} cannot start a new conversation for this chat because no agent is configured.`;
|
|
151584
151796
|
}
|
|
151585
151797
|
function getModelEntryRank(entry) {
|
|
@@ -151638,7 +151850,7 @@ function buildChannelModelNotFoundText(channelId) {
|
|
|
151638
151850
|
return `Model not found. Use ${modelCommandPrefix(channelId)} list to see available models.`;
|
|
151639
151851
|
}
|
|
151640
151852
|
function buildChannelCurrentModelMessage(channelId, params) {
|
|
151641
|
-
const displayName =
|
|
151853
|
+
const displayName = channelDisplayName4(channelId);
|
|
151642
151854
|
const scope = params.scope === "agent" ? "agent" : "conversation";
|
|
151643
151855
|
const handleText = params.modelHandle && params.modelHandle !== params.modelLabel ? ` (${params.modelHandle})` : "";
|
|
151644
151856
|
const switchCommand = modelCommandPrefix(channelId);
|
|
@@ -151666,7 +151878,7 @@ function appendModelEntrySection(lines, channelId, title, entries, limit3) {
|
|
|
151666
151878
|
}
|
|
151667
151879
|
}
|
|
151668
151880
|
function buildChannelModelListMessage(channelId, params) {
|
|
151669
|
-
const displayName =
|
|
151881
|
+
const displayName = channelDisplayName4(channelId);
|
|
151670
151882
|
const limit3 = params.limit ?? DEFAULT_CHANNEL_MODEL_LIST_LIMIT;
|
|
151671
151883
|
const entries = params.entries;
|
|
151672
151884
|
const byHandle = buildModelEntriesByHandle(entries);
|
|
@@ -151699,33 +151911,33 @@ function buildChannelModelListMessage(channelId, params) {
|
|
|
151699
151911
|
`);
|
|
151700
151912
|
}
|
|
151701
151913
|
function buildChannelModelListUnavailableMessage(channelId, error54) {
|
|
151702
|
-
const displayName =
|
|
151914
|
+
const displayName = channelDisplayName4(channelId);
|
|
151703
151915
|
return `${displayName} could not load the model list: ${error54}`;
|
|
151704
151916
|
}
|
|
151705
151917
|
function buildChannelCurrentModelUnavailableMessage(channelId, error54) {
|
|
151706
|
-
const displayName =
|
|
151918
|
+
const displayName = channelDisplayName4(channelId);
|
|
151707
151919
|
return `${displayName} could not load the current model: ${error54}`;
|
|
151708
151920
|
}
|
|
151709
151921
|
function buildChannelModelUpdatedMessage(channelId, params) {
|
|
151710
|
-
const displayName =
|
|
151922
|
+
const displayName = channelDisplayName4(channelId);
|
|
151711
151923
|
const scope = params.appliedTo === "agent" ? "agent" : "conversation";
|
|
151712
151924
|
const handleText = params.modelHandle === params.modelLabel ? "" : ` (${params.modelHandle})`;
|
|
151713
151925
|
return `${displayName} updated this ${scope}'s model to ${params.modelLabel}${handleText}.`;
|
|
151714
151926
|
}
|
|
151715
151927
|
function buildChannelModelUpdateFailedMessage(channelId, identifier2, error54) {
|
|
151716
|
-
const displayName =
|
|
151928
|
+
const displayName = channelDisplayName4(channelId);
|
|
151717
151929
|
return `${displayName} could not switch this chat's routed model to ${identifier2}: ${error54}`;
|
|
151718
151930
|
}
|
|
151719
151931
|
function buildChannelModelUnavailableMessage(channelId) {
|
|
151720
|
-
const displayName =
|
|
151932
|
+
const displayName = channelDisplayName4(channelId);
|
|
151721
151933
|
return `${displayName} cannot use /model because the listener is not ready yet. Try again in a moment.`;
|
|
151722
151934
|
}
|
|
151723
151935
|
function buildChannelReflectionUnavailableMessage(channelId) {
|
|
151724
|
-
const displayName =
|
|
151936
|
+
const displayName = channelDisplayName4(channelId);
|
|
151725
151937
|
return `${displayName} cannot start reflection for this chat because the listener is not ready yet. Try again in a moment.`;
|
|
151726
151938
|
}
|
|
151727
151939
|
function buildChannelReloadUnavailableMessage(channelId) {
|
|
151728
|
-
const displayName =
|
|
151940
|
+
const displayName = channelDisplayName4(channelId);
|
|
151729
151941
|
return `${displayName} cannot reload listener settings for this chat because the listener is not ready yet. Try again in a moment.`;
|
|
151730
151942
|
}
|
|
151731
151943
|
async function handleScopedCommand(params) {
|
|
@@ -151759,12 +151971,12 @@ async function tryHandleChannelSlashCommand(adapter, msg, options3 = {}) {
|
|
|
151759
151971
|
const isBangCommand = command.raw.startsWith("!");
|
|
151760
151972
|
const isSlackMentionControl = isSlackMentionControlCommand(msg, command);
|
|
151761
151973
|
if (isBangCommand && !isSupportedSlackMentionCommand(command.name)) {
|
|
151762
|
-
await adapter.sendDirectReply(msg.chatId, buildUnsupportedChannelCommandMessage(msg.channel, command), msg
|
|
151974
|
+
await adapter.sendDirectReply(msg.chatId, buildUnsupportedChannelCommandMessage(msg.channel, command), buildDirectReplyOptions(msg));
|
|
151763
151975
|
return true;
|
|
151764
151976
|
}
|
|
151765
151977
|
const canonicalName = canonicalizeChannelCommandName(command.name);
|
|
151766
151978
|
if (options3.commandGate && !canRunChannelCommand(options3.commandGate, canonicalName)) {
|
|
151767
|
-
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));
|
|
151768
151980
|
return true;
|
|
151769
151981
|
}
|
|
151770
151982
|
const reply = normalizeDirectReplyPayload(await (async () => {
|
|
@@ -151869,6 +152081,7 @@ var init_commands = __esm(() => {
|
|
|
151869
152081
|
init_access_control();
|
|
151870
152082
|
init_feedback2();
|
|
151871
152083
|
init_plugin_registry();
|
|
152084
|
+
init_registry_presentation();
|
|
151872
152085
|
CHANNEL_SLASH_COMMANDS = [
|
|
151873
152086
|
{
|
|
151874
152087
|
name: "help",
|
|
@@ -152522,11 +152735,11 @@ var init_progress_formatting = __esm(() => {
|
|
|
152522
152735
|
});
|
|
152523
152736
|
|
|
152524
152737
|
// src/channels/slack/public-utils.ts
|
|
152525
|
-
function
|
|
152738
|
+
function isNonEmptyString5(value) {
|
|
152526
152739
|
return typeof value === "string" && value.length > 0;
|
|
152527
152740
|
}
|
|
152528
152741
|
function firstNonEmptyString3(...values2) {
|
|
152529
|
-
return values2.find(
|
|
152742
|
+
return values2.find(isNonEmptyString5);
|
|
152530
152743
|
}
|
|
152531
152744
|
function normalizeSlackText(text) {
|
|
152532
152745
|
return text.replace(/^(?:\s*<@[A-Z0-9]+>\s*)+/, "").trim();
|
|
@@ -152562,14 +152775,14 @@ function formatSlackToolNameForDisplay(toolName) {
|
|
|
152562
152775
|
return toolName;
|
|
152563
152776
|
}
|
|
152564
152777
|
function resolveSlackConcreteActivity(event2) {
|
|
152565
|
-
if (event2.kind === "command" &&
|
|
152778
|
+
if (event2.kind === "command" && isNonEmptyString5(event2.command)) {
|
|
152566
152779
|
return sanitizeSlackStatusText(formatSlackToolNameForDisplay(event2.command), SLACK_STATUS_TEXT_MAX);
|
|
152567
152780
|
}
|
|
152568
|
-
if (event2.kind !== "tool" || !
|
|
152781
|
+
if (event2.kind !== "tool" || !isNonEmptyString5(event2.toolName) || event2.toolName.toLowerCase() === "messagechannel") {
|
|
152569
152782
|
return null;
|
|
152570
152783
|
}
|
|
152571
152784
|
for (const description of [event2.toolTitle, event2.toolDetails]) {
|
|
152572
|
-
if (!
|
|
152785
|
+
if (!isNonEmptyString5(description)) {
|
|
152573
152786
|
continue;
|
|
152574
152787
|
}
|
|
152575
152788
|
const sanitized = sanitizeSlackStatusText(description, SLACK_STATUS_TEXT_MAX);
|
|
@@ -152671,12 +152884,12 @@ Run \`${toolName}\`?`
|
|
|
152671
152884
|
];
|
|
152672
152885
|
}
|
|
152673
152886
|
function parseSlackApprovalActionPayload(value) {
|
|
152674
|
-
if (!
|
|
152887
|
+
if (!isNonEmptyString4(value)) {
|
|
152675
152888
|
return null;
|
|
152676
152889
|
}
|
|
152677
152890
|
try {
|
|
152678
152891
|
const parsed = JSON.parse(value);
|
|
152679
|
-
if (!
|
|
152892
|
+
if (!isNonEmptyString4(parsed.requestId) || parsed.decision !== "allow" && parsed.decision !== "deny") {
|
|
152680
152893
|
return null;
|
|
152681
152894
|
}
|
|
152682
152895
|
return { requestId: parsed.requestId, decision: parsed.decision };
|
|
@@ -152899,16 +153112,16 @@ async function mapSlackThreadMessage(message, attachmentOptions, sourceThreadId)
|
|
|
152899
153112
|
const attachments = await resolveSlackMessageAttachments(message, attachmentOptions, sourceThreadId);
|
|
152900
153113
|
return {
|
|
152901
153114
|
text: resolveSlackThreadMessageText(message),
|
|
152902
|
-
userId:
|
|
152903
|
-
botId:
|
|
152904
|
-
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,
|
|
152905
153118
|
...attachments.length > 0 ? { attachments } : {}
|
|
152906
153119
|
};
|
|
152907
153120
|
}
|
|
152908
153121
|
function asRecord4(value) {
|
|
152909
153122
|
return value && typeof value === "object" ? value : null;
|
|
152910
153123
|
}
|
|
152911
|
-
function
|
|
153124
|
+
function isNonEmptyString6(value) {
|
|
152912
153125
|
return typeof value === "string" && value.trim().length > 0;
|
|
152913
153126
|
}
|
|
152914
153127
|
function normalizeSlackFileLike(value) {
|
|
@@ -152917,12 +153130,12 @@ function normalizeSlackFileLike(value) {
|
|
|
152917
153130
|
return null;
|
|
152918
153131
|
}
|
|
152919
153132
|
return {
|
|
152920
|
-
id:
|
|
152921
|
-
name:
|
|
152922
|
-
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,
|
|
152923
153136
|
size: typeof record5.size === "number" ? record5.size : undefined,
|
|
152924
|
-
url_private:
|
|
152925
|
-
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
|
|
152926
153139
|
};
|
|
152927
153140
|
}
|
|
152928
153141
|
function normalizeSlackAttachmentLike(value) {
|
|
@@ -152932,12 +153145,12 @@ function normalizeSlackAttachmentLike(value) {
|
|
|
152932
153145
|
}
|
|
152933
153146
|
const files = Array.isArray(record5.files) ? record5.files.map((entry) => normalizeSlackFileLike(entry)).filter((entry) => Boolean(entry)) : undefined;
|
|
152934
153147
|
return {
|
|
152935
|
-
text:
|
|
152936
|
-
fallback:
|
|
152937
|
-
pretext:
|
|
152938
|
-
author_name:
|
|
152939
|
-
title:
|
|
152940
|
-
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,
|
|
152941
153154
|
files
|
|
152942
153155
|
};
|
|
152943
153156
|
}
|
|
@@ -152970,7 +153183,7 @@ function resolveSlackThreadMessageText(message) {
|
|
|
152970
153183
|
if (text) {
|
|
152971
153184
|
return text;
|
|
152972
153185
|
}
|
|
152973
|
-
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) : [];
|
|
152974
153187
|
if (attachmentTexts.length > 0) {
|
|
152975
153188
|
return attachmentTexts.join(`
|
|
152976
153189
|
|
|
@@ -153277,7 +153490,7 @@ async function resolveSlackFilesAsAttachments(params) {
|
|
|
153277
153490
|
return resolved;
|
|
153278
153491
|
}
|
|
153279
153492
|
function resolveSlackThreadAttachmentOptions(params) {
|
|
153280
|
-
if (!
|
|
153493
|
+
if (!isNonEmptyString6(params.accountId) || !isNonEmptyString6(params.token)) {
|
|
153281
153494
|
return;
|
|
153282
153495
|
}
|
|
153283
153496
|
return {
|
|
@@ -153304,7 +153517,7 @@ async function resolveSlackMessageAttachments(message, attachmentOptions, source
|
|
|
153304
153517
|
token: attachmentOptions.token,
|
|
153305
153518
|
files: collectSlackFiles(message),
|
|
153306
153519
|
sourceMessageId: message.ts,
|
|
153307
|
-
sourceThreadId: sourceThreadId ?? (
|
|
153520
|
+
sourceThreadId: sourceThreadId ?? (isNonEmptyString6(message.thread_ts) ? message.thread_ts : null),
|
|
153308
153521
|
transcribeVoice: attachmentOptions.transcribeVoice
|
|
153309
153522
|
});
|
|
153310
153523
|
}
|
|
@@ -153314,8 +153527,8 @@ async function resolveSlackInboundAttachments(params) {
|
|
|
153314
153527
|
accountId: params.accountId,
|
|
153315
153528
|
token: params.token,
|
|
153316
153529
|
files: collectSlackFiles(params.rawEvent),
|
|
153317
|
-
sourceMessageId:
|
|
153318
|
-
sourceThreadId:
|
|
153530
|
+
sourceMessageId: isNonEmptyString6(rawEvent?.ts) ? rawEvent.ts : undefined,
|
|
153531
|
+
sourceThreadId: isNonEmptyString6(rawEvent?.thread_ts) ? rawEvent.thread_ts : null,
|
|
153319
153532
|
transcribeVoice: params.transcribeVoice
|
|
153320
153533
|
});
|
|
153321
153534
|
}
|
|
@@ -153388,7 +153601,7 @@ async function resolveSlackThreadHistory(params) {
|
|
|
153388
153601
|
...cursor ? { cursor } : {}
|
|
153389
153602
|
});
|
|
153390
153603
|
for (const message of response.messages ?? []) {
|
|
153391
|
-
if (params.include === "bot" && !
|
|
153604
|
+
if (params.include === "bot" && !isNonEmptyString6(message.bot_id)) {
|
|
153392
153605
|
continue;
|
|
153393
153606
|
}
|
|
153394
153607
|
if (!hasSlackThreadMessageContent(message, attachmentOptions)) {
|
|
@@ -153452,11 +153665,11 @@ var init_media2 = __esm(() => {
|
|
|
153452
153665
|
});
|
|
153453
153666
|
|
|
153454
153667
|
// src/channels/slack/attachment-download.ts
|
|
153455
|
-
function
|
|
153668
|
+
function isNonEmptyString7(value) {
|
|
153456
153669
|
return typeof value === "string" && value.trim().length > 0;
|
|
153457
153670
|
}
|
|
153458
153671
|
async function resolveCanonicalSlackMessage(params) {
|
|
153459
|
-
if (
|
|
153672
|
+
if (isNonEmptyString7(params.threadTs)) {
|
|
153460
153673
|
let cursor;
|
|
153461
153674
|
do {
|
|
153462
153675
|
const response2 = await params.client.conversations.replies({
|
|
@@ -153471,7 +153684,7 @@ async function resolveCanonicalSlackMessage(params) {
|
|
|
153471
153684
|
return message;
|
|
153472
153685
|
}
|
|
153473
153686
|
const nextCursor = response2.response_metadata?.next_cursor;
|
|
153474
|
-
cursor =
|
|
153687
|
+
cursor = isNonEmptyString7(nextCursor) ? nextCursor.trim() : undefined;
|
|
153475
153688
|
} while (cursor);
|
|
153476
153689
|
return null;
|
|
153477
153690
|
}
|
|
@@ -153623,7 +153836,7 @@ function createSlackInboundDebounceController(params) {
|
|
|
153623
153836
|
const deduped = [];
|
|
153624
153837
|
for (const entry of entries) {
|
|
153625
153838
|
const messageId = entry.inbound.messageId;
|
|
153626
|
-
const messageKey =
|
|
153839
|
+
const messageKey = isNonEmptyString4(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
|
|
153627
153840
|
if (!messageKey) {
|
|
153628
153841
|
deduped.push(entry);
|
|
153629
153842
|
continue;
|
|
@@ -153658,7 +153871,7 @@ function createSlackInboundDebounceController(params) {
|
|
|
153658
153871
|
if (pending?.size === 0)
|
|
153659
153872
|
pendingTopLevelKeys.delete(conversationKey);
|
|
153660
153873
|
}
|
|
153661
|
-
if (
|
|
153874
|
+
if (isNonEmptyString4(last.inbound.messageId)) {
|
|
153662
153875
|
const seenKey = `${last.inbound.chatId}:${last.inbound.messageId}`;
|
|
153663
153876
|
pruneAppMentionMaps(Date.now());
|
|
153664
153877
|
if (last.opts.source === "app_mention") {
|
|
@@ -153737,13 +153950,13 @@ function hasRecordValue(value) {
|
|
|
153737
153950
|
return value !== null && typeof value === "object";
|
|
153738
153951
|
}
|
|
153739
153952
|
function hasSlackMention(text, userId) {
|
|
153740
|
-
return
|
|
153953
|
+
return isNonEmptyString5(text) && isNonEmptyString5(userId) && (text.includes(`<@${userId}>`) || text.includes(`<@${userId}|`));
|
|
153741
153954
|
}
|
|
153742
153955
|
function isBotAuthoredMessage(message) {
|
|
153743
|
-
return
|
|
153956
|
+
return isNonEmptyString5(message.bot_id) || message.subtype === "bot_message";
|
|
153744
153957
|
}
|
|
153745
153958
|
function resolveMessageSubtypeIgnoreReason(message) {
|
|
153746
|
-
const subtype =
|
|
153959
|
+
const subtype = isNonEmptyString5(message.subtype) ? message.subtype : null;
|
|
153747
153960
|
if (!subtype) {
|
|
153748
153961
|
return null;
|
|
153749
153962
|
}
|
|
@@ -153757,14 +153970,14 @@ function resolveMessageSubtypeIgnoreReason(message) {
|
|
|
153757
153970
|
}
|
|
153758
153971
|
function resolveSlackMessageIngressPolicy(params) {
|
|
153759
153972
|
const { message } = params;
|
|
153760
|
-
if (!
|
|
153973
|
+
if (!isNonEmptyString5(message.channel)) {
|
|
153761
153974
|
return { shouldRoute: false, reason: "missing_channel" };
|
|
153762
153975
|
}
|
|
153763
153976
|
const senderId = firstNonEmptyString3(message.user, message.bot_id);
|
|
153764
153977
|
if (!senderId) {
|
|
153765
153978
|
return { shouldRoute: false, reason: "missing_sender" };
|
|
153766
153979
|
}
|
|
153767
|
-
if (!
|
|
153980
|
+
if (!isNonEmptyString5(message.ts)) {
|
|
153768
153981
|
return { shouldRoute: false, reason: "missing_timestamp" };
|
|
153769
153982
|
}
|
|
153770
153983
|
if (message.hidden === true) {
|
|
@@ -153776,10 +153989,10 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153776
153989
|
}
|
|
153777
153990
|
const chatType = resolveSlackChatType2(message.channel);
|
|
153778
153991
|
const threadId = chatType === "direct" ? firstNonEmptyString3(message.thread_ts) ?? null : firstNonEmptyString3(message.thread_ts, message.ts) ?? null;
|
|
153779
|
-
if (chatType === "channel" && !
|
|
153992
|
+
if (chatType === "channel" && !isNonEmptyString5(message.thread_ts)) {
|
|
153780
153993
|
return { shouldRoute: false, reason: "top_level_channel_message" };
|
|
153781
153994
|
}
|
|
153782
|
-
const rawText =
|
|
153995
|
+
const rawText = isNonEmptyString5(message.text) ? message.text : "";
|
|
153783
153996
|
const wasMentioned = hasSlackMention(rawText, params.botUserId);
|
|
153784
153997
|
const isAgentThread = params.isAgentThread === true;
|
|
153785
153998
|
const effectiveMention = isBotAuthoredMessage(message) ? wasMentioned : wasMentioned || isAgentThread;
|
|
@@ -153787,8 +154000,8 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153787
154000
|
shouldRoute: true,
|
|
153788
154001
|
channelId: message.channel,
|
|
153789
154002
|
senderId,
|
|
153790
|
-
...
|
|
153791
|
-
...
|
|
154003
|
+
...isNonEmptyString5(message.user) ? { senderUserId: message.user } : {},
|
|
154004
|
+
...isNonEmptyString5(message.bot_id) ? { senderBotId: message.bot_id } : {},
|
|
153792
154005
|
messageId: message.ts,
|
|
153793
154006
|
threadId,
|
|
153794
154007
|
chatType,
|
|
@@ -153801,23 +154014,23 @@ function resolveSlackMessageIngressPolicy(params) {
|
|
|
153801
154014
|
}
|
|
153802
154015
|
function resolveSlackAppMentionIngressPolicy(params) {
|
|
153803
154016
|
const { event: event2 } = params;
|
|
153804
|
-
if (!
|
|
154017
|
+
if (!isNonEmptyString5(event2.channel)) {
|
|
153805
154018
|
return { shouldRoute: false, reason: "missing_channel" };
|
|
153806
154019
|
}
|
|
153807
154020
|
const senderId = firstNonEmptyString3(event2.user, event2.bot_id);
|
|
153808
154021
|
if (!senderId) {
|
|
153809
154022
|
return { shouldRoute: false, reason: "missing_sender" };
|
|
153810
154023
|
}
|
|
153811
|
-
if (!
|
|
154024
|
+
if (!isNonEmptyString5(event2.ts)) {
|
|
153812
154025
|
return { shouldRoute: false, reason: "missing_timestamp" };
|
|
153813
154026
|
}
|
|
153814
|
-
const rawText =
|
|
154027
|
+
const rawText = isNonEmptyString5(event2.text) ? event2.text : "";
|
|
153815
154028
|
return {
|
|
153816
154029
|
shouldRoute: true,
|
|
153817
154030
|
channelId: event2.channel,
|
|
153818
154031
|
senderId,
|
|
153819
|
-
...
|
|
153820
|
-
...
|
|
154032
|
+
...isNonEmptyString5(event2.user) ? { senderUserId: event2.user } : {},
|
|
154033
|
+
...isNonEmptyString5(event2.bot_id) ? { senderBotId: event2.bot_id } : {},
|
|
153821
154034
|
messageId: event2.ts,
|
|
153822
154035
|
threadId: firstNonEmptyString3(event2.thread_ts, event2.ts) ?? event2.ts,
|
|
153823
154036
|
chatType: "channel",
|
|
@@ -153885,7 +154098,7 @@ function createSlackIngressController(params) {
|
|
|
153885
154098
|
}
|
|
153886
154099
|
}
|
|
153887
154100
|
function markIngressMessageSeen(channelId, messageId) {
|
|
153888
|
-
if (!
|
|
154101
|
+
if (!isNonEmptyString4(channelId) || !isNonEmptyString4(messageId)) {
|
|
153889
154102
|
return false;
|
|
153890
154103
|
}
|
|
153891
154104
|
const key = `${channelId}:${messageId}`;
|
|
@@ -153896,12 +154109,12 @@ function createSlackIngressController(params) {
|
|
|
153896
154109
|
return false;
|
|
153897
154110
|
}
|
|
153898
154111
|
function rememberMessageThread(messageId, threadId) {
|
|
153899
|
-
if (
|
|
154112
|
+
if (isNonEmptyString4(messageId)) {
|
|
153900
154113
|
knownThreadIdsByMessageId.set(messageId, threadId);
|
|
153901
154114
|
}
|
|
153902
154115
|
}
|
|
153903
154116
|
async function resolveUserName(app, userId) {
|
|
153904
|
-
if (!
|
|
154117
|
+
if (!isNonEmptyString4(userId))
|
|
153905
154118
|
return;
|
|
153906
154119
|
const cached2 = knownUserDisplayNames.get(userId);
|
|
153907
154120
|
if (cached2)
|
|
@@ -153917,10 +154130,10 @@ function createSlackIngressController(params) {
|
|
|
153917
154130
|
return userId;
|
|
153918
154131
|
}
|
|
153919
154132
|
async function resolveInboundSenderName(app, userId, botId) {
|
|
153920
|
-
if (
|
|
154133
|
+
if (isNonEmptyString4(userId)) {
|
|
153921
154134
|
return resolveUserName(app, userId);
|
|
153922
154135
|
}
|
|
153923
|
-
return
|
|
154136
|
+
return isNonEmptyString4(botId) ? `Bot (${botId})` : undefined;
|
|
153924
154137
|
}
|
|
153925
154138
|
function shouldAcceptInboundMessageByBotPolicy(input) {
|
|
153926
154139
|
return shouldAcceptSlackInboundBotMessage({
|
|
@@ -153948,7 +154161,7 @@ function createSlackIngressController(params) {
|
|
|
153948
154161
|
return;
|
|
153949
154162
|
const rawMessage = asRecord2(message);
|
|
153950
154163
|
const channelId = rawMessage?.channel;
|
|
153951
|
-
if (!rawMessage || !
|
|
154164
|
+
if (!rawMessage || !isNonEmptyString4(channelId)) {
|
|
153952
154165
|
return;
|
|
153953
154166
|
}
|
|
153954
154167
|
const basePolicy = resolveSlackMessageIngressPolicy({
|
|
@@ -153970,7 +154183,7 @@ function createSlackIngressController(params) {
|
|
|
153970
154183
|
transcribeVoice: config3.transcribeVoice === true
|
|
153971
154184
|
});
|
|
153972
154185
|
const senderName = await resolveInboundSenderName(app, basePolicy.senderUserId, basePolicy.senderBotId);
|
|
153973
|
-
const isAgentThread = basePolicy.chatType === "channel" &&
|
|
154186
|
+
const isAgentThread = basePolicy.chatType === "channel" && isNonEmptyString4(basePolicy.threadId) && params.agentThreadTracker.has(channelId, basePolicy.threadId);
|
|
153974
154187
|
const policy = resolveSlackMessageIngressPolicy({
|
|
153975
154188
|
message: rawMessage,
|
|
153976
154189
|
botUserId: params.getBotUserId(),
|
|
@@ -154073,10 +154286,10 @@ function createSlackIngressController(params) {
|
|
|
154073
154286
|
}) => {
|
|
154074
154287
|
await ack();
|
|
154075
154288
|
const adapter = params.getAdapter();
|
|
154076
|
-
if (!adapter.onMessage || !
|
|
154289
|
+
if (!adapter.onMessage || !isNonEmptyString4(command.command) || !isNonEmptyString4(command.channel_id) || !isNonEmptyString4(command.user_id)) {
|
|
154077
154290
|
return;
|
|
154078
154291
|
}
|
|
154079
|
-
const args =
|
|
154292
|
+
const args = isNonEmptyString4(command.text) ? command.text.trim() : "";
|
|
154080
154293
|
try {
|
|
154081
154294
|
await adapter.onMessage({
|
|
154082
154295
|
channel: "slack",
|
|
@@ -154140,7 +154353,7 @@ function createSlackIngressController(params) {
|
|
|
154140
154353
|
const item = asRecord2(event2.item);
|
|
154141
154354
|
const chatId = item?.channel;
|
|
154142
154355
|
const targetMessageId = item?.ts;
|
|
154143
|
-
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()) {
|
|
154144
154357
|
return;
|
|
154145
154358
|
}
|
|
154146
154359
|
const chatType = resolveSlackChatType(chatId);
|
|
@@ -154164,7 +154377,7 @@ function createSlackIngressController(params) {
|
|
|
154164
154377
|
action: action3,
|
|
154165
154378
|
emoji: event2.reaction,
|
|
154166
154379
|
targetMessageId,
|
|
154167
|
-
targetSenderId:
|
|
154380
|
+
targetSenderId: isNonEmptyString4(event2.item_user) ? event2.item_user : undefined
|
|
154168
154381
|
},
|
|
154169
154382
|
raw: event2
|
|
154170
154383
|
});
|
|
@@ -154210,22 +154423,22 @@ function createSlackStatusController(params) {
|
|
|
154210
154423
|
const keepaliveByConversation = new Map;
|
|
154211
154424
|
const clearedStaleReplyKeys = new Set;
|
|
154212
154425
|
function getConversationKey(source2) {
|
|
154213
|
-
return source2.channel === "slack" &&
|
|
154426
|
+
return source2.channel === "slack" && isNonEmptyString5(source2.agentId) && isNonEmptyString5(source2.conversationId) ? `${source2.agentId}:${source2.conversationId}` : null;
|
|
154214
154427
|
}
|
|
154215
154428
|
function getLifecycleReplyKey(source2) {
|
|
154216
|
-
if (source2.channel !== "slack" || !
|
|
154429
|
+
if (source2.channel !== "slack" || !isNonEmptyString5(source2.chatId)) {
|
|
154217
154430
|
return null;
|
|
154218
154431
|
}
|
|
154219
154432
|
const replyToMessageId = resolveSlackProgressThreadTs(source2);
|
|
154220
|
-
return
|
|
154433
|
+
return isNonEmptyString5(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : null;
|
|
154221
154434
|
}
|
|
154222
154435
|
function getLifecycleErrorReplyKey(source2) {
|
|
154223
|
-
if (source2.channel !== "slack" || !
|
|
154436
|
+
if (source2.channel !== "slack" || !isNonEmptyString5(source2.chatId)) {
|
|
154224
154437
|
return null;
|
|
154225
154438
|
}
|
|
154226
154439
|
if (source2.chatType === "direct" || resolveSlackChatType2(source2.chatId) === "direct") {
|
|
154227
154440
|
const replyToMessageId = resolveSlackSourceThreadTs2(source2);
|
|
154228
|
-
return
|
|
154441
|
+
return isNonEmptyString5(replyToMessageId) ? `${source2.chatId}:${replyToMessageId}` : `${source2.chatId}:direct`;
|
|
154229
154442
|
}
|
|
154230
154443
|
return getLifecycleReplyKey(source2);
|
|
154231
154444
|
}
|
|
@@ -154384,7 +154597,7 @@ ${loadingText}`;
|
|
|
154384
154597
|
markAutoClearedByKey(key);
|
|
154385
154598
|
},
|
|
154386
154599
|
markAutoClearedForMessage(msg) {
|
|
154387
|
-
if (
|
|
154600
|
+
if (isNonEmptyString5(msg.agentId) && isNonEmptyString5(msg.conversationId)) {
|
|
154388
154601
|
markAutoClearedByKey(`${msg.agentId}:${msg.conversationId}`);
|
|
154389
154602
|
return;
|
|
154390
154603
|
}
|
|
@@ -154432,7 +154645,7 @@ function truncateThreadLabel(text, maxLength3 = 80) {
|
|
|
154432
154645
|
return normalized.length <= maxLength3 ? normalized : `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
|
|
154433
154646
|
}
|
|
154434
154647
|
function buildThreadLabel(msg, starterText) {
|
|
154435
|
-
const roomLabel = msg.chatType === "channel" &&
|
|
154648
|
+
const roomLabel = msg.chatType === "channel" && isNonEmptyString4(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
154436
154649
|
const preview = truncateThreadLabel(starterText ?? msg.text);
|
|
154437
154650
|
const threadLabel = msg.chatType === "direct" ? "Slack DM thread" : "Slack thread";
|
|
154438
154651
|
if (preview)
|
|
@@ -154442,12 +154655,12 @@ function buildThreadLabel(msg, starterText) {
|
|
|
154442
154655
|
function buildChannelContextLabel(msg) {
|
|
154443
154656
|
if (msg.chatType !== "channel")
|
|
154444
154657
|
return;
|
|
154445
|
-
const roomLabel =
|
|
154658
|
+
const roomLabel = isNonEmptyString4(msg.chatLabel) && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
154446
154659
|
return roomLabel ? `Slack channel context${roomLabel} before thread start` : "Slack channel context before thread start";
|
|
154447
154660
|
}
|
|
154448
154661
|
async function prepareSlackInboundMessage(params) {
|
|
154449
154662
|
const { msg, config: config3 } = params;
|
|
154450
|
-
if (msg.channel !== "slack" || !
|
|
154663
|
+
if (msg.channel !== "slack" || !isNonEmptyString4(msg.threadId) || !isNonEmptyString4(msg.messageId)) {
|
|
154451
154664
|
return msg;
|
|
154452
154665
|
}
|
|
154453
154666
|
const isFirstRouteTurn = params.options?.isFirstRouteTurn === true;
|
|
@@ -154496,18 +154709,18 @@ async function prepareSlackInboundMessage(params) {
|
|
|
154496
154709
|
return msg;
|
|
154497
154710
|
}
|
|
154498
154711
|
const userIds = new Set;
|
|
154499
|
-
if (
|
|
154712
|
+
if (isNonEmptyString4(starter?.userId))
|
|
154500
154713
|
userIds.add(starter.userId);
|
|
154501
154714
|
for (const entry of history) {
|
|
154502
|
-
if (
|
|
154715
|
+
if (isNonEmptyString4(entry.userId))
|
|
154503
154716
|
userIds.add(entry.userId);
|
|
154504
154717
|
}
|
|
154505
154718
|
await Promise.all(Array.from(userIds).map((userId) => params.resolveUserName(app, userId)));
|
|
154506
154719
|
const resolveSenderName = (userId, botId) => {
|
|
154507
|
-
if (
|
|
154720
|
+
if (isNonEmptyString4(userId)) {
|
|
154508
154721
|
return params.getKnownUserDisplayName(userId) ?? userId;
|
|
154509
154722
|
}
|
|
154510
|
-
return
|
|
154723
|
+
return isNonEmptyString4(botId) ? `Bot (${botId})` : undefined;
|
|
154511
154724
|
};
|
|
154512
154725
|
return {
|
|
154513
154726
|
...msg,
|
|
@@ -154666,7 +154879,7 @@ function createSlackAdapter(config3) {
|
|
|
154666
154879
|
if (!running)
|
|
154667
154880
|
return;
|
|
154668
154881
|
if (event2.type === "queued") {
|
|
154669
|
-
if (isSlackFlatChannelThreadOpener(event2.source) &&
|
|
154882
|
+
if (isSlackFlatChannelThreadOpener(event2.source) && isNonEmptyString4(event2.source.messageId) && !agentThreadTracker.has(event2.source.chatId, event2.source.messageId)) {
|
|
154670
154883
|
await status.activate(event2.source, SLACK_ASSISTANT_STARTUP_STATUS, SLACK_ASSISTANT_STARTUP_STATUS);
|
|
154671
154884
|
}
|
|
154672
154885
|
return;
|
|
@@ -154728,7 +154941,7 @@ function createSlackAdapter(config3) {
|
|
|
154728
154941
|
if (msg.mediaPath) {
|
|
154729
154942
|
const result = await uploadSlackFile(client, msg);
|
|
154730
154943
|
const threadId = msg.threadId ?? msg.replyToMessageId ?? null;
|
|
154731
|
-
if (resolveSlackChatType(msg.chatId) === "channel" &&
|
|
154944
|
+
if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString4(threadId)) {
|
|
154732
154945
|
agentThreadTracker.remember(msg.chatId, threadId);
|
|
154733
154946
|
}
|
|
154734
154947
|
status.markAutoClearedForMessage(msg);
|
|
@@ -154739,7 +154952,7 @@ function createSlackAdapter(config3) {
|
|
|
154739
154952
|
threadId: msg.threadId,
|
|
154740
154953
|
replyToMessageId: msg.replyToMessageId
|
|
154741
154954
|
});
|
|
154742
|
-
const footnote =
|
|
154955
|
+
const footnote = isNonEmptyString4(msg.agentId) && isNonEmptyString4(msg.conversationId) ? buildSlackChatFootnote({
|
|
154743
154956
|
agentId: msg.agentId,
|
|
154744
154957
|
conversationId: msg.conversationId
|
|
154745
154958
|
}) : "";
|
|
@@ -154752,7 +154965,7 @@ function createSlackAdapter(config3) {
|
|
|
154752
154965
|
});
|
|
154753
154966
|
const outboundThreadId = threadTs ?? (resolveSlackChatType(msg.chatId) === "channel" ? response.ts ?? null : null);
|
|
154754
154967
|
ingress.rememberMessageThread(response.ts, outboundThreadId);
|
|
154755
|
-
if (resolveSlackChatType(msg.chatId) === "channel" &&
|
|
154968
|
+
if (resolveSlackChatType(msg.chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154756
154969
|
agentThreadTracker.remember(msg.chatId, outboundThreadId);
|
|
154757
154970
|
}
|
|
154758
154971
|
status.markAutoClearedForMessage(msg);
|
|
@@ -154775,7 +154988,7 @@ function createSlackAdapter(config3) {
|
|
|
154775
154988
|
});
|
|
154776
154989
|
const outboundThreadId = threadTs ?? (resolveSlackChatType(chatId) === "channel" ? response.ts ?? null : null);
|
|
154777
154990
|
ingress.rememberMessageThread(response.ts, outboundThreadId);
|
|
154778
|
-
if (resolveSlackChatType(chatId) === "channel" &&
|
|
154991
|
+
if (resolveSlackChatType(chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154779
154992
|
agentThreadTracker.remember(chatId, outboundThreadId);
|
|
154780
154993
|
}
|
|
154781
154994
|
status.markAutoClearedForMessage({
|
|
@@ -154801,7 +155014,7 @@ function createSlackAdapter(config3) {
|
|
|
154801
155014
|
if (event2.kind === "generic_tool_approval" && response.ts) {
|
|
154802
155015
|
approvals.rememberPrompt(event2, response.ts);
|
|
154803
155016
|
}
|
|
154804
|
-
if (resolveSlackChatType(event2.source.chatId) === "channel" &&
|
|
155017
|
+
if (resolveSlackChatType(event2.source.chatId) === "channel" && isNonEmptyString4(outboundThreadId)) {
|
|
154805
155018
|
agentThreadTracker.remember(event2.source.chatId, outboundThreadId);
|
|
154806
155019
|
}
|
|
154807
155020
|
status.markAutoCleared(event2.source);
|
|
@@ -154817,8 +155030,8 @@ function createSlackAdapter(config3) {
|
|
|
154817
155030
|
const slackApp = await ensureApp();
|
|
154818
155031
|
const auth = await slackApp.client.auth.test();
|
|
154819
155032
|
const authRecord = auth;
|
|
154820
|
-
botUserId =
|
|
154821
|
-
botId =
|
|
155033
|
+
botUserId = isNonEmptyString4(authRecord.user_id) ? authRecord.user_id : null;
|
|
155034
|
+
botId = isNonEmptyString4(authRecord.bot_id) ? authRecord.bot_id : null;
|
|
154822
155035
|
await slackApp.start();
|
|
154823
155036
|
running = true;
|
|
154824
155037
|
console.log(`[Slack] App started for workspace ${auth.team ?? "unknown"} (dm_policy: ${config3.dmPolicy})`);
|
|
@@ -156041,7 +156254,7 @@ function formatDiscordDeliveryError(error54) {
|
|
|
156041
156254
|
}
|
|
156042
156255
|
|
|
156043
156256
|
// src/channels/discord/utils.ts
|
|
156044
|
-
function
|
|
156257
|
+
function isNonEmptyString8(value) {
|
|
156045
156258
|
return typeof value === "string" && value.length > 0;
|
|
156046
156259
|
}
|
|
156047
156260
|
function isDiscordTextChannel(channel) {
|
|
@@ -156108,7 +156321,7 @@ function shouldAutoThreadOnDiscordMention(account, channelId) {
|
|
|
156108
156321
|
return account.autoThreadOnMention ?? false;
|
|
156109
156322
|
}
|
|
156110
156323
|
function buildDiscordIngressMessageKey(accountId, messageId) {
|
|
156111
|
-
if (!
|
|
156324
|
+
if (!isNonEmptyString8(accountId) || !isNonEmptyString8(messageId)) {
|
|
156112
156325
|
return null;
|
|
156113
156326
|
}
|
|
156114
156327
|
return `${accountId}:${messageId}`;
|
|
@@ -156192,13 +156405,13 @@ function createDiscordAdapter(config3) {
|
|
|
156192
156405
|
return false;
|
|
156193
156406
|
}
|
|
156194
156407
|
function getLifecycleMessageKey(source2) {
|
|
156195
|
-
if (source2.channel !== "discord" || !
|
|
156408
|
+
if (source2.channel !== "discord" || !isNonEmptyString8(source2.chatId) || !isNonEmptyString8(source2.messageId)) {
|
|
156196
156409
|
return null;
|
|
156197
156410
|
}
|
|
156198
156411
|
return `${source2.chatId}:${source2.messageId}`;
|
|
156199
156412
|
}
|
|
156200
156413
|
function getLifecycleReplyKey(source2) {
|
|
156201
|
-
if (source2.channel !== "discord" || !
|
|
156414
|
+
if (source2.channel !== "discord" || !isNonEmptyString8(source2.chatId)) {
|
|
156202
156415
|
return null;
|
|
156203
156416
|
}
|
|
156204
156417
|
return [
|
|
@@ -156211,7 +156424,7 @@ function createDiscordAdapter(config3) {
|
|
|
156211
156424
|
if (source2.channel !== "discord")
|
|
156212
156425
|
return null;
|
|
156213
156426
|
const channelId = source2.threadId ?? source2.chatId;
|
|
156214
|
-
return
|
|
156427
|
+
return isNonEmptyString8(channelId) ? channelId : null;
|
|
156215
156428
|
}
|
|
156216
156429
|
function getTypingSourceKey(source2) {
|
|
156217
156430
|
const channelId = getTypingChannelId(source2);
|
|
@@ -156263,7 +156476,7 @@ function createDiscordAdapter(config3) {
|
|
|
156263
156476
|
return true;
|
|
156264
156477
|
}
|
|
156265
156478
|
async function sendLifecycleReaction(source2, emoji3, remove = false) {
|
|
156266
|
-
if (!client || !
|
|
156479
|
+
if (!client || !isNonEmptyString8(source2.messageId))
|
|
156267
156480
|
return;
|
|
156268
156481
|
try {
|
|
156269
156482
|
const channel = await client.channels.fetch(source2.chatId);
|
|
@@ -156504,15 +156717,23 @@ function createDiscordAdapter(config3) {
|
|
|
156504
156717
|
client.on("messageCreate", async (message) => {
|
|
156505
156718
|
if (!adapter.onMessage)
|
|
156506
156719
|
return;
|
|
156507
|
-
if (message.author.bot)
|
|
156508
|
-
return;
|
|
156509
156720
|
const content = (message.content ?? "").trim();
|
|
156510
156721
|
const userId = message.author.id;
|
|
156511
156722
|
if (!userId)
|
|
156512
156723
|
return;
|
|
156724
|
+
const effectiveBotUserId = botUserId ?? client?.user?.id ?? null;
|
|
156513
156725
|
const chatType = resolveDiscordChatType(message.guildId);
|
|
156514
156726
|
const isThread = isThreadMessage(message);
|
|
156515
|
-
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
|
+
}
|
|
156516
156737
|
if (chatType === "direct") {
|
|
156517
156738
|
if (markIngressMessageSeen(message.id))
|
|
156518
156739
|
return;
|
|
@@ -156538,7 +156759,9 @@ function createDiscordAdapter(config3) {
|
|
|
156538
156759
|
await adapter.onMessage(inbound2);
|
|
156539
156760
|
} catch (error54) {
|
|
156540
156761
|
console.error("[Discord] Error handling DM:", error54);
|
|
156541
|
-
|
|
156762
|
+
if (!message.author.bot) {
|
|
156763
|
+
await notifyDiscordDeliveryError(message, error54);
|
|
156764
|
+
}
|
|
156542
156765
|
}
|
|
156543
156766
|
return;
|
|
156544
156767
|
}
|
|
@@ -156593,7 +156816,9 @@ function createDiscordAdapter(config3) {
|
|
|
156593
156816
|
await adapter.onMessage(inbound);
|
|
156594
156817
|
} catch (error54) {
|
|
156595
156818
|
console.error("[Discord] Error handling guild message:", error54);
|
|
156596
|
-
|
|
156819
|
+
if (!message.author.bot) {
|
|
156820
|
+
await notifyDiscordDeliveryError(message, error54);
|
|
156821
|
+
}
|
|
156597
156822
|
}
|
|
156598
156823
|
});
|
|
156599
156824
|
const handleReactionEvent = async (reaction, user, action3) => {
|
|
@@ -156802,7 +157027,7 @@ function createDiscordAdapter(config3) {
|
|
|
156802
157027
|
clearTypingForChannel(chatId);
|
|
156803
157028
|
},
|
|
156804
157029
|
async prepareInboundMessage(msg, options3) {
|
|
156805
|
-
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !
|
|
157030
|
+
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString8(msg.threadId) || !client) {
|
|
156806
157031
|
return msg;
|
|
156807
157032
|
}
|
|
156808
157033
|
const starter = await resolveDiscordThreadStarter({
|
|
@@ -160855,168 +161080,6 @@ var init_app_urls = __esm(() => {
|
|
|
160855
161080
|
LETTA_CHAT_API_KEYS_URL = `${CHAT_BASE}/preferences/api-keys`;
|
|
160856
161081
|
});
|
|
160857
161082
|
|
|
160858
|
-
// src/channels/registry-presentation.ts
|
|
160859
|
-
function channelDisplayName4(channelId) {
|
|
160860
|
-
try {
|
|
160861
|
-
return getChannelDisplayName(channelId);
|
|
160862
|
-
} catch {
|
|
160863
|
-
return channelId;
|
|
160864
|
-
}
|
|
160865
|
-
}
|
|
160866
|
-
function normalizeAgentId(agentId) {
|
|
160867
|
-
const normalized = agentId?.trim();
|
|
160868
|
-
return normalized ? normalized : null;
|
|
160869
|
-
}
|
|
160870
|
-
function getConfiguredAgentId(config3) {
|
|
160871
|
-
if (!config3 || typeof config3 !== "object")
|
|
160872
|
-
return null;
|
|
160873
|
-
const source2 = config3;
|
|
160874
|
-
return normalizeAgentId(source2.agentId) ?? normalizeAgentId(source2.binding?.agentId);
|
|
160875
|
-
}
|
|
160876
|
-
function buildPairingInstructions(channelId, code2, options3 = {}) {
|
|
160877
|
-
const displayName = channelDisplayName4(channelId);
|
|
160878
|
-
const configuredAgentId = normalizeAgentId(options3.agentId);
|
|
160879
|
-
const pairingCommand = `letta channels pair --channel ${channelId} --code ${code2} --agent ${configuredAgentId ?? "<agent-id>"}`;
|
|
160880
|
-
const agentLookupLines = configuredAgentId ? [] : ["Find the target agent with: letta agents list"];
|
|
160881
|
-
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
160882
|
-
return [
|
|
160883
|
-
"Connect this chat to a Letta agent.",
|
|
160884
|
-
"",
|
|
160885
|
-
`Pairing code: ${code2}`,
|
|
160886
|
-
"",
|
|
160887
|
-
"CLI on the listener machine:",
|
|
160888
|
-
pairingCommand,
|
|
160889
|
-
...agentLookupLines,
|
|
160890
|
-
"",
|
|
160891
|
-
"This code expires in 15 minutes."
|
|
160892
|
-
].join(`
|
|
160893
|
-
`);
|
|
160894
|
-
}
|
|
160895
|
-
return [
|
|
160896
|
-
"Connect this chat to a Letta agent.",
|
|
160897
|
-
"",
|
|
160898
|
-
`Pairing code: ${code2}`,
|
|
160899
|
-
"",
|
|
160900
|
-
`In Letta Code: open Channels > ${displayName} and approve this pending chat.`,
|
|
160901
|
-
"",
|
|
160902
|
-
"CLI on the listener machine:",
|
|
160903
|
-
pairingCommand,
|
|
160904
|
-
...agentLookupLines,
|
|
160905
|
-
"",
|
|
160906
|
-
"This code expires in 15 minutes."
|
|
160907
|
-
].join(`
|
|
160908
|
-
`);
|
|
160909
|
-
}
|
|
160910
|
-
function buildUnboundRouteInstructions(channelId, chatId) {
|
|
160911
|
-
const displayName = channelDisplayName4(channelId);
|
|
160912
|
-
if (!isFirstPartyChannelPlugin(channelId)) {
|
|
160913
|
-
return `This chat isn't connected to a Letta agent yet.
|
|
160914
|
-
|
|
160915
|
-
` + `On the machine where your listener runs:
|
|
160916
|
-
|
|
160917
|
-
` + `letta channels route add --channel ${channelId} --chat-id ${chatId} --agent <agent-id>
|
|
160918
|
-
|
|
160919
|
-
` + `Find your agent id with letta agents list.`;
|
|
160920
|
-
}
|
|
160921
|
-
return `This chat isn't connected to a Letta agent yet.
|
|
160922
|
-
|
|
160923
|
-
` + `Open Channels > ${displayName} in Letta Code and connect this chat there.
|
|
160924
|
-
|
|
160925
|
-
` + `Chat ID: ${chatId}`;
|
|
160926
|
-
}
|
|
160927
|
-
function buildSlackAppSetupInstructions() {
|
|
160928
|
-
return `This Slack app isn't connected to a Letta agent yet.
|
|
160929
|
-
|
|
160930
|
-
` + "Open Channels > Slack in Letta Code, choose which agent this app should represent, and try again.";
|
|
160931
|
-
}
|
|
160932
|
-
function truncateChannelSummaryPreview(text, maxLength3 = 72) {
|
|
160933
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
160934
|
-
if (!normalized)
|
|
160935
|
-
return null;
|
|
160936
|
-
if (normalized.length <= maxLength3)
|
|
160937
|
-
return normalized;
|
|
160938
|
-
return `${normalized.slice(0, maxLength3 - 1).trimEnd()}…`;
|
|
160939
|
-
}
|
|
160940
|
-
function buildSlackConversationSummary(msg) {
|
|
160941
|
-
if (msg.chatType === "direct") {
|
|
160942
|
-
if (msg.threadId?.trim()) {
|
|
160943
|
-
const preview3 = truncateChannelSummaryPreview(msg.text);
|
|
160944
|
-
return preview3 ? `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}: ${preview3}` : `[Slack] DM thread with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160945
|
-
}
|
|
160946
|
-
return `[Slack] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160947
|
-
}
|
|
160948
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160949
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160950
|
-
if (preview2)
|
|
160951
|
-
return `[Slack] Thread${channelLabel}: ${preview2}`;
|
|
160952
|
-
return `[Slack] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
160953
|
-
}
|
|
160954
|
-
function buildDiscordConversationSummary(msg) {
|
|
160955
|
-
if (msg.chatType === "direct") {
|
|
160956
|
-
return `[Discord] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160957
|
-
}
|
|
160958
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160959
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160960
|
-
if (preview2)
|
|
160961
|
-
return `[Discord] Thread${channelLabel}: ${preview2}`;
|
|
160962
|
-
return `[Discord] Thread${channelLabel || ` ${msg.chatId}`}`;
|
|
160963
|
-
}
|
|
160964
|
-
function buildTelegramConversationSummary(msg) {
|
|
160965
|
-
if (msg.chatType === "direct") {
|
|
160966
|
-
return `[Telegram] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160967
|
-
}
|
|
160968
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160969
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160970
|
-
if (preview2)
|
|
160971
|
-
return `[Telegram] Topic${channelLabel}: ${preview2}`;
|
|
160972
|
-
return `[Telegram] Topic${channelLabel || ` ${msg.chatId}`}`;
|
|
160973
|
-
}
|
|
160974
|
-
function buildWhatsAppConversationSummary(msg) {
|
|
160975
|
-
if (msg.chatType === "direct") {
|
|
160976
|
-
return `[WhatsApp] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160977
|
-
}
|
|
160978
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160979
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160980
|
-
if (preview2)
|
|
160981
|
-
return `[WhatsApp] Group${channelLabel}: ${preview2}`;
|
|
160982
|
-
return `[WhatsApp] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
160983
|
-
}
|
|
160984
|
-
function buildSignalConversationSummary(msg) {
|
|
160985
|
-
if (msg.chatType === "direct") {
|
|
160986
|
-
return `[Signal] DM with ${msg.senderName?.trim() || msg.senderId}`;
|
|
160987
|
-
}
|
|
160988
|
-
const preview2 = truncateChannelSummaryPreview(msg.text);
|
|
160989
|
-
const channelLabel = msg.chatLabel && msg.chatLabel !== msg.chatId ? ` in ${msg.chatLabel}` : "";
|
|
160990
|
-
if (preview2)
|
|
160991
|
-
return `[Signal] Group${channelLabel}: ${preview2}`;
|
|
160992
|
-
return `[Signal] Group${channelLabel || ` ${msg.chatId}`}`;
|
|
160993
|
-
}
|
|
160994
|
-
function buildChannelTurnSource(route, msg) {
|
|
160995
|
-
return {
|
|
160996
|
-
channel: msg.channel,
|
|
160997
|
-
accountId: msg.accountId,
|
|
160998
|
-
chatId: msg.chatId,
|
|
160999
|
-
chatType: msg.chatType,
|
|
161000
|
-
senderId: msg.senderId,
|
|
161001
|
-
senderTeamId: msg.senderTeamId,
|
|
161002
|
-
messageId: msg.messageId,
|
|
161003
|
-
threadId: msg.threadId,
|
|
161004
|
-
agentId: route.agentId,
|
|
161005
|
-
conversationId: route.conversationId
|
|
161006
|
-
};
|
|
161007
|
-
}
|
|
161008
|
-
function buildDirectReplyOptions(msg) {
|
|
161009
|
-
if (!msg.messageId && !msg.threadId)
|
|
161010
|
-
return;
|
|
161011
|
-
return {
|
|
161012
|
-
replyToMessageId: msg.threadId ?? msg.messageId ?? undefined,
|
|
161013
|
-
threadId: msg.threadId ?? null
|
|
161014
|
-
};
|
|
161015
|
-
}
|
|
161016
|
-
var init_registry_presentation = __esm(() => {
|
|
161017
|
-
init_plugin_registry();
|
|
161018
|
-
});
|
|
161019
|
-
|
|
161020
161083
|
// src/channels/routing.ts
|
|
161021
161084
|
var exports_routing = {};
|
|
161022
161085
|
__export(exports_routing, {
|
|
@@ -161027,8 +161090,10 @@ __export(exports_routing, {
|
|
|
161027
161090
|
removeRouteInMemory: () => removeRouteInMemory,
|
|
161028
161091
|
removeRoute: () => removeRoute,
|
|
161029
161092
|
loadRoutes: () => loadRoutes,
|
|
161093
|
+
loadRouteForInboundMessage: () => loadRouteForInboundMessage,
|
|
161030
161094
|
getRoutesForChannel: () => getRoutesForChannel,
|
|
161031
161095
|
getRouteRaw: () => getRouteRaw,
|
|
161096
|
+
getRouteForInboundMessage: () => getRouteForInboundMessage,
|
|
161032
161097
|
getRoute: () => getRoute,
|
|
161033
161098
|
getAllRoutes: () => getAllRoutes,
|
|
161034
161099
|
clearAllRoutes: () => clearAllRoutes,
|
|
@@ -161131,6 +161196,28 @@ function getRoute(channel, chatId, accountId, threadId) {
|
|
|
161131
161196
|
function getRouteRaw(channel, chatId, accountId, threadId) {
|
|
161132
161197
|
return routesByKey.get(routeKey(channel, chatId, accountId, threadId));
|
|
161133
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
|
+
}
|
|
161134
161221
|
function getRoutesForChannel(channelId, accountId) {
|
|
161135
161222
|
const prefix = accountId === undefined ? `${channelId}:` : `${channelId}:${normalizeAccountId3(accountId)}:`;
|
|
161136
161223
|
const routes = [];
|
|
@@ -161212,16 +161299,10 @@ var init_routing = __esm(() => {
|
|
|
161212
161299
|
|
|
161213
161300
|
// src/channels/registry-commands.ts
|
|
161214
161301
|
function createChannelCommandRouter(deps) {
|
|
161215
|
-
function findRawRouteForMessage(msg) {
|
|
161216
|
-
return getRouteRaw(msg.channel, msg.chatId, msg.accountId, msg.threadId) ?? null;
|
|
161217
|
-
}
|
|
161218
161302
|
function loadAndFindRawRouteForMessage(msg) {
|
|
161219
|
-
|
|
161220
|
-
|
|
161221
|
-
|
|
161222
|
-
}
|
|
161223
|
-
loadRoutes(msg.channel);
|
|
161224
|
-
return findRawRouteForMessage(msg);
|
|
161303
|
+
return loadRouteForInboundMessage(msg, msg.accountId, {
|
|
161304
|
+
includeDisabled: true
|
|
161305
|
+
});
|
|
161225
161306
|
}
|
|
161226
161307
|
async function handlePauseResumeSlashCommand(commandName, msg) {
|
|
161227
161308
|
const route = loadAndFindRawRouteForMessage(msg);
|
|
@@ -161471,15 +161552,9 @@ function createChannelCommandRouter(deps) {
|
|
|
161471
161552
|
});
|
|
161472
161553
|
}
|
|
161473
161554
|
function getCancelRoute(msg) {
|
|
161474
|
-
|
|
161475
|
-
if (route)
|
|
161476
|
-
return route;
|
|
161477
|
-
}
|
|
161478
|
-
loadRoutes(msg.channel);
|
|
161479
|
-
route = deps.getRoute(msg.channel, msg.chatId, msg.accountId, msg.threadId);
|
|
161480
|
-
if (route) {
|
|
161555
|
+
const route = loadRouteForInboundMessage(msg, msg.accountId);
|
|
161556
|
+
if (route)
|
|
161481
161557
|
return route;
|
|
161482
|
-
}
|
|
161483
161558
|
if (msg.channel !== "slack" || msg.chatType !== "channel" || msg.threadId != null) {
|
|
161484
161559
|
return null;
|
|
161485
161560
|
}
|
|
@@ -162340,7 +162415,7 @@ function createChannelInboundRouter(deps) {
|
|
|
162340
162415
|
return;
|
|
162341
162416
|
}
|
|
162342
162417
|
if (resolveChannelAccessScope(msg.chatType) === "dm") {
|
|
162343
|
-
await adapter.sendDirectReply(msg.chatId, buildChannelAccessDeniedMessage(msg.channel));
|
|
162418
|
+
await adapter.sendDirectReply(msg.chatId, buildChannelAccessDeniedMessage(msg.channel), buildDirectReplyOptions(msg));
|
|
162344
162419
|
} else {
|
|
162345
162420
|
console.log(`[channels] Dropped ${msg.channel} group message from unauthorized sender ${msg.senderId} in chat ${msg.chatId}`);
|
|
162346
162421
|
}
|
|
@@ -162352,14 +162427,7 @@ function createChannelInboundRouter(deps) {
|
|
|
162352
162427
|
if (deps.commands.shouldDropUnroutedSlackThreadInput(msg, accountId, config3)) {
|
|
162353
162428
|
return;
|
|
162354
162429
|
}
|
|
162355
|
-
const getStatusRoute = () =>
|
|
162356
|
-
let statusRoute = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162357
|
-
if (!statusRoute) {
|
|
162358
|
-
loadRoutes(msg.channel);
|
|
162359
|
-
statusRoute = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162360
|
-
}
|
|
162361
|
-
return statusRoute;
|
|
162362
|
-
};
|
|
162430
|
+
const getStatusRoute = () => loadRouteForInboundMessage(msg, accountId);
|
|
162363
162431
|
if (await tryHandleChannelSlashCommand(adapter, msg, {
|
|
162364
162432
|
statusContext: {
|
|
162365
162433
|
adapterRunning: adapter.isRunning(),
|
|
@@ -162509,16 +162577,12 @@ function createChannelInboundRouter(deps) {
|
|
|
162509
162577
|
});
|
|
162510
162578
|
await adapter.sendDirectReply(msg.chatId, buildPairingInstructions(msg.channel, code2, {
|
|
162511
162579
|
agentId: getConfiguredAgentId(config3)
|
|
162512
|
-
}));
|
|
162580
|
+
}), buildDirectReplyOptions(msg));
|
|
162513
162581
|
return;
|
|
162514
162582
|
}
|
|
162515
|
-
|
|
162516
|
-
if (!route) {
|
|
162517
|
-
loadRoutes(msg.channel);
|
|
162518
|
-
route = getRoute(msg.channel, msg.chatId, accountId, msg.threadId);
|
|
162519
|
-
}
|
|
162583
|
+
const route = loadRouteForInboundMessage(msg, accountId);
|
|
162520
162584
|
if (!route) {
|
|
162521
|
-
await adapter.sendDirectReply(msg.chatId, buildUnboundRouteInstructions(msg.channel, msg.chatId));
|
|
162585
|
+
await adapter.sendDirectReply(msg.chatId, buildUnboundRouteInstructions(msg.channel, msg.chatId), buildDirectReplyOptions(msg));
|
|
162522
162586
|
return;
|
|
162523
162587
|
}
|
|
162524
162588
|
const preparedMessage = adapter.prepareInboundMessage ? await adapter.prepareInboundMessage(msg, { isFirstRouteTurn: false }) : msg;
|
|
@@ -345981,6 +346045,7 @@ async function loadLocalMods(options3) {
|
|
|
345981
346045
|
const builtinCommandIds = new Set([...options3.builtinCommandIds ?? []]);
|
|
345982
346046
|
const reservedToolNames = new Set([...options3.reservedToolNames ?? []]);
|
|
345983
346047
|
const registry2 = createEmptyModRegistry(sources, generation2, capabilities, options3.registerCapabilitiesGlobally !== false);
|
|
346048
|
+
options3.onRegistryCreated?.(registry2);
|
|
345984
346049
|
for (const source2 of sources) {
|
|
345985
346050
|
for (const diagnostic of source2.diagnostics ?? []) {
|
|
345986
346051
|
const owner = createModOwner(diagnostic.path, source2, generation2);
|
|
@@ -346191,6 +346256,13 @@ function createModEngine(options3) {
|
|
|
346191
346256
|
const nextRegistry = await loadLocalMods({
|
|
346192
346257
|
...modOptions,
|
|
346193
346258
|
generation: loadGeneration,
|
|
346259
|
+
onRegistryCreated: (registry2) => {
|
|
346260
|
+
loadingRegistry = registry2;
|
|
346261
|
+
if (!disposed && loadGeneration === generation2) {
|
|
346262
|
+
activeRegistry = registry2;
|
|
346263
|
+
publish();
|
|
346264
|
+
}
|
|
346265
|
+
},
|
|
346194
346266
|
onChange: () => {
|
|
346195
346267
|
if (!disposed && loadingRegistry && loadGeneration === generation2) {
|
|
346196
346268
|
activeRegistry = loadingRegistry;
|
|
@@ -353068,10 +353140,7 @@ function inferAccountIdFromChannelTurnSources(params) {
|
|
|
353068
353140
|
}
|
|
353069
353141
|
const accountIds = new Set;
|
|
353070
353142
|
for (const source2 of params.channelTurnSources ?? []) {
|
|
353071
|
-
if (source2.channel !== params.input.channel || source2.chatId !== chatId || source2.agentId !== params.scope.agentId || source2.conversationId !== params.scope.conversationId) {
|
|
353072
|
-
continue;
|
|
353073
|
-
}
|
|
353074
|
-
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) {
|
|
353075
353144
|
continue;
|
|
353076
353145
|
}
|
|
353077
353146
|
if (source2.accountId?.trim()) {
|
|
@@ -353174,7 +353243,7 @@ async function message_channel(args) {
|
|
|
353174
353243
|
accountId: resolvedAccountId,
|
|
353175
353244
|
channelTurnSources: args.channelTurnSources
|
|
353176
353245
|
});
|
|
353177
|
-
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);
|
|
353178
353247
|
executionContext = {
|
|
353179
353248
|
request: buildMessageChannelRequest(input, input.chatId, requestThreadId),
|
|
353180
353249
|
route: route2,
|
|
@@ -381951,6 +382020,17 @@ var init_local_backend = __esm(() => {
|
|
|
381951
382020
|
|
|
381952
382021
|
// src/backend/backend.ts
|
|
381953
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
|
+
}
|
|
381954
382034
|
|
|
381955
382035
|
class APIBackend {
|
|
381956
382036
|
capabilities = {
|
|
@@ -382022,7 +382102,7 @@ class APIBackend {
|
|
|
382022
382102
|
}
|
|
382023
382103
|
async listConversationMessages(conversationId, body, options3) {
|
|
382024
382104
|
const client = await this.getClient();
|
|
382025
|
-
return client.conversations.messages.list(conversationId, body, options3);
|
|
382105
|
+
return client.conversations.messages.list(conversationId, toApiConversationMessageListBody(body), options3);
|
|
382026
382106
|
}
|
|
382027
382107
|
async compactConversationMessages(conversationId, body, options3) {
|
|
382028
382108
|
const client = await this.getClient();
|
|
@@ -382160,7 +382240,7 @@ async function configureDevBackend(name) {
|
|
|
382160
382240
|
function __testSetBackend(nextBackend) {
|
|
382161
382241
|
backend = nextBackend ?? createInitialBackend();
|
|
382162
382242
|
}
|
|
382163
|
-
var backend = null;
|
|
382243
|
+
var DEFAULT_CONVERSATION_MESSAGE_ORDER = "desc", backend = null;
|
|
382164
382244
|
var init_backend = __esm(() => {
|
|
382165
382245
|
init_backend_mode();
|
|
382166
382246
|
init_local_backend();
|
|
@@ -382179,6 +382259,7 @@ __export(exports_backend, {
|
|
|
382179
382259
|
configureDevBackend: () => configureDevBackend,
|
|
382180
382260
|
configureBackendMode: () => configureBackendMode,
|
|
382181
382261
|
__testSetBackend: () => __testSetBackend,
|
|
382262
|
+
DEFAULT_CONVERSATION_MESSAGE_ORDER: () => DEFAULT_CONVERSATION_MESSAGE_ORDER,
|
|
382182
382263
|
APIBackend: () => APIBackend
|
|
382183
382264
|
});
|
|
382184
382265
|
var init_backend2 = __esm(() => {
|
|
@@ -423944,6 +424025,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423944
424025
|
"token",
|
|
423945
424026
|
"agent_id",
|
|
423946
424027
|
"allowed_channels",
|
|
424028
|
+
"allow_bots",
|
|
423947
424029
|
"default_permission_mode",
|
|
423948
424030
|
"transcribe_voice",
|
|
423949
424031
|
"auto_thread_on_mention",
|
|
@@ -423959,7 +424041,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423959
424041
|
return false;
|
|
423960
424042
|
}
|
|
423961
424043
|
}
|
|
423962
|
-
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);
|
|
423963
424045
|
},
|
|
423964
424046
|
toAccountPatch(config3) {
|
|
423965
424047
|
const allowedChannels = isAllowedChannels(config3.allowed_channels) ? Array.isArray(config3.allowed_channels) ? [...config3.allowed_channels] : { ...config3.allowed_channels } : undefined;
|
|
@@ -423968,6 +424050,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423968
424050
|
agentId: isNullableString2(config3.agent_id) ? config3.agent_id : undefined,
|
|
423969
424051
|
defaultPermissionMode: isDefaultPermissionMode(config3.default_permission_mode) ? migratePermissionMode(config3.default_permission_mode) : undefined,
|
|
423970
424052
|
allowedChannels,
|
|
424053
|
+
allowBots: config3.allow_bots !== undefined && isValidDiscordAllowBotsConfigValue(config3.allow_bots) ? normalizeDiscordAllowBotsMode(config3.allow_bots) : undefined,
|
|
423971
424054
|
transcribeVoice: isBoolean(config3.transcribe_voice) ? config3.transcribe_voice : undefined,
|
|
423972
424055
|
autoThreadOnMention: isBoolean(config3.auto_thread_on_mention) ? config3.auto_thread_on_mention : undefined,
|
|
423973
424056
|
threadPolicyByChannel: typeof config3.thread_policy_by_channel === "object" && !Array.isArray(config3.thread_policy_by_channel) ? { ...config3.thread_policy_by_channel } : undefined,
|
|
@@ -423982,6 +424065,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423982
424065
|
agent_id: account.agentId,
|
|
423983
424066
|
default_permission_mode: account.defaultPermissionMode ?? "standard",
|
|
423984
424067
|
allowed_channels: serializeAllowedChannels(account.allowedChannels),
|
|
424068
|
+
allow_bots: account.allowBots ?? false,
|
|
423985
424069
|
transcribe_voice: account.transcribeVoice === true,
|
|
423986
424070
|
auto_thread_on_mention: account.autoThreadOnMention ?? false,
|
|
423987
424071
|
thread_policy_by_channel: account.threadPolicyByChannel ?? {},
|
|
@@ -423996,6 +424080,7 @@ var init_account_config2 = __esm(() => {
|
|
|
423996
424080
|
agent_id: account.agentId,
|
|
423997
424081
|
default_permission_mode: account.defaultPermissionMode ?? "standard",
|
|
423998
424082
|
allowed_channels: serializeAllowedChannels(account.allowedChannels),
|
|
424083
|
+
allow_bots: account.allowBots ?? false,
|
|
423999
424084
|
transcribe_voice: account.transcribeVoice === true,
|
|
424000
424085
|
auto_thread_on_mention: account.autoThreadOnMention ?? false,
|
|
424001
424086
|
thread_policy_by_channel: account.threadPolicyByChannel ?? {},
|
|
@@ -424561,6 +424646,7 @@ function createAccountFromPatch(channelId, accountId, patch2) {
|
|
|
424561
424646
|
allowedChannels: normalizedPatch.allowedChannels ?? [],
|
|
424562
424647
|
autoThreadOnMention: normalizedPatch.autoThreadOnMention ?? false,
|
|
424563
424648
|
threadPolicyByChannel: normalizedPatch.threadPolicyByChannel,
|
|
424649
|
+
allowBots: normalizedPatch.allowBots ?? false,
|
|
424564
424650
|
acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction,
|
|
424565
424651
|
removeStaleRoutes: normalizedPatch.removeStaleRoutes,
|
|
424566
424652
|
inboundDebounceMs: normalizedPatch.inboundDebounceMs,
|
|
@@ -424676,6 +424762,7 @@ function mergeAccountPatch(existing, patch2) {
|
|
|
424676
424762
|
allowedChannels: normalizedPatch.allowedChannels ?? existing.allowedChannels,
|
|
424677
424763
|
autoThreadOnMention: normalizedPatch.autoThreadOnMention ?? existing.autoThreadOnMention,
|
|
424678
424764
|
threadPolicyByChannel: normalizedPatch.threadPolicyByChannel ?? existing.threadPolicyByChannel,
|
|
424765
|
+
allowBots: normalizedPatch.allowBots ?? existing.allowBots ?? false,
|
|
424679
424766
|
acknowledgeMessageReaction: normalizedPatch.acknowledgeMessageReaction ?? existing.acknowledgeMessageReaction,
|
|
424680
424767
|
removeStaleRoutes: normalizedPatch.removeStaleRoutes ?? existing.removeStaleRoutes,
|
|
424681
424768
|
inboundDebounceMs: normalizedPatch.inboundDebounceMs ?? existing.inboundDebounceMs,
|
|
@@ -424841,6 +424928,7 @@ function toAccountSnapshot(account) {
|
|
|
424841
424928
|
autoThreadOnMention: account.autoThreadOnMention ?? false,
|
|
424842
424929
|
threadPolicyByChannel: account.threadPolicyByChannel ?? {},
|
|
424843
424930
|
acknowledgeMessageReaction: account.acknowledgeMessageReaction ?? false,
|
|
424931
|
+
allowBots: account.allowBots ?? false,
|
|
424844
424932
|
removeStaleRoutes: account.removeStaleRoutes ?? false,
|
|
424845
424933
|
inboundDebounceMs: account.inboundDebounceMs,
|
|
424846
424934
|
createdAt: account.createdAt,
|
|
@@ -425006,6 +425094,7 @@ function getChannelConfigSnapshot(channelId, accountId) {
|
|
|
425006
425094
|
autoThreadOnMention: account.autoThreadOnMention ?? false,
|
|
425007
425095
|
threadPolicyByChannel: account.threadPolicyByChannel ?? {},
|
|
425008
425096
|
acknowledgeMessageReaction: account.acknowledgeMessageReaction ?? false,
|
|
425097
|
+
allowBots: account.allowBots ?? false,
|
|
425009
425098
|
removeStaleRoutes: account.removeStaleRoutes ?? false,
|
|
425010
425099
|
inboundDebounceMs: account.inboundDebounceMs
|
|
425011
425100
|
};
|
|
@@ -446603,6 +446692,40 @@ function getPageItems(page) {
|
|
|
446603
446692
|
}
|
|
446604
446693
|
return [];
|
|
446605
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
|
+
}
|
|
446606
446729
|
async function handleAgentConversationManagementCommand(parsed, socket, safeSocketSend) {
|
|
446607
446730
|
const backend3 = getBackend();
|
|
446608
446731
|
if (parsed.type === "agent_list") {
|
|
@@ -446835,12 +446958,14 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
446835
446958
|
}
|
|
446836
446959
|
if (parsed.type === "conversation_messages_list") {
|
|
446837
446960
|
try {
|
|
446838
|
-
const page = await backend3
|
|
446961
|
+
const page = await listConversationMessagePage(backend3, parsed.conversation_id, parsed.query);
|
|
446839
446962
|
safeSocketSend(socket, {
|
|
446840
446963
|
type: "conversation_messages_list_response",
|
|
446841
446964
|
request_id: parsed.request_id,
|
|
446842
446965
|
success: true,
|
|
446843
|
-
messages:
|
|
446966
|
+
messages: page.messages,
|
|
446967
|
+
next_before: page.nextBefore,
|
|
446968
|
+
has_more: page.hasMore
|
|
446844
446969
|
}, "listener_conversation_management_send_failed", "listener_conversation_management");
|
|
446845
446970
|
} catch (error54) {
|
|
446846
446971
|
safeSocketSend(socket, {
|
|
@@ -446848,6 +446973,8 @@ async function handleAgentConversationManagementCommand(parsed, socket, safeSock
|
|
|
446848
446973
|
request_id: parsed.request_id,
|
|
446849
446974
|
success: false,
|
|
446850
446975
|
messages: [],
|
|
446976
|
+
next_before: null,
|
|
446977
|
+
has_more: false,
|
|
446851
446978
|
error: getErrorMessage4(error54, "Failed to list conversation messages")
|
|
446852
446979
|
}, "listener_conversation_management_send_failed", "listener_conversation_management");
|
|
446853
446980
|
}
|
|
@@ -448784,7 +448911,7 @@ function normalizeCatalogSource(source2) {
|
|
|
448784
448911
|
return source2.trim().replace(/\/+$/, "");
|
|
448785
448912
|
}
|
|
448786
448913
|
}
|
|
448787
|
-
function
|
|
448914
|
+
function isNonEmptyString9(value) {
|
|
448788
448915
|
return typeof value === "string" && value.length > 0;
|
|
448789
448916
|
}
|
|
448790
448917
|
function isPositiveFiniteNumber(value) {
|
|
@@ -448805,13 +448932,13 @@ function isRecord9(value) {
|
|
|
448805
448932
|
function hasEntryIdentity(entry) {
|
|
448806
448933
|
if (!isRecord9(entry))
|
|
448807
448934
|
return false;
|
|
448808
|
-
return
|
|
448935
|
+
return isNonEmptyString9(entry.id) && isNonEmptyString9(entry.handle) && isNonEmptyString9(entry.label);
|
|
448809
448936
|
}
|
|
448810
448937
|
function isValidEntry(entry) {
|
|
448811
448938
|
if (!hasEntryIdentity(entry))
|
|
448812
448939
|
return false;
|
|
448813
448940
|
const candidate = entry;
|
|
448814
|
-
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));
|
|
448815
448942
|
}
|
|
448816
448943
|
function isValidCachedModel(entry) {
|
|
448817
448944
|
if (!hasEntryIdentity(entry))
|
|
@@ -451468,11 +451595,11 @@ function hasExistingOtidAlias(aliasMap, canonical, nextOtid) {
|
|
|
451468
451595
|
return false;
|
|
451469
451596
|
}
|
|
451470
451597
|
function resolveAssistantLineId(b3, chunk) {
|
|
451471
|
-
const
|
|
451598
|
+
const messageId2 = typeof chunk.id === "string" ? chunk.id : undefined;
|
|
451472
451599
|
const otid = typeof chunk.otid === "string" ? chunk.otid : undefined;
|
|
451473
|
-
const canonicalFromMessageId =
|
|
451600
|
+
const canonicalFromMessageId = messageId2 ? b3.assistantCanonicalByMessageId.get(messageId2) : undefined;
|
|
451474
451601
|
const canonicalFromOtid = otid ? b3.assistantCanonicalByOtid.get(otid) : undefined;
|
|
451475
|
-
let canonical = canonicalFromMessageId || canonicalFromOtid ||
|
|
451602
|
+
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId2 || otid;
|
|
451476
451603
|
if (!canonical)
|
|
451477
451604
|
return;
|
|
451478
451605
|
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
@@ -451495,27 +451622,27 @@ function resolveAssistantLineId(b3, chunk) {
|
|
|
451495
451622
|
}
|
|
451496
451623
|
debugLog("accumulator", `Assistant id/otid alias conflict resolved to ${canonical}`);
|
|
451497
451624
|
}
|
|
451498
|
-
if (
|
|
451499
|
-
b3.assistantCanonicalByMessageId.set(
|
|
451625
|
+
if (messageId2) {
|
|
451626
|
+
b3.assistantCanonicalByMessageId.set(messageId2, canonical);
|
|
451500
451627
|
}
|
|
451501
451628
|
if (otid) {
|
|
451502
451629
|
b3.assistantCanonicalByOtid.set(otid, canonical);
|
|
451503
451630
|
}
|
|
451504
451631
|
const lineId = resolveLineIdForKind(b3, canonical, "assistant");
|
|
451505
451632
|
if (lineId !== canonical) {
|
|
451506
|
-
if (
|
|
451507
|
-
b3.assistantCanonicalByMessageId.set(
|
|
451633
|
+
if (messageId2)
|
|
451634
|
+
b3.assistantCanonicalByMessageId.set(messageId2, lineId);
|
|
451508
451635
|
if (otid)
|
|
451509
451636
|
b3.assistantCanonicalByOtid.set(otid, lineId);
|
|
451510
451637
|
}
|
|
451511
451638
|
return lineId;
|
|
451512
451639
|
}
|
|
451513
451640
|
function resolveReasoningLineId(b3, chunk) {
|
|
451514
|
-
const
|
|
451641
|
+
const messageId2 = typeof chunk.id === "string" ? chunk.id : undefined;
|
|
451515
451642
|
const otid = typeof chunk.otid === "string" ? chunk.otid : undefined;
|
|
451516
|
-
const canonicalFromMessageId =
|
|
451643
|
+
const canonicalFromMessageId = messageId2 ? b3.reasoningCanonicalByMessageId.get(messageId2) : undefined;
|
|
451517
451644
|
const canonicalFromOtid = otid ? b3.reasoningCanonicalByOtid.get(otid) : undefined;
|
|
451518
|
-
let canonical = canonicalFromMessageId || canonicalFromOtid ||
|
|
451645
|
+
let canonical = canonicalFromMessageId || canonicalFromOtid || messageId2 || otid;
|
|
451519
451646
|
if (!canonical)
|
|
451520
451647
|
return;
|
|
451521
451648
|
if (otid && !canonicalFromOtid && canonicalFromMessageId) {
|
|
@@ -451538,16 +451665,16 @@ function resolveReasoningLineId(b3, chunk) {
|
|
|
451538
451665
|
}
|
|
451539
451666
|
debugLog("accumulator", `Reasoning id/otid alias conflict resolved to ${canonical}`);
|
|
451540
451667
|
}
|
|
451541
|
-
if (
|
|
451542
|
-
b3.reasoningCanonicalByMessageId.set(
|
|
451668
|
+
if (messageId2) {
|
|
451669
|
+
b3.reasoningCanonicalByMessageId.set(messageId2, canonical);
|
|
451543
451670
|
}
|
|
451544
451671
|
if (otid) {
|
|
451545
451672
|
b3.reasoningCanonicalByOtid.set(otid, canonical);
|
|
451546
451673
|
}
|
|
451547
451674
|
const lineId = resolveLineIdForKind(b3, canonical, "reasoning");
|
|
451548
451675
|
if (lineId !== canonical) {
|
|
451549
|
-
if (
|
|
451550
|
-
b3.reasoningCanonicalByMessageId.set(
|
|
451676
|
+
if (messageId2)
|
|
451677
|
+
b3.reasoningCanonicalByMessageId.set(messageId2, lineId);
|
|
451551
451678
|
if (otid)
|
|
451552
451679
|
b3.reasoningCanonicalByOtid.set(otid, lineId);
|
|
451553
451680
|
}
|
|
@@ -451605,13 +451732,13 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451605
451732
|
}
|
|
451606
451733
|
handleOtidTransition(b3, id2);
|
|
451607
451734
|
const delta2 = chunk.reasoning;
|
|
451608
|
-
const
|
|
451735
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451609
451736
|
const line = ensure(b3, id2, () => ({
|
|
451610
451737
|
kind: "reasoning",
|
|
451611
451738
|
id: id2,
|
|
451612
451739
|
text: "",
|
|
451613
451740
|
phase: "streaming",
|
|
451614
|
-
messageId
|
|
451741
|
+
messageId: messageId2
|
|
451615
451742
|
}));
|
|
451616
451743
|
if (delta2) {
|
|
451617
451744
|
const newText = normalizeReasoningSectionBoundaries(line.text + delta2);
|
|
@@ -451620,11 +451747,11 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451620
451747
|
b3.byId.set(id2, {
|
|
451621
451748
|
...line,
|
|
451622
451749
|
text: newText,
|
|
451623
|
-
messageId:
|
|
451750
|
+
messageId: messageId2 ?? line.messageId
|
|
451624
451751
|
});
|
|
451625
451752
|
}
|
|
451626
|
-
} else if (
|
|
451627
|
-
b3.byId.set(id2, { ...line, messageId });
|
|
451753
|
+
} else if (messageId2 && line.messageId !== messageId2) {
|
|
451754
|
+
b3.byId.set(id2, { ...line, messageId: messageId2 });
|
|
451628
451755
|
}
|
|
451629
451756
|
break;
|
|
451630
451757
|
}
|
|
@@ -451635,13 +451762,13 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451635
451762
|
break;
|
|
451636
451763
|
handleOtidTransition(b3, id2);
|
|
451637
451764
|
const delta2 = extractTextPart(chunk.content);
|
|
451638
|
-
const
|
|
451765
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451639
451766
|
const line = ensure(b3, id2, () => ({
|
|
451640
451767
|
kind: "assistant",
|
|
451641
451768
|
id: id2,
|
|
451642
451769
|
text: "",
|
|
451643
451770
|
phase: "streaming",
|
|
451644
|
-
messageId
|
|
451771
|
+
messageId: messageId2
|
|
451645
451772
|
}));
|
|
451646
451773
|
if (delta2) {
|
|
451647
451774
|
const newText = line.text + delta2;
|
|
@@ -451650,20 +451777,20 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451650
451777
|
b3.byId.set(id2, {
|
|
451651
451778
|
...line,
|
|
451652
451779
|
text: newText,
|
|
451653
|
-
messageId:
|
|
451780
|
+
messageId: messageId2 ?? line.messageId
|
|
451654
451781
|
});
|
|
451655
451782
|
}
|
|
451656
|
-
} else if (
|
|
451657
|
-
b3.byId.set(id2, { ...line, messageId });
|
|
451783
|
+
} else if (messageId2 && line.messageId !== messageId2) {
|
|
451784
|
+
b3.byId.set(id2, { ...line, messageId: messageId2 });
|
|
451658
451785
|
}
|
|
451659
451786
|
break;
|
|
451660
451787
|
}
|
|
451661
451788
|
case "user_message": {
|
|
451662
451789
|
const chunkWithIds = chunk;
|
|
451663
|
-
const
|
|
451790
|
+
const messageId2 = typeof chunkWithIds.id === "string" ? chunkWithIds.id : undefined;
|
|
451664
451791
|
const otid = typeof chunkWithIds.otid === "string" ? chunkWithIds.otid : undefined;
|
|
451665
451792
|
const mappedLineId = otid ? b3.userLineIdByOtid.get(otid) : undefined;
|
|
451666
|
-
const lineId = mappedLineId || otid ||
|
|
451793
|
+
const lineId = mappedLineId || otid || messageId2;
|
|
451667
451794
|
if (!lineId)
|
|
451668
451795
|
break;
|
|
451669
451796
|
handleOtidTransition(b3, lineId);
|
|
@@ -451687,14 +451814,14 @@ function onChunk(b3, chunk, ctx) {
|
|
|
451687
451814
|
kind: "user",
|
|
451688
451815
|
id: lineId,
|
|
451689
451816
|
text: rawText,
|
|
451690
|
-
messageId,
|
|
451817
|
+
messageId: messageId2,
|
|
451691
451818
|
otid
|
|
451692
451819
|
}));
|
|
451693
451820
|
if (line.kind === "user") {
|
|
451694
451821
|
b3.byId.set(lineId, {
|
|
451695
451822
|
...line,
|
|
451696
451823
|
text: line.text || rawText,
|
|
451697
|
-
messageId:
|
|
451824
|
+
messageId: messageId2 ?? line.messageId,
|
|
451698
451825
|
otid: otid ?? line.otid
|
|
451699
451826
|
});
|
|
451700
451827
|
}
|
|
@@ -499514,6 +499641,8 @@ function ModelSelector({
|
|
|
499514
499641
|
const [byokProviderAliases, setByokProviderAliases] = import_react91.useState(() => buildByokProviderAliases([]));
|
|
499515
499642
|
const [openAICompatibleProxyHandles, setOpenAICompatibleProxyHandles] = import_react91.useState(() => getCachedOpenAICompatibleProxyHandles() ?? new Set);
|
|
499516
499643
|
const [openAICompatibleProxyProviders, setOpenAICompatibleProxyProviders] = import_react91.useState(new Set);
|
|
499644
|
+
const providerRegistryRevision = import_react91.useSyncExternalStore(subscribePiProviderRegistry, getPiProviderRegistryRevision, getPiProviderRegistryRevision);
|
|
499645
|
+
const previousProviderRegistryRevision = import_react91.useRef(providerRegistryRevision);
|
|
499517
499646
|
const mountedRef = import_react91.useRef(true);
|
|
499518
499647
|
import_react91.useEffect(() => {
|
|
499519
499648
|
mountedRef.current = true;
|
|
@@ -499576,8 +499705,12 @@ function ModelSelector({
|
|
|
499576
499705
|
}
|
|
499577
499706
|
});
|
|
499578
499707
|
import_react91.useEffect(() => {
|
|
499708
|
+
if (previousProviderRegistryRevision.current !== providerRegistryRevision) {
|
|
499709
|
+
previousProviderRegistryRevision.current = providerRegistryRevision;
|
|
499710
|
+
clearAvailableModelsCache();
|
|
499711
|
+
}
|
|
499579
499712
|
loadModels.current(forceRefreshOnMount ?? false);
|
|
499580
|
-
}, [forceRefreshOnMount]);
|
|
499713
|
+
}, [forceRefreshOnMount, providerRegistryRevision]);
|
|
499581
499714
|
import_react91.useEffect(() => {
|
|
499582
499715
|
if (localModelCatalog) {
|
|
499583
499716
|
setByokProviderAliases(buildByokProviderAliases([]));
|
|
@@ -500263,6 +500396,7 @@ var init_ModelSelector = __esm(async () => {
|
|
|
500263
500396
|
init_available_models();
|
|
500264
500397
|
init_model();
|
|
500265
500398
|
init_remote_model_catalog();
|
|
500399
|
+
init_pi_provider_mod_registry();
|
|
500266
500400
|
init_byok_providers();
|
|
500267
500401
|
init_settings_manager();
|
|
500268
500402
|
init_colors();
|
|
@@ -500549,8 +500683,9 @@ function ProviderSelector({
|
|
|
500549
500683
|
const [awsProfiles, setAwsProfiles] = import_react94.useState([]);
|
|
500550
500684
|
const [profileIndex, setProfileIndex] = import_react94.useState(0);
|
|
500551
500685
|
const [isLoadingProfiles, setIsLoadingProfiles] = import_react94.useState(false);
|
|
500552
|
-
|
|
500553
|
-
const
|
|
500686
|
+
import_react94.useSyncExternalStore(subscribePiProviderRegistry, getPiProviderRegistryRevision, getPiProviderRegistryRevision);
|
|
500687
|
+
const providers = getProviderConfigs(selectedTarget);
|
|
500688
|
+
const filteredProviders = filterProviderConfigs(providers, searchQuery);
|
|
500554
500689
|
const showProviderStoreTabs = shouldShowProviderStoreTabs(hasCloudCredentials2);
|
|
500555
500690
|
const connectedProviders = import_react94.useMemo(() => connectedProvidersByTarget[selectedTarget] ?? new Map, [connectedProvidersByTarget, selectedTarget]);
|
|
500556
500691
|
const isLoading = isProviderTargetLoading({
|
|
@@ -501824,6 +501959,7 @@ function ProviderSelector({
|
|
|
501824
501959
|
var import_react94, jsx_dev_runtime70, SOLID_LINE17 = "─", VISIBLE_PROVIDERS = 8;
|
|
501825
501960
|
var init_ProviderSelector = __esm(async () => {
|
|
501826
501961
|
init_available_models();
|
|
501962
|
+
init_pi_provider_mod_registry();
|
|
501827
501963
|
init_use_terminal_width();
|
|
501828
501964
|
init_byok_providers();
|
|
501829
501965
|
init_chatgpt_usage_service();
|
|
@@ -541297,4 +541433,4 @@ function registerBunOAuthFlows() {
|
|
|
541297
541433
|
registerBunOAuthFlows();
|
|
541298
541434
|
await init_src5().then(() => exports_src2);
|
|
541299
541435
|
|
|
541300
|
-
//# debugId=
|
|
541436
|
+
//# debugId=EDD0BAA906B8C7B064756E2164756E21
|