UNPKG

@gguf/claw

Version:

Multi-channel AI gateway with extensible messaging integrations

924 lines (910 loc) 2.67 MB
import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js"; import { _ as isSubagentSessionKey, c as normalizeAccountId$3, d as resolveAgentIdFromSessionKey, f as resolveThreadSessionKeys, g as isCronSessionKey, h as isAcpSessionKey, i as buildAgentMainSessionKey, l as normalizeAgentId, m as getSubagentDepth, n as DEFAULT_AGENT_ID, p as sanitizeAgentId, s as classifySessionKeyShape, t as DEFAULT_ACCOUNT_ID$1, u as normalizeMainKey, v as parseAgentSessionKey, y as resolveThreadParentSessionKey } from "./session-key-9yEYlIQe.js"; import { c as logoutWeb, f as readWebSelfId, g as webAuthExists, o as getWebAuthAgeMs, r as resolveWhatsAppAccount, s as logWebSelfId } from "./accounts-Dy3mxoHH.js"; import { B as danger, C as formatTerminalLink, D as normalizeE164, F as sleep$1, G as setVerbose, I as sliceUtf16Safe, J as warn, K as shouldLogVerbose, N as shortenHomeInString, P as shortenHomePath, Q as getChildLogger, R as truncateUtf16Safe, S as escapeRegExp, U as logVerbose, X as isRich, Y as colorize, Z as theme, _ as CONFIG_DIR, a as normalizeAnyChannelId, at as normalizeLogLevel, ct as createInternalHookEvent, d as createPluginRegistry, f as clearPluginCommands, g as matchPluginCommand, h as listPluginCommands, j as resolveUserPath, l as requireActivePluginRegistry, lt as triggerInternalHook, m as getPluginCommandSpecs, n as CHAT_CHANNEL_ORDER, o as normalizeChannelId, p as executePluginCommand, r as DEFAULT_CHAT_CHANNEL, st as resolvePreferredOpenClawTmpDir, u as setActivePluginRegistry, ut as normalizePluginHttpPath, w as isRecord$1, x as ensureDir$3, y as clampInt, z as isPlainObject } from "./registry-C8pj8ctW.js"; import { c as expandHomePrefix, i as resolveGatewayPort, n as resolveConfigPath, s as resolveStateDir, t as STATE_DIR, u as resolveRequiredHomeDir } from "./paths-DJmOcr7Q.js"; import { A as getSoonestCooldownExpiry, B as resolveOpenClawAgentDir, C as getCustomProviderApiKey, D as resolveModelAuthMode, E as resolveEnvApiKey, F as dedupeProfileIds, G as DEFAULT_PROVIDER, H as resolveAuthProfileDisplayLabel, I as listProfilesForProvider, J as resolveShellEnvFallbackTimeoutMs, K as getShellPathFromLoginShell, L as markAuthProfileGood, M as markAuthProfileFailure, N as markAuthProfileUsed, P as resolveApiKeyForProfile, Q as withFileLock, R as ensureAuthProfileStore, S as getApiKeyForModel, T as resolveApiKeyForProvider, U as DEFAULT_CONTEXT_TOKENS, V as normalizeSecretInput, W as DEFAULT_MODEL, a as isCliProvider, b as OLLAMA_NATIVE_BASE_URL, c as normalizeProviderId, d as resolveDefaultModelForAgent, f as resolveModelRefFromString, i as findNormalizedProviderValue, j as isProfileInCooldown, k as resolveAuthProfileOrder, m as resolveThinkingDefault, n as buildConfiguredAllowlistKeys, o as modelKey, p as resolveSubagentSpawnModelSelection, r as buildModelAliasIndex, s as normalizeModelRef$2, t as buildAllowedModelSet, u as resolveConfiguredModelRef, w as requireApiKey, x as createOllamaStreamFn, z as resolveAuthStorePathForDisplay } from "./model-selection-DQIwoYb8.js"; import { B as isSafeExecutableValue, H as TELEGRAM_COMMAND_NAME_PATTERN, J as resolveIMessageAttachmentRoots, K as isInboundPathAllowed, U as normalizeTelegramCommandName, V as parseDurationMs, W as resolveTelegramCustomCommands, X as normalizeScpRemoteHost, Y as resolveIMessageRemoteAttachmentRoots, _ as resolveAgentMaxConcurrent, a as writeConfigFile, c as validateJsonSchemaValue, d as setConfigOverride, f as unsetConfigOverride, g as unsetConfigValueAtPath, h as setConfigValueAtPath, i as resolveConfigSnapshotHash, l as getConfigOverrides, m as parseConfigPath, n as loadConfig, o as validateConfigObjectWithPlugins, p as getConfigValueAtPath, r as readConfigFileSnapshot, u as resetConfigOverrides, v as VERSION } from "./config-DA0pxYcO.js"; import { a as formatIMessageChatTarget, c as parseIMessageTarget, i as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS, o as isAllowedIMessageSender, r as createIMessageRpcClient, s as normalizeIMessageHandle, t as sendMessageIMessage } from "./send-BEpJBywc.js"; import { d as detectMime, f as extensionForMime, g as isGifMedia, h as isAudioFileName, m as imageMimeFromFormat, s as getImageMetadata, u as resizeToJpeg, x as mediaKindFromMime, y as MAX_IMAGE_BYTES } from "./fs-safe-CGcLaY9D.js"; import { a as clearActiveProgressLine, i as defaultRuntime, o as registerActiveProgressLine, r as createNonExitingRuntime, s as unregisterActiveProgressLine, t as createSubsystemLogger } from "./subsystem-BfLMZ8kW.js"; import { A as logError, C as resolveOpenClawPackageRoot, D as runExec, E as runCommandWithTimeout, M as logWarn, O as spawnWithFallback, S as loadWorkspaceBootstrapFiles, a as resolveAgentModelPrimary, b as ensureAgentWorkspace, c as resolveDefaultAgentId, d as resolveSessionAgentIds, i as resolveAgentModelFallbacksOverride, j as logInfo, k as logDebug, l as resolveEffectiveModelFallbacks, m as DEFAULT_BOOTSTRAP_FILENAME, n as resolveAgentConfig, o as resolveAgentSkillsFilter, p as DEFAULT_AGENT_WORKSPACE_DIR, r as resolveAgentDir, s as resolveAgentWorkspaceDir, t as listAgentIds, u as resolveSessionAgentId, x as filterBootstrapFilesForSession } from "./agent-scope-OWMdRegz.js"; import { a as parseAvailableTags, c as readStringArrayParam, h as resolveImageSanitizationLimits, i as jsonResult, l as readStringOrNumberParam, m as sanitizeToolResultImages, n as imageResult, o as readNumberParam, p as sanitizeImageBlocks, r as imageResultFromFile, s as readReactionParams, t as createActionGate, u as readStringParam } from "./common-CCPGi5xr.js"; import { a as createSlackWebClient, c as validateSlackBlocksArray, i as buildSlackBlocksFallbackText, o as resolveSlackWebClientOptions, s as parseSlackBlocksInput, t as sendMessageSlack } from "./send-DyFx4sCR.js"; import { a as chunkText, c as resolveChunkMode, d as isSafeFenceBreak, f as parseFenceSpans, i as chunkMarkdownTextWithMode, l as resolveTextChunkLimit, o as chunkTextWithMode, r as chunkMarkdownText, t as chunkByNewline, u as findFenceSpanAt } from "./chunk-C9J4kyVw.js"; import { $ as parseTelegramTarget, A as hasBotMention, B as resolveSenderAllowMatch, C as buildTelegramGroupPeerId, D as describeReplyTarget, E as buildTypingThreadParams, F as resolveTelegramReplyId, G as readChannelAllowFromStore, H as isSenderIdAllowed, I as resolveTelegramStreamMode, J as upsertChannelPairingRequest, L as resolveTelegramThreadSpec, M as resolveTelegramForumThreadId, N as resolveTelegramGroupAllowFromContext, O as expandTextLinks, P as resolveTelegramMediaPlaceholder, Q as isVoiceCompatibleAudio, R as isSenderAllowed$1, S as buildTelegramGroupFrom, T as buildTelegramThreadParams, U as mergeAllowFromSources, V as firstDefined$1, W as addChannelAllowFromStoreEntry, X as listPairingChannels, Y as getPairingAdapter, Z as withTelegramApiErrorLogging, _ as resolveTelegramFetch, a as reactMessageTelegram, b as buildSenderLabel, c as sendStickerTelegram, d as wasSentByBot, et as resolveTelegramTargetChatType, f as isRecoverableTelegramNetworkError, g as wrapFileReferencesInHtml, h as renderTelegramHtmlText, i as editMessageTelegram, j as normalizeForwardedContext, k as extractTelegramLocation, m as markdownToTelegramHtml, n as createForumTopicTelegram, nt as toLocationContext, o as sendMessageTelegram, p as markdownToTelegramChunks, q as removeChannelAllowFromStoreEntry, r as deleteMessageTelegram, s as sendPollTelegram, t as buildInlineKeyboard, tt as formatLocationText, u as resolveTelegramVoiceSend, v as splitTelegramCaption, w as buildTelegramParentPeer, x as buildSenderName, y as buildGroupLabel, z as normalizeAllowFromWithStore$1 } from "./send-CxkhX9l7.js"; import { _ as CLI_OUTPUT_MAX_BUFFER, a as resolveMediaAttachmentLocalRoots, c as loadModelCatalog, d as resolveAttachmentKind, f as registerUnhandledRejectionHandler, g as resolveMediaUnderstandingScope, h as normalizeMediaUnderstandingChatType, i as resolveAutoImageModel, l as modelSupportsVision, m as resolveTimeoutMs$1, n as createMediaAttachmentCache, o as runCapability, p as resolveConcurrency, r as normalizeMediaAttachments, s as findModelInCatalog, t as buildProviderRegistry, v as applyTemplate, y as buildRandomTempFilePath } from "./runner-DIcTJgbP.js"; import { a as resolveAckReaction, i as resolveResponsePrefixTemplate, n as createReplyPrefixOptions, o as resolveEffectiveMessagesConfig, s as resolveHumanDelayConfig } from "./reply-prefix-YUOHz1rF.js"; import { n as SILENT_REPLY_TOKEN, r as isSilentReplyText, t as HEARTBEAT_TOKEN } from "./tokens-D1LxPszt.js"; import { c as getSkillsSnapshotVersion, d as resolvePairingPaths, f as createAsyncLock, i as resolveSkillCommandInvocation, l as generatePairingToken, m as writeJsonAtomic, n as listSkillCommandsForAgents, o as getRemoteSkillEligibility, p as readJsonFile, r as listSkillCommandsForWorkspace, s as ensureSkillsWatcher, t as listReservedChatSlashCommandNames, u as pruneExpiredPending } from "./skill-commands-BpaH_zzk.js"; import { c as assertSandboxPath, d as resolveSandboxedMediaSource, f as applySkillEnvOverrides, i as resolveSkillsPromptForRun, l as resolveSandboxInputPath, n as buildWorkspaceSkillSnapshot, p as applySkillEnvOverridesFromSnapshot, r as loadWorkspaceSkillEntries, s as assertMediaNotDataUrl } from "./skills-OZUqNHBX.js"; import { n as formatErrorMessage, r as formatUncaughtError } from "./errors-Bv8oZiTO.js"; import { n as fetchWithTimeout, t as bindAbortRelay } from "./fetch-timeout-BKZjgek-.js"; import { a as isBlockedHostnameOrIp, c as normalizeHostname, t as SsrFBlockedError } from "./ssrf-DxmqkHJJ.js"; import { a as readResponseWithLimit, i as fetchRemoteMedia, n as getDefaultMediaLocalRoots, o as fetchWithSsrFGuard, t as getAgentScopedMediaLocalRoots } from "./local-roots-jpNoUngc.js"; import { M as isSecureWebSocketUrl, N as rawDataToString, T as DEFAULT_AI_SNAPSHOT_MAX_CHARS, x as ensureChromeExtensionRelayServer } from "./chrome-32CP7Tm2.js"; import { i as parseBooleanValue$1, n as resolveCliName, r as isTruthyEnvValue, t as formatCliCommand } from "./command-format-sreXrOOr.js"; import { A as normalizeHyphenSlug, F as resolveChannelGroupRequireMention, I as resolveChannelGroupToolsPolicy, M as normalizeStringEntriesLower, P as resolveChannelGroupPolicy, a as normalizeReasoningLevel, c as normalizeVerboseLevel, d as getChannelDock, f as listChannelDocks, i as normalizeElevatedLevel, j as normalizeStringEntries, k as normalizeAtHashSlug, l as resolveResponseUsageMode, m as normalizeSignalMessagingTarget, n as formatXHighModelHint, o as normalizeThinkLevel, s as normalizeUsageDisplay, t as formatThinkingLevels, u as supportsXHighThinking } from "./thinking-DFXDZFyu.js"; import { a as listTelegramAccountIds, b as resolveDiscordAccount, c as resolveTelegramToken, f as resolveSlackAccount, g as createDiscordActionGate, h as resolveSlackBotToken, i as listEnabledTelegramAccounts, m as resolveSlackAppToken, n as normalizeWhatsAppTarget, r as createTelegramActionGate, s as resolveTelegramAccount, t as isWhatsAppGroupJid, v as listEnabledDiscordAccounts, x as normalizeDiscordToken } from "./normalize-D9b0GOOm.js"; import { r as resolveIMessageAccount } from "./accounts-mzh94Dc2.js"; import { i as resolveSignalAccount, t as listEnabledSignalAccounts } from "./accounts-Bkix50Fs.js"; import { t as normalizeChatType } from "./chat-type-B5__aQIT.js"; import { h as resolveSlackChannelId, m as parseSlackTarget, n as listChannelPlugins, r as normalizeChannelId$1, t as getChannelPlugin } from "./plugins-BpKonLQ1.js"; import { $ as resolveDiscordChannelId, A as addRoleDiscord, B as removeRoleDiscord, C as fetchMessageDiscord, Ct as applyChannelMatchMeta, D as readMessagesDiscord, Dt as resolveChannelEntryMatchWithFallback, E as pinMessageDiscord, F as fetchRoleInfoDiscord, G as createChannelDiscord, H as listGuildEmojisDiscord, I as fetchVoiceStatusDiscord, J as moveChannelDiscord, K as deleteChannelDiscord, L as kickMemberDiscord, M as createScheduledEventDiscord, N as fetchChannelInfoDiscord, O as searchMessagesDiscord, P as fetchMemberInfoDiscord, Q as parseDiscordTarget, R as listGuildChannelsDiscord, S as editMessageDiscord, St as chunkDiscordTextWithMode, T as listThreadsDiscord, Tt as normalizeChannelSlug, U as uploadEmojiDiscord, V as timeoutMemberDiscord, W as uploadStickerDiscord, X as setChannelPermissionDiscord, Y as removeChannelPermissionDiscord, Z as stripUndefinedFields, _ as sendPollDiscord, _t as resolveTimestampMs, a as removeReactionDiscord, at as normalizeDiscordSlug, b as createThreadDiscord, bt as hasAnyGuildPermissionDiscord, c as formatDiscordComponentEventText, ct as resolveDiscordGuildEntry, d as parseDiscordModalCustomId, dt as resolveDiscordShouldRequireMention, et as listDiscordDirectoryGroupsLive, f as parseDiscordModalCustomIdForCarbon, ft as resolveGroupDmAllow, g as sendMessageDiscord, gt as resolveDiscordSystemLocation, h as resolveDiscordModalEntry, ht as formatDiscordUserTag, i as removeOwnReactionsDiscord, it as normalizeDiscordAllowList, j as banMemberDiscord, k as unpinMessageDiscord, l as parseDiscordComponentCustomId, lt as resolveDiscordMemberAccessState, m as resolveDiscordComponentEntry, mt as formatDiscordReactionEmoji, n as fetchReactionsDiscord, nt as allowListMatches$1, o as sendDiscordComponentMessage, ot as resolveDiscordAllowListMatch, p as readDiscordComponentSpec, pt as shouldEmitDiscordReactionNotification, q as editChannelDiscord, r as reactMessageDiscord, rt as isDiscordGroupAllowedByPolicy, s as createDiscordFormModal, st as resolveDiscordChannelConfigWithFallback, tt as listDiscordDirectoryPeersLive, u as parseDiscordComponentCustomIdForCarbon, ut as resolveDiscordOwnerAllowFrom, v as sendStickerDiscord, vt as fetchDiscord, w as listPinsDiscord, wt as buildChannelKeyCandidates, x as deleteMessageDiscord, xt as createDiscordClient, y as sendVoiceMessageDiscord, yt as fetchChannelPermissionsDiscord, z as listScheduledEventsDiscord } from "./send-DwpvvHgk.js"; import { C as getGlobalHookRunner, S as throwIfAborted, _ as normalizeTargetForProvider, a as normalizeOutboundPayloadsForJson, b as splitMediaFromOutput, c as applyReplyThreading, d as isRenderablePayload, f as shouldSuppressMessagingToolReplies, g as normalizeChannelTargetInput, h as buildTargetResolverSignature, i as normalizeOutboundPayloads, l as filterMessagingToolDuplicates, m as resolveReplyToMode, o as normalizeReplyPayloadsForDelivery, p as createReplyToModeFilterForChannel, r as formatOutboundPayloadLog, s as applyReplyTagsToPayload, t as deliverOutboundPayloads, u as filterMessagingToolMediaDuplicates, v as parseReplyDirectives, w as initializeGlobalHookRunner, x as parseInlineDirectives$1, y as MEDIA_TOKEN_RE } from "./deliver-Dn83X5NP.js"; import { a as isMarkdownCapableMessageChannel, c as resolveGatewayMessageChannel, d as GATEWAY_CLIENT_MODES, f as GATEWAY_CLIENT_NAMES, i as isInternalMessageChannel, l as resolveMessageChannel, n as isDeliverableMessageChannel, o as listDeliverableMessageChannels, r as isGatewayMessageChannel, s as normalizeMessageChannel, t as INTERNAL_MESSAGE_CHANNEL, u as GATEWAY_CLIENT_IDS } from "./message-channel-C3OrO29D.js"; import { $ as normalizeToolName, A as isTransientHttpError, At as INPUT_PROVENANCE_KIND_VALUES, B as resolveProfile, Bt as resolveSessionResetType, C as isContextOverflowError, Ct as normalizeDeliveryContext, D as isRateLimitAssistantError, Dt as capArrayByJsonBytes, E as isLikelyContextOverflowError, Et as archiveSessionTranscripts, F as resolveSandboxContext, Ft as resolveSessionLockMaxHoldFromTimeout, G as resolveBrowserControlAuth, Gt as resolveExplicitAgentSessionKey, H as resolveExistingPathsWithinRoot, Ht as DEFAULT_RESET_TRIGGERS, I as resolveSandboxRuntimeStatus, It as resolveSessionKey, J as buildPluginToolGroups, Jt as resolveGroupSessionKey, K as resolveSandboxConfigForAgent, Kt as resolveMainSessionKey, L as createBrowserRouteContext, Lt as evaluateSessionFreshness, M as parseImageSizeError, Mt as hasInterSessionUserProvenance, N as sanitizeUserFacingText, Nt as normalizeInputProvenance, O as isRawApiErrorPayload, Ot as countToolResults, P as ensureSandboxWorkspaceForSession, Pt as acquireSessionWriteLock, Q as mergeAlsoAllowPolicy, R as registerBrowserRoutes, Rt as resolveChannelResetConfig, S as isCompactionFailureError, St as mergeDeliveryContext, T as isFailoverErrorMessage, Tt as normalizeAccountId$4, U as getBridgeAuthForPort, Ut as resolveFreshSessionTotalTokens, V as DEFAULT_UPLOAD_DIR, Vt as resolveThreadFlag, W as ensureBrowserControlAuth, Wt as canonicalizeMainSessionAlias, X as expandPolicyWithPluginGroups, Y as collectExplicitAllowlist, Z as expandToolGroups, _ as formatRawAssistantErrorForUi, _t as updateSessionStoreEntry, a as isMessagingToolDuplicateNormalized, at as ensureSessionHeader, b as isBillingAssistantError, bt as deliveryContextFromSession, c as extractToolCallsFromAssistant, ct as sanitizeGoogleTurnOrdering, d as isAntigravityClaude, et as resolveToolProfilePolicy, f as isGoogleModelApi, ft as loadSessionStore, g as formatBillingErrorMessage, gt as updateSessionStore, h as formatAssistantErrorText, ht as updateLastRoute, it as buildBootstrapContextFiles, j as parseImageDimensionError, jt as applyInputProvenanceToUserMessage, k as isTimeoutErrorMessage, kt as extractToolCallNames, l as extractToolResultId, lt as extractDeliveryInfo, m as classifyFailoverReason, mt as recordSessionMetaFromInbound, n as validateGeminiTurns, nt as compileGlobPatterns, o as normalizeTextForComparison, ot as resolveBootstrapMaxChars, p as BILLING_ERROR_USER_MESSAGE, pt as readSessionUpdatedAt, q as applyOwnerOnlyToolPolicy, qt as deriveSessionMetaPatch, r as pickFallbackThinkingLevel, rt as matchesAnyGlobPattern, s as sanitizeSessionMessagesImages, st as resolveBootstrapTotalMaxChars, t as validateAnthropicTurns, tt as stripPluginOnlyAllowlist, u as downgradeOpenAIReasoningBlocks, ut as appendAssistantMessageToSessionTranscript, v as getApiErrorPayloadFingerprint, vt as isCacheEnabled, w as isFailoverAssistantError, wt as normalizeSessionDeliveryFields, x as isCloudCodeAssistFormatError, xt as deliveryContextKey, y as isAuthAssistantError, yt as resolveCacheTtlMs$1, z as resolveBrowserConfig, zt as resolveSessionResetPolicy } from "./pi-embedded-helpers-Caj23g0W.js"; import { n as resolveConversationLabel } from "./conversation-label-2FLz1ei_.js"; import { a as saveJsonFile, i as loadJsonFile } from "./github-copilot-token-etmIcdko.js"; import { c as normalizePluginsConfig, f as isPathInsideWithRealpath, i as safeStatSync, l as resolveEnableState, n as discoverOpenClawPlugins, r as isPathInside, s as applyTestPluginDefaults, t as loadPluginManifestRegistry, u as resolveMemorySlotDecision } from "./manifest-registry-Lzj-fZNH.js"; import { i as resolveSessionTranscriptPath, n as resolveSessionFilePath, o as resolveSessionTranscriptsDirForAgent, r as resolveSessionFilePathOptions, s as resolveStorePath, t as resolveDefaultSessionStorePath } from "./paths-a1ZEI8nz.js"; import { t as emitSessionTranscriptUpdate } from "./transcript-events-Cj85Mq0h.js"; import { a as logMessageProcessed, c as logWebhookError, d as startDiagnosticHeartbeat, f as stopDiagnosticHeartbeat, i as logLaneEnqueue, l as logWebhookProcessed, m as isDiagnosticsEnabled, o as logMessageQueued, p as emitDiagnosticEvent, r as logLaneDequeue, s as logSessionStateChange, t as diag, u as logWebhookReceived } from "./diagnostic-oBxO5N68.js"; import { i as saveMediaBuffer, r as getMediaDir } from "./store-BJRhX9Bi.js"; import { n as normalizePollInput } from "./polls-dTqdfZ_K.js"; import { a as loadWebMedia, i as getDefaultLocalRoots } from "./ir-JSGKj1e6.js"; import { n as retryAsync } from "./retry-B8Oq5mgi.js"; import { n as recordChannelActivity, r as createDiscordRetryRunner, t as getChannelActivity } from "./channel-activity-DHI8R5Xg.js"; import { n as wrapFetchWithAbortSignal, t as resolveFetch } from "./fetch-B79-NBmS.js"; import { n as resolveMarkdownTableMode } from "./markdown-tables-Cf5RtnFi.js"; import { t as convertMarkdownTables } from "./tables-D5aPNTF6.js"; import { r as normalizeInboundTextNewlines, t as finalizeInboundContext } from "./inbound-context-hgCIam0H.js"; import { S as minimaxUnderstandImage, _ as stripThinkingTagsFromText, a as decodeDataUrl, b as extractTextFromChatContent, c as extractAssistantThinking, d as formatReasoningMessage, f as inferToolMetaFromArgs, g as stripMinimaxToolCallXml, h as stripDowngradedToolCallText, i as coerceImageModelConfig, l as extractThinkingFromTaggedStream, m as promoteThinkingTagsToBlocks, o as resolveProviderVisionModelFromConfig, p as isAssistantMessage, r as coerceImageAssistantText, s as extractAssistantText$1, u as extractThinkingFromTaggedText, v as resolveToolDisplay, x as ensureOpenClawModelsJson, y as stripReasoningTagsFromText } from "./image-B6uzdadC.js"; import { n as discoverModels, t as discoverAuthStorage } from "./pi-model-discovery-3Y4hcIsw.js"; import { d as listMemoryFiles, f as normalizeExtraMemoryPaths, v as runTasksWithConcurrency } from "./sqlite-Yn48izJ_.js"; import { r as getDiagnosticSessionState } from "./diagnostic-session-state-BW5KRYN1.js"; import { n as resolveMemorySearchConfig } from "./manager-iI-4K8tc.js"; import { a as listChatCommandsForConfig, c as normalizeCommandBody, d as resolveCommandArgMenu, f as serializeCommandArgs, i as listChatCommands, l as parseCommandArgs, o as listNativeCommandSpecs, p as shouldHandleTextCommands, r as findCommandByNativeName, s as listNativeCommandSpecsForConfig, t as buildCommandTextFromArgs, u as resolveCommandArgChoices } from "./commands-registry-zf_cMU77.js"; import { c as signalRpcRequest, l as streamSignalEvents, n as sendReadReceiptSignal, o as resolveSignalRpcContext, r as sendTypingSignal, s as signalCheck, t as sendMessageSignal } from "./send-BqnSueAq.js"; import { t as makeProxyFetch } from "./proxy-BwzmpJWq.js"; import { n as resolveAgentRoute, t as buildAgentSessionKey } from "./resolve-route-DudlMKs4.js"; import { a as createReplyReferencePlanner, i as resolveSlackThreadTs, n as deliverReplies$3, t as createSlackReplyDeliveryPlan } from "./replies-CH9sggoc.js"; import { t as getActiveWebListener } from "./active-listener-RPIOZo7v.js"; import { n as recordCommandPoll, r as resetCommandPollCount } from "./command-poll-backoff-NAePk3eL.js"; import { createRequire } from "node:module"; import * as path$1 from "node:path"; import path from "node:path"; import fs, { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs"; import os, { homedir } from "node:os"; import JSON5 from "json5"; import * as fs$2 from "node:fs/promises"; import fs$1 from "node:fs/promises"; import { inspect, promisify } from "node:util"; import { execFile, execFileSync, spawn, spawnSync } from "node:child_process"; import crypto, { X509Certificate, randomBytes, randomUUID } from "node:crypto"; import { fileURLToPath } from "node:url"; import { ProxyAgent, fetch as fetch$1 } from "undici"; import { Buffer as Buffer$1 } from "node:buffer"; import { complete, completeSimple, streamSimple } from "@mariozechner/pi-ai"; import AjvPkg from "ajv"; import { CURRENT_SESSION_VERSION, DefaultResourceLoader, SessionManager, SettingsManager, codingTools, createAgentSession, createEditTool, createReadTool, createWriteTool, estimateTokens, generateSummary, readTool } from "@mariozechner/pi-coding-agent"; import { Type } from "@sinclair/typebox"; import { createServer } from "node:http"; import { ApplicationCommandOptionType, ButtonStyle, ChannelType, PermissionFlagsBits, Routes, StickerFormatType } from "discord-api-types/v10"; import { Button, ChannelSelectMenu, ChannelType as ChannelType$1, Client, Command, CommandWithSubcommands, Container, MentionableSelectMenu, MessageCreateListener, MessageReactionAddListener, MessageReactionRemoveListener, MessageType, Modal, PresenceUpdateListener, ReadyListener, RoleSelectMenu, Row, Separator, StringSelectMenu, TextDisplay, UserSelectMenu, serializePayload } from "@buape/carbon"; import { spinner } from "@clack/prompts"; import WebSocket, { WebSocket as WebSocket$1 } from "ws"; import { EdgeTTS } from "node-edge-tts"; import { createJiti } from "jiti"; import readline from "node:readline"; import { API_CONSTANTS, Bot, GrammyError, InputFile, webhookCallback } from "grammy"; import { createOscProgressController, supportsOscProgress } from "osc-progress"; import { GatewayCloseCodes, GatewayIntents, GatewayPlugin } from "@buape/carbon/gateway"; import { VoicePlugin } from "@buape/carbon/voice"; import { AudioPlayerStatus, EndBehaviorType, VoiceConnectionStatus, createAudioPlayer, createAudioResource, entersState, joinVoiceChannel } from "@discordjs/voice"; import { HttpsProxyAgent } from "https-proxy-agent"; import { setTimeout as setTimeout$1 } from "node:timers/promises"; import { messagingApi } from "@line/bot-sdk"; import SlackBolt from "@slack/bolt"; import { run, sequentialize } from "@grammyjs/runner"; import { apiThrottler } from "@grammyjs/transformer-throttler"; import { EventEmitter } from "node:events"; //#region src/channels/plugins/message-action-names.ts const CHANNEL_MESSAGE_ACTION_NAMES = [ "send", "broadcast", "poll", "react", "reactions", "read", "edit", "unsend", "reply", "sendWithEffect", "renameGroup", "setGroupIcon", "addParticipant", "removeParticipant", "leaveGroup", "sendAttachment", "delete", "pin", "unpin", "list-pins", "permissions", "thread-create", "thread-list", "thread-reply", "search", "sticker", "sticker-search", "member-info", "role-info", "emoji-list", "emoji-upload", "sticker-upload", "role-add", "role-remove", "channel-info", "channel-list", "channel-create", "channel-edit", "channel-delete", "channel-move", "category-create", "category-edit", "category-delete", "topic-create", "voice-status", "event-list", "event-create", "timeout", "kick", "ban", "set-presence" ]; //#endregion //#region src/channels/plugins/bluebubbles-actions.ts const BLUEBUBBLES_ACTIONS = { react: { gate: "reactions" }, edit: { gate: "edit", unsupportedOnMacOS26: true }, unsend: { gate: "unsend" }, reply: { gate: "reply" }, sendWithEffect: { gate: "sendWithEffect" }, renameGroup: { gate: "renameGroup", groupOnly: true }, setGroupIcon: { gate: "setGroupIcon", groupOnly: true }, addParticipant: { gate: "addParticipant", groupOnly: true }, removeParticipant: { gate: "removeParticipant", groupOnly: true }, leaveGroup: { gate: "leaveGroup", groupOnly: true }, sendAttachment: { gate: "sendAttachment" } }; const BLUEBUBBLES_ACTION_SPECS = BLUEBUBBLES_ACTIONS; const BLUEBUBBLES_ACTION_NAMES = Object.keys(BLUEBUBBLES_ACTIONS); const BLUEBUBBLES_GROUP_ACTIONS = new Set(BLUEBUBBLES_ACTION_NAMES.filter((action) => BLUEBUBBLES_ACTION_SPECS[action]?.groupOnly)); //#endregion //#region src/plugins/http-registry.ts function registerPluginHttpRoute(params) { const registry = params.registry ?? requireActivePluginRegistry(); const routes = registry.httpRoutes ?? []; registry.httpRoutes = routes; const normalizedPath = normalizePluginHttpPath(params.path, params.fallbackPath); const suffix = params.accountId ? ` for account "${params.accountId}"` : ""; if (!normalizedPath) { params.log?.(`plugin: webhook path missing${suffix}`); return () => {}; } if (routes.some((entry) => entry.path === normalizedPath)) { const pluginHint = params.pluginId ? ` (${params.pluginId})` : ""; params.log?.(`plugin: webhook path ${normalizedPath} already registered${suffix}${pluginHint}`); return () => {}; } const entry = { path: normalizedPath, handler: params.handler, pluginId: params.pluginId, source: params.source }; routes.push(entry); return () => { const index = routes.indexOf(entry); if (index >= 0) routes.splice(index, 1); }; } //#endregion //#region src/plugin-sdk/tool-send.ts function extractToolSend(args, expectedAction = "sendMessage") { if ((typeof args.action === "string" ? args.action.trim() : "") !== expectedAction) return null; const to = typeof args.to === "string" ? args.to : void 0; if (!to) return null; return { to, accountId: typeof args.accountId === "string" ? args.accountId.trim() : void 0 }; } //#endregion //#region src/shared/device-auth.ts function normalizeDeviceAuthRole(role) { return role.trim(); } function normalizeDeviceAuthScopes(scopes) { if (!Array.isArray(scopes)) return []; const out = /* @__PURE__ */ new Set(); for (const scope of scopes) { const trimmed = scope.trim(); if (trimmed) out.add(trimmed); } return [...out].toSorted(); } //#endregion //#region src/infra/device-pairing.ts const PENDING_TTL_MS = 300 * 1e3; const withLock = createAsyncLock(); async function loadState(baseDir) { const { pendingPath, pairedPath } = resolvePairingPaths(baseDir, "devices"); const [pending, paired] = await Promise.all([readJsonFile(pendingPath), readJsonFile(pairedPath)]); const state = { pendingById: pending ?? {}, pairedByDeviceId: paired ?? {} }; pruneExpiredPending(state.pendingById, Date.now(), PENDING_TTL_MS); return state; } async function persistState(state, baseDir) { const { pendingPath, pairedPath } = resolvePairingPaths(baseDir, "devices"); await Promise.all([writeJsonAtomic(pendingPath, state.pendingById), writeJsonAtomic(pairedPath, state.pairedByDeviceId)]); } function normalizeDeviceId(deviceId) { return deviceId.trim(); } function normalizeRole(role) { const trimmed = role?.trim(); return trimmed ? trimmed : null; } function mergeRoles(...items) { const roles = /* @__PURE__ */ new Set(); for (const item of items) { if (!item) continue; if (Array.isArray(item)) for (const role of item) { const trimmed = role.trim(); if (trimmed) roles.add(trimmed); } else { const trimmed = item.trim(); if (trimmed) roles.add(trimmed); } } if (roles.size === 0) return; return [...roles]; } function mergeScopes(...items) { const scopes = /* @__PURE__ */ new Set(); for (const item of items) { if (!item) continue; for (const scope of item) { const trimmed = scope.trim(); if (trimmed) scopes.add(trimmed); } } if (scopes.size === 0) return; return [...scopes]; } function newToken() { return generatePairingToken(); } async function listDevicePairing(baseDir) { const state = await loadState(baseDir); return { pending: Object.values(state.pendingById).toSorted((a, b) => b.ts - a.ts), paired: Object.values(state.pairedByDeviceId).toSorted((a, b) => b.approvedAtMs - a.approvedAtMs) }; } async function approveDevicePairing(requestId, baseDir) { return await withLock(async () => { const state = await loadState(baseDir); const pending = state.pendingById[requestId]; if (!pending) return null; const now = Date.now(); const existing = state.pairedByDeviceId[pending.deviceId]; const roles = mergeRoles(existing?.roles, existing?.role, pending.roles, pending.role); const approvedScopes = mergeScopes(existing?.approvedScopes ?? existing?.scopes, pending.scopes); const tokens = existing?.tokens ? { ...existing.tokens } : {}; const roleForToken = normalizeRole(pending.role); if (roleForToken) { const nextScopes = normalizeDeviceAuthScopes(pending.scopes); const existingToken = tokens[roleForToken]; const now = Date.now(); tokens[roleForToken] = { token: newToken(), role: roleForToken, scopes: nextScopes, createdAtMs: existingToken?.createdAtMs ?? now, rotatedAtMs: existingToken ? now : void 0, revokedAtMs: void 0, lastUsedAtMs: existingToken?.lastUsedAtMs }; } const device = { deviceId: pending.deviceId, publicKey: pending.publicKey, displayName: pending.displayName, platform: pending.platform, clientId: pending.clientId, clientMode: pending.clientMode, role: pending.role, roles, scopes: approvedScopes, approvedScopes, remoteIp: pending.remoteIp, tokens, createdAtMs: existing?.createdAtMs ?? now, approvedAtMs: now }; delete state.pendingById[requestId]; state.pairedByDeviceId[device.deviceId] = device; await persistState(state, baseDir); return { requestId, device }; }); } async function rejectDevicePairing(requestId, baseDir) { return await withLock(async () => { const state = await loadState(baseDir); const pending = state.pendingById[requestId]; if (!pending) return null; delete state.pendingById[requestId]; await persistState(state, baseDir); return { requestId, deviceId: pending.deviceId }; }); } async function clearDevicePairing(deviceId, baseDir) { return await withLock(async () => { const state = await loadState(baseDir); const normalizedId = normalizeDeviceId(deviceId); if (!state.pairedByDeviceId[normalizedId]) return false; delete state.pairedByDeviceId[normalizedId]; await persistState(state, baseDir); return true; }); } //#endregion //#region src/infra/map-size.ts function pruneMapToMaxSize(map, maxSize) { const limit = Math.max(0, Math.floor(maxSize)); if (limit <= 0) { map.clear(); return; } while (map.size > limit) { const oldest = map.keys().next(); if (oldest.done) break; map.delete(oldest.value); } } //#endregion //#region src/infra/dedupe.ts function createDedupeCache(options) { const ttlMs = Math.max(0, options.ttlMs); const maxSize = Math.max(0, Math.floor(options.maxSize)); const cache = /* @__PURE__ */ new Map(); const touch = (key, now) => { cache.delete(key); cache.set(key, now); }; const prune = (now) => { const cutoff = ttlMs > 0 ? now - ttlMs : void 0; if (cutoff !== void 0) { for (const [entryKey, entryTs] of cache) if (entryTs < cutoff) cache.delete(entryKey); } if (maxSize <= 0) { cache.clear(); return; } pruneMapToMaxSize(cache, maxSize); }; return { check: (key, now = Date.now()) => { if (!key) return false; const existing = cache.get(key); if (existing !== void 0 && (ttlMs <= 0 || now - existing < ttlMs)) { touch(key, now); return true; } touch(key, now); prune(now); return false; }, clear: () => { cache.clear(); }, size: () => cache.size }; } //#endregion //#region src/infra/http-body.ts const DEFAULT_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024; const DEFAULT_WEBHOOK_BODY_TIMEOUT_MS = 3e4; const DEFAULT_ERROR_MESSAGE = { PAYLOAD_TOO_LARGE: "PayloadTooLarge", REQUEST_BODY_TIMEOUT: "RequestBodyTimeout", CONNECTION_CLOSED: "RequestBodyConnectionClosed" }; const DEFAULT_ERROR_STATUS_CODE = { PAYLOAD_TOO_LARGE: 413, REQUEST_BODY_TIMEOUT: 408, CONNECTION_CLOSED: 400 }; const DEFAULT_RESPONSE_MESSAGE = { PAYLOAD_TOO_LARGE: "Payload too large", REQUEST_BODY_TIMEOUT: "Request body timeout", CONNECTION_CLOSED: "Connection closed" }; var RequestBodyLimitError = class extends Error { constructor(init) { super(init.message ?? DEFAULT_ERROR_MESSAGE[init.code]); this.name = "RequestBodyLimitError"; this.code = init.code; this.statusCode = DEFAULT_ERROR_STATUS_CODE[init.code]; } }; function isRequestBodyLimitError(error, code) { if (!(error instanceof RequestBodyLimitError)) return false; if (!code) return true; return error.code === code; } function requestBodyErrorToText(code) { return DEFAULT_RESPONSE_MESSAGE[code]; } function parseContentLengthHeader(req) { const header = req.headers["content-length"]; const raw = Array.isArray(header) ? header[0] : header; if (typeof raw !== "string") return null; const parsed = Number.parseInt(raw, 10); if (!Number.isFinite(parsed) || parsed < 0) return null; return parsed; } async function readRequestBodyWithLimit(req, options) { const maxBytes = Number.isFinite(options.maxBytes) ? Math.max(1, Math.floor(options.maxBytes)) : 1; const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(1, Math.floor(options.timeoutMs)) : DEFAULT_WEBHOOK_BODY_TIMEOUT_MS; const encoding = options.encoding ?? "utf-8"; const declaredLength = parseContentLengthHeader(req); if (declaredLength !== null && declaredLength > maxBytes) { const error = new RequestBodyLimitError({ code: "PAYLOAD_TOO_LARGE" }); if (!req.destroyed) req.destroy(); throw error; } return await new Promise((resolve, reject) => { let done = false; let ended = false; let totalBytes = 0; const chunks = []; const cleanup = () => { req.removeListener("data", onData); req.removeListener("end", onEnd); req.removeListener("error", onError); req.removeListener("close", onClose); clearTimeout(timer); }; const finish = (cb) => { if (done) return; done = true; cleanup(); cb(); }; const fail = (error) => { finish(() => reject(error)); }; const timer = setTimeout(() => { const error = new RequestBodyLimitError({ code: "REQUEST_BODY_TIMEOUT" }); if (!req.destroyed) req.destroy(); fail(error); }, timeoutMs); const onData = (chunk) => { if (done) return; const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); totalBytes += buffer.length; if (totalBytes > maxBytes) { const error = new RequestBodyLimitError({ code: "PAYLOAD_TOO_LARGE" }); if (!req.destroyed) req.destroy(); fail(error); return; } chunks.push(buffer); }; const onEnd = () => { ended = true; finish(() => resolve(Buffer.concat(chunks).toString(encoding))); }; const onError = (error) => { if (done) return; fail(error); }; const onClose = () => { if (done || ended) return; fail(new RequestBodyLimitError({ code: "CONNECTION_CLOSED" })); }; req.on("data", onData); req.on("end", onEnd); req.on("error", onError); req.on("close", onClose); }); } async function readJsonBodyWithLimit(req, options) { try { const trimmed = (await readRequestBodyWithLimit(req, options)).trim(); if (!trimmed) { if (options.emptyObjectOnEmpty === false) return { ok: false, code: "INVALID_JSON", error: "empty payload" }; return { ok: true, value: {} }; } try { return { ok: true, value: JSON.parse(trimmed) }; } catch (error) { return { ok: false, code: "INVALID_JSON", error: error instanceof Error ? error.message : String(error) }; } } catch (error) { if (isRequestBodyLimitError(error)) return { ok: false, code: error.code, error: requestBodyErrorToText(error.code) }; return { ok: false, code: "INVALID_JSON", error: error instanceof Error ? error.message : String(error) }; } } function installRequestBodyLimitGuard(req, res, options) { const maxBytes = Number.isFinite(options.maxBytes) ? Math.max(1, Math.floor(options.maxBytes)) : 1; const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(1, Math.floor(options.timeoutMs)) : DEFAULT_WEBHOOK_BODY_TIMEOUT_MS; const responseFormat = options.responseFormat ?? "json"; const customText = options.responseText ?? {}; let tripped = false; let reason = null; let done = false; let ended = false; let totalBytes = 0; const cleanup = () => { req.removeListener("data", onData); req.removeListener("end", onEnd); req.removeListener("close", onClose); req.removeListener("error", onError); clearTimeout(timer); }; const finish = () => { if (done) return; done = true; cleanup(); }; const respond = (error) => { const text = customText[error.code] ?? requestBodyErrorToText(error.code); if (!res.headersSent) { res.statusCode = error.statusCode; if (responseFormat === "text") { res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end(text); } else { res.setHeader("Content-Type", "application/json; charset=utf-8"); res.end(JSON.stringify({ error: text })); } } }; const trip = (error) => { if (tripped) return; tripped = true; reason = error.code; finish(); respond(error); if (!req.destroyed) req.destroy(); }; const onData = (chunk) => { if (done) return; const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); totalBytes += buffer.length; if (totalBytes > maxBytes) trip(new RequestBodyLimitError({ code: "PAYLOAD_TOO_LARGE" })); }; const onEnd = () => { ended = true; finish(); }; const onClose = () => { if (done || ended) return; finish(); }; const onError = () => { finish(); }; const timer = setTimeout(() => { trip(new RequestBodyLimitError({ code: "REQUEST_BODY_TIMEOUT" })); }, timeoutMs); req.on("data", onData); req.on("end", onEnd); req.on("close", onClose); req.on("error", onError); const declaredLength = parseContentLengthHeader(req); if (declaredLength !== null && declaredLength > maxBytes) trip(new RequestBodyLimitError({ code: "PAYLOAD_TOO_LARGE" })); return { dispose: finish, isTripped: () => tripped, code: () => reason }; } //#endregion //#region src/infra/wsl.ts function isWSLEnv() { if (process.env.WSL_INTEROP || process.env.WSL_DISTRO_NAME || process.env.WSLENV) return true; return false; } /** * Synchronously check if running in WSL. * Checks env vars first, then /proc/version. */ function isWSLSync() { if (process.platform !== "linux") return false; if (isWSLEnv()) return true; try { const release = readFileSync("/proc/version", "utf8").toLowerCase(); return release.includes("microsoft") || release.includes("wsl"); } catch { return false; } } /** * Synchronously check if running in WSL2. */ function isWSL2Sync() { if (!isWSLSync()) return false; try { const version = readFileSync("/proc/version", "utf8").toLowerCase(); return version.includes("wsl2") || version.includes("microsoft-standard"); } catch { return false; } } //#endregion //#region src/channels/allowlist-match.ts function formatAllowlistMatchMeta(match) { return `matchKey=${match?.matchKey ?? "none"} matchSource=${match?.matchSource ?? "none"}`; } function resolveAllowlistMatchSimple(params) { const allowFrom = params.allowFrom.map((entry) => String(entry).trim().toLowerCase()).filter(Boolean); if (allowFrom.length === 0) return { allowed: false }; if (allowFrom.includes("*")) return { allowed: true, matchKey: "*", matchSource: "wildcard" }; const senderId = params.senderId.toLowerCase(); if (allowFrom.includes(senderId)) return { allowed: true, matchKey: senderId, matchSource: "id" }; const senderName = params.senderName?.toLowerCase(); if (senderName && allowFrom.includes(senderName)) return { allowed: true, matchKey: senderName, matchSource: "name" }; return { allowed: false }; } //#endregion //#region src/auto-reply/reply/mentions.ts function deriveMentionPatterns(identity) { const patterns = []; const name = identity?.name?.trim(); if (name) { const parts = name.split(/\s+/).filter(Boolean).map(escapeRegExp); const re = parts.length ? parts.join(String.raw`\s+`) : escapeRegExp(name); patterns.push(String.raw`\b@?${re}\b`); } const emoji = identity?.emoji?.trim(); if (emoji) patterns.push(escapeRegExp(emoji)); return patterns; } const BACKSPACE_CHAR = "\b"; const CURRENT_MESSAGE_MARKER = "[Current message - respond to this]"; function normalizeMentionPattern(pattern) { if (!pattern.includes(BACKSPACE_CHAR)) return pattern; return pattern.split(BACKSPACE_CHAR).join("\\b"); } function normalizeMentionPatterns(patterns) { return patterns.map(normalizeMentionPattern); } function resolveMentionPatterns(cfg, agentId) { if (!cfg) return []; const agentConfig = agentId ? resolveAgentConfig(cfg, agentId) : void 0; const agentGroupChat = agentConfig?.groupChat; if (agentGroupChat && Object.hasOwn(agentGroupChat, "mentionPatterns")) return agentGroupChat.mentionPatterns ?? []; const globalGroupChat = cfg.messages?.groupChat; if (globalGroupChat && Object.hasOwn(globalGroupChat, "mentionPatterns")) return globalGroupChat.mentionPatterns ?? []; const derived = deriveMentionPatterns(agentConfig?.identity); return derived.length > 0 ? derived : []; } function buildMentionRegexes(cfg, agentId) { return normalizeMentionPatterns(resolveMentionPatterns(cfg, agentId)).map((pattern) => { try { return new RegExp(pattern, "i"); } catch { return null; } }).filter((value) => Boolean(value)); } function normalizeMentionText(text) { return (text ?? "").replace(/[\u200b-\u200f\u202a-\u202e\u2060-\u206f]/g, "").toLowerCase(); } function matchesMentionPatterns(text, mentionRegexes) { if (mentionRegexes.length === 0) return false; const cleaned = normalizeMentionText(text ?? ""); if (!cleaned) return false; return mentionRegexes.some((re) => re.test(cleaned)); } function matchesMentionWithExplicit(params) { const cleaned = normalizeMentionText(params.text ?? ""); const explicit = params.explicit?.isExplicitlyMentioned === true; const explicitAvailable = params.explicit?.canResolveExplicit === true; const hasAnyMention = params.explicit?.hasAnyMention === true; const transcriptCleaned = params.transcript ? normalizeMentionText(params.transcript) : ""; const textToCheck = cleaned || transcriptCleaned; if (hasAnyMention && explicitAvailable) return explicit || params.mentionRegexes.some((re) => re.test(textToCheck)); if (!textToCheck) return explicit; return explicit || params.mentionRegexes.some((re) => re.test(textToCheck)); } function stripStructuralPrefixes(text) { return (text.includes(CURRENT_MESSAGE_MARKER) ? text.slice(text.indexOf(CURRENT_MESSAGE_MARKER) + 35).trimStart() : text).replace(/\[[^\]]+\]\s*/g, "").replace(/^[ \t]*[A-Za-z0-9+()\-_. ]+:\s*/gm, "").replace(/\\n/g, " ").replace(/\s+/g, " ").trim(); } function stripMentions(text, ctx, cfg, agentId) { let result = text; const providerId = ctx.Provider ? normalizeChannelId$1(ctx.Provider) : null; const providerMentions = providerId ? getChannelDock(providerId)?.mentions : void 0; const patterns = normalizeMentionPatterns([...resolveMentionPatterns(cfg, agentId), ...providerMentions?.stripPatterns?.({ ctx, cfg, agentId }) ?? []]); for (const p of patterns) try { const re = new RegExp(p, "gi"); result = result.replace(re, " "); } catch {} if (providerMentions?.stripMentions) result = providerMentions.stripMentions({ text: result, ctx, cfg, agentId }); result = result.replace(/@[0-9+]{5,}/g, " "); return result.replace(/\s+/g, " ").trim(); } //#endregion //#region src/auto-reply/reply/history.ts const HISTORY_CONTEXT_MARKER = "[Chat messages since your last reply - for context]"; const DEFAULT_GROUP_HISTORY_LIMIT = 50; /** Maximum number of group history keys to retain (LRU eviction when exceeded). */ const MAX_HISTORY_KEYS = 1e3; /** * Evict oldest keys from a history map when it exceeds MAX_HISTORY_KEYS. * Uses Map's insertion order for LRU-like behavior. */ function evictOldHistoryKeys(historyMap, maxKeys = MAX_HISTORY_KEYS) { if (historyMap.size <= maxKeys) return; const keysToDelete = historyMap.size - maxKeys; const iterator = historyMap.keys(); for (let i = 0; i < keysToDelete; i++) { const key = iterator.next().value; if (key !== void 0) historyMap.delete(key); } } function buildHistoryContext(params) { const { historyText, currentMessage } = params; const lineBreak = params.lineBreak ?? "\n"; if (!historyText.trim()) return currentMessage; return [ HISTORY_CONTEXT_MARKER, historyText, "", CURRENT_MESSAGE_MARKER, currentMessage ].join(lineBreak); } function appendHistoryEntry(params) { const { historyMap, historyKey, entry } = params; if (params.limit <= 0) return []; const history = historyMap.get(historyKey) ?? []; history.push(entry); while (history.length > params.limit) history.shift(); if (historyMap.has(historyKey)) historyMap.delete(historyKey); historyMap.set(historyKey, history); evictOldHistoryKeys(historyMap); return history; } function recordPendingHistoryEntry(params) { return appendHistoryEntry(params); } function recordPendingHistoryEntryIfEnabled(params) { if (!params.entry) return []; if (params.limit <= 0) return []; return recordPendingHistoryEntry({ historyMap: params.historyMap, historyKey: params.historyKey, entry: params.entry, limit: params.limit }); } function buildPendingHistoryContextFromMap(params) { if (params.limit <= 0) return params.currentMessage; return buildHistoryContextFromEntries({ entries: params.historyMap.get(params.historyKey) ?? [], currentMessage: params.currentMessage, formatEntry: params.formatEntry, lineBreak: params.lineBreak, excludeLast: false }); } function clearHistoryEntries(params) { params.historyMap.set(params.historyKey, []); } function clearHistoryEntriesIfEnabled(params) { if (params.limit <= 0) return; clearHistoryEntries({ historyMap: params.historyMap, historyKey: params.historyKey }); } function buildHistoryContextFromEntries(params) { const lineBreak = params.lineBreak ?? "\n"; const entries = params.excludeLast === false ? params.entries : params.entries.slice(0, -1); if (entries.length === 0) return params.currentMessage; return buildHistoryContext({ historyText: entries.map(params.formatEntry).join(lineBreak), currentMessage: params.currentMessage, lineBreak }); } //#endregion //#region src/channels/allowlists/resolve-utils.ts function mergeAllowlist(params) { const seen = /* @__PURE__ */ new Set(); const merged = []; const push = (value) => { const normalized = value.trim(); if (!normalized) return; const key = normalized.toLowerCase(); if (seen.has(key)) return; seen.add(key); merged.push(normalized); }; for (const entry of params.existing ?? []) push(String(entry)); for (const entry of params.additions) push(entry); return merged; } function buildAllowlistResolutionSummary(resolvedUsers, opts) { const resolvedMap = new Map(resolvedUsers.map((entry) => [entry.input, entry])); const resolvedOk = (entry) => Boolean(entry.resolved && entry.id); const formatResolved = opts?.formatResolved ?? ((entry) => `${entry.input}→${entry.id}`); const mapping = resolvedUsers.filter(resolvedOk).map(formatRe