     1→import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
     2→import { a as resolveAgentModelFallbacksOverride, c as resolveAgentWorkspaceDir, d as resolveSessionAgentId, f as resolveSessionAgentIds, g as toAgentModelListLike, h as resolveAgentModelPrimaryValue, l as resolveDefaultAgentId, m as resolveAgentModelFallbackValues, n as resolveAgentConfig, r as resolveAgentDir, s as resolveAgentSkillsFilter, t as listAgentIds, u as resolveEffectiveModelFallbacks } from "./agent-scope-BbLbkVXD.js";
     3→import { c as expandHomePrefix, i as resolveGatewayPort, n as resolveConfigPath, s as resolveStateDir, t as STATE_DIR, u as resolveRequiredHomeDir } from "./paths-C9do7WCN.js";
     4→import { $ as warn, A as isRecord$1, B as shortenHomePath, C as CONFIG_DIR, D as ensureDir$3, G as isPlainObject, H as sliceUtf16Safe, J as logVerbose, K as danger, L as resolveUserPath, N as normalizeE164, O as escapeRegExp, S as matchPluginCommand, T as clampInt, V as sleep$1, W as truncateUtf16Safe, X as setVerbose, Z as shouldLogVerbose, _ as normalizePluginHttpPath, a as registerActiveProgressLine, b as getPluginCommandSpecs, c as CHAT_CHANNEL_ORDER, ct as resolvePreferredOpenClawTmpDir, d as normalizeChannelId, et as colorize, ft as triggerInternalHook, g as createPluginRegistry, h as setActivePluginRegistry, i as clearActiveProgressLine, k as formatTerminalLink, lt as createInternalHookEvent, m as requireActivePluginRegistry, n as createNonExitingRuntime, nt as theme, o as unregisterActiveProgressLine, r as defaultRuntime, rt as getChildLogger, st as normalizeLogLevel, t as createSubsystemLogger, tt as isRich, u as normalizeAnyChannelId, v as clearPluginCommands, x as listPluginCommands, y as executePluginCommand, z as shortenHomeInString } from "./subsystem-BoKOAh1n.js";
     5→import { S as resolveThreadParentSessionKey, _ as getSubagentDepth, b as isSubagentSessionKey, c as normalizeMainKey, d as sanitizeAgentId, f as DEFAULT_ACCOUNT_ID, g as deriveSessionChatType, h as isBlockedObjectKey, l as resolveAgentIdFromSessionKey, m as normalizeOptionalAccountId, o as classifySessionKeyShape, p as normalizeAccountId$2, r as buildAgentMainSessionKey, s as normalizeAgentId, t as DEFAULT_AGENT_ID, u as resolveThreadSessionKeys, v as isAcpSessionKey, x as parseAgentSessionKey, y as isCronSessionKey } from "./session-key-YGVrIVO5.js";
     6→import { S as logWarn, _ as runExec, a as DEFAULT_IDENTITY_FILENAME, b as logError, f as loadWorkspaceBootstrapFiles, g as runCommandWithTimeout, l as ensureAgentWorkspace, m as resolveOpenClawPackageRoot, n as DEFAULT_AGENT_WORKSPACE_DIR, r as DEFAULT_BOOTSTRAP_FILENAME, u as filterBootstrapFilesForSession, v as spawnWithFallback, x as logInfo, y as logDebug } from "./workspace-PSi34tZF.js";
     7→import { B as isProfileInCooldown, C as getApiKeyForModel, D as resolveEnvApiKey, E as resolveApiKeyForProvider, F as isDangerousHostEnvVarName, G as dedupeProfileIds, H as markAuthProfileUsed, J as ensureAuthProfileStore, K as listProfilesForProvider, O as resolveModelAuthMode, R as resolveAuthProfileOrder, S as createOllamaStreamFn, T as requireApiKey, U as resolveProfilesUnavailableReason, V as markAuthProfileFailure, W as resolveApiKeyForProfile, X as resolveOpenClawAgentDir, Y as resolveAuthStorePathForDisplay, Z as withFileLock, a as isCliProvider, c as normalizeProviderId, d as resolveDefaultModelForAgent, et as normalizeSecretInput, f as resolveModelRefFromString, h as resolveThinkingDefault, i as findNormalizedProviderValue, it as DEFAULT_PROVIDER, j as resolveShellEnvFallbackTimeoutMs, k as getShellPathFromLoginShell, m as resolveSubagentSpawnModelSelection, n as buildConfiguredAllowlistKeys, nt as DEFAULT_CONTEXT_TOKENS, o as modelKey, p as resolveReasoningDefault, q as markAuthProfileGood, r as buildModelAliasIndex, rt as DEFAULT_MODEL, s as normalizeModelRef$2, t as buildAllowedModelSet, tt as resolveAuthProfileDisplayLabel, u as resolveConfiguredModelRef, w as getCustomProviderApiKey, x as OLLAMA_NATIVE_BASE_URL, z as getSoonestCooldownExpiry } from "./model-selection-B5NjONwE.js";
     8→import { a as saveJsonFile, i as loadJsonFile } from "./github-copilot-token-BkwQAVvU.js";
     9→import { n as formatCliCommand, r as resolveCliName, t as isTruthyEnvValue } from "./env-Bw45uydv.js";
    10→import { t as parseBooleanValue$1 } from "./boolean-mcn6kL0s.js";
    11→import { i as isSilentReplyText, n as SILENT_REPLY_TOKEN, r as isSilentReplyPrefixText, t as HEARTBEAT_TOKEN } from "./tokens-BLlPaiD5.js";
    12→import { _ as resolveDiscordAccount, a as normalizeWhatsAppTarget, c as listTelegramAccountIds, d as resolveSlackAccount, g as listEnabledDiscordAccounts, h as createDiscordActionGate, i as isWhatsAppGroupJid, l as resolveTelegramAccount, m as resolveSlackBotToken, n as listChannelPlugins, o as createTelegramActionGate, p as resolveSlackAppToken, r as normalizeChannelId$1, s as listEnabledTelegramAccounts, t as getChannelPlugin, u as resolveTelegramToken, v as normalizeDiscordToken } from "./plugins-BlRpkhyC.js";
    13→import { a as logoutWeb, i as logWebSelfId, l as readWebSelfId, p as webAuthExists, r as getWebAuthAgeMs, t as resolveWhatsAppAccount } from "./accounts-CxYlEftx.js";
    14→import { t as resolveAccountEntry } from "./account-lookup-lrwBXb1l.js";
    15→import { t as normalizeChatType } from "./chat-type-C4pAlbsI.js";
    16→import { a as resolveSlackWebClientOptions, c as buildSlackBlocksFallbackText, i as createSlackWebClient, l as parseSlackTarget, o as parseSlackBlocksInput, s as validateSlackBlocksArray, t as sendMessageSlack, u as resolveSlackChannelId } from "./send-BF8QfC--.js";
    17→import { $ as fetchChannelPermissionsDiscord, A as unpinMessageDiscord, B as listScheduledEventsDiscord, C as editMessageDiscord, Ct as resolveTimestampMs, D as pinMessageDiscord, Dt as normalizeChannelSlug, E as listThreadsDiscord, Et as buildChannelKeyCandidates, F as fetchMemberInfoDiscord, G as uploadStickerDiscord, H as timeoutMemberDiscord, I as fetchRoleInfoDiscord, J as editChannelDiscord, K as createChannelDiscord, L as fetchVoiceStatusDiscord, M as banMemberDiscord, N as createScheduledEventDiscord, O as readMessagesDiscord, Ot as resolveChannelEntryMatchWithFallback, P as fetchChannelInfoDiscord, Q as stripUndefinedFields, R as kickMemberDiscord, S as deleteMessageDiscord, St as resolveDiscordSystemLocation, T as listPinsDiscord, Tt as applyChannelMatchMeta, U as listGuildEmojisDiscord, V as removeRoleDiscord, W as uploadEmojiDiscord, X as removeChannelPermissionDiscord, Y as moveChannelDiscord, Z as setChannelPermissionDiscord, _ as sendPollDiscord, _t as resolveDiscordShouldRequireMention, a as removeReactionDiscord, at as resolveDiscordChannelId, b as sendWebhookMessageDiscord, bt as formatDiscordReactionEmoji, c as formatDiscordComponentEventText, ct as allowListMatches$1, d as parseDiscordModalCustomId, dt as normalizeDiscordSlug, et as hasAnyGuildPermissionDiscord, f as parseDiscordModalCustomIdForCarbon, ft as resolveDiscordAllowListMatch, g as sendMessageDiscord, gt as resolveDiscordOwnerAllowFrom, h as resolveDiscordModalEntry, ht as resolveDiscordMemberAccessState, i as removeOwnReactionsDiscord, it as parseDiscordTarget, j as addRoleDiscord, k as searchMessagesDiscord, l as parseDiscordComponentCustomId, lt as isDiscordGroupAllowedByPolicy, m as resolveDiscordComponentEntry, mt as resolveDiscordGuildEntry, n as fetchReactionsDiscord, nt as createDiscordClient, o as sendDiscordComponentMessage, ot as listDiscordDirectoryGroupsLive, p as readDiscordComponentSpec, pt as resolveDiscordChannelConfigWithFallback, q as deleteChannelDiscord, r as reactMessageDiscord, rt as createDiscordRestClient, s as createDiscordFormModal, st as listDiscordDirectoryPeersLive, tt as chunkDiscordTextWithMode, u as parseDiscordComponentCustomIdForCarbon, ut as normalizeDiscordAllowList, v as sendStickerDiscord, vt as resolveGroupDmAllow, w as fetchMessageDiscord, wt as fetchDiscord, x as createThreadDiscord, xt as formatDiscordUserTag, y as sendVoiceMessageDiscord, yt as shouldEmitDiscordReactionNotification, z as listGuildChannelsDiscord } from "./send-CBl-cFHi.js";
    18→import { n as generateSecureUuid, t as generateSecureToken } from "./secure-random-faWesvBQ.js";
    19→import { S as initializeGlobalHookRunner, _ 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 throwIfAborted, x as getGlobalHookRunner, y as parseReplyDirectives } from "./deliver-i_F6aUuX.js";
    20→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-D_de7-KX.js";
    21→import { r as getDiagnosticSessionState } from "./diagnostic-session-state-C0Sxjfox.js";
    22→import { n as resolveSignalAccount, t as listEnabledSignalAccounts } from "./accounts-Ci-FogVD.js";
    23→import { $ as getPairingAdapter, A as extractTelegramLocation, B as normalizeAllowFromWithStore$1, C as buildTelegramGroupFrom, D as buildTypingThreadParams, E as buildTelegramThreadParams, F as resolveTelegramMediaPlaceholder, G as formatLocationText, H as firstDefined$1, I as resolveTelegramReplyId, J as readChannelAllowFromStore, K as toLocationContext, L as resolveTelegramStreamMode, M as normalizeForwardedContext, N as resolveTelegramForumThreadId, O as describeReplyTarget, P as resolveTelegramGroupAllowFromContext, Q as writeJsonFileAtomically, R as resolveTelegramThreadSpec, S as buildSenderName, T as buildTelegramParentPeer, U as isSenderIdAllowed, V as resolveSenderAllowMatch, W as mergeAllowFromSources, X as upsertChannelPairingRequest, Y as removeChannelAllowFromStoreEntry, Z as readJsonFileWithFallback, _ as resolveTelegramFetch, a as reactMessageTelegram, b as buildGroupLabel, c as sendStickerTelegram, d as wasSentByBot, et as listPairingChannels, f as isRecoverableTelegramNetworkError, g as wrapFileReferencesInHtml, h as renderTelegramHtmlText, i as editMessageTelegram, j as hasBotMention, k as expandTextLinks, m as markdownToTelegramHtml, n as createForumTopicTelegram, nt as parseTelegramTarget, o as sendMessageTelegram, p as markdownToTelegramChunks, q as addChannelAllowFromStoreEntry, r as deleteMessageTelegram, rt as resolveTelegramTargetChatType, s as sendPollTelegram, t as buildInlineKeyboard, tt as isVoiceCompatibleAudio, u as resolveTelegramVoiceSend, v as splitTelegramCaption, w as buildTelegramGroupPeerId, x as buildSenderLabel, y as withTelegramApiErrorLogging, z as isSenderAllowed$1 } from "./send-BEnRshK8.js";
    24→import { d as detectMime, f as extensionForMime, g as isGifMedia, h as isAudioFileName, i as getImageMetadata, m as imageMimeFromFormat, s as resizeToJpeg, x as mediaKindFromMime, y as MAX_IMAGE_BYTES } from "./image-ops-DR7iVy0X.js";
    25→import { n as discoverModels, t as discoverAuthStorage } from "./pi-model-discovery-C-yOXpma.js";
    26→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-NXidGUO7.js";
    27→import { $ as mergeAlsoAllowPolicy, A as isTransientHttpError, B as resolveProfile, C as isContextOverflowError, D as isRateLimitAssistantError, E as isLikelyContextOverflowError, F as resolveSandboxContext, G as resolveBrowserControlAuth, H as resolveExistingPathsWithinRoot, I as resolveSandboxRuntimeStatus, J as resolveSandboxConfigForAgent, K as resolveGatewayCredentialsFromConfig, L as createBrowserRouteContext, M as parseImageSizeError, N as sanitizeUserFacingText, O as isRawApiErrorPayload, P as ensureSandboxWorkspaceForSession, Q as expandPolicyWithPluginGroups, R as registerBrowserRoutes, S as isCompactionFailureError, T as isFailoverErrorMessage, U as getBridgeAuthForPort, V as DEFAULT_UPLOAD_DIR, W as ensureBrowserControlAuth, X as buildPluginToolGroups, Y as applyOwnerOnlyToolPolicy, Z as collectExplicitAllowlist, _ as formatRawAssistantErrorForUi, a as isMessagingToolDuplicateNormalized, at as matchesAnyGlobPattern, b as isBillingAssistantError, c as extractToolCallsFromAssistant, ct as resolveBootstrapMaxChars, d as downgradeOpenAIReasoningBlocks, et as stripPluginOnlyAllowlist, f as isGoogleModelApi, g as formatBillingErrorMessage, h as formatAssistantErrorText, it as compileGlobPatterns, j as parseImageDimensionError, k as isTimeoutErrorMessage, l as extractToolResultId, lt as resolveBootstrapTotalMaxChars, m as classifyFailoverReason, n as validateGeminiTurns, nt as normalizeToolName, o as normalizeTextForComparison, ot as buildBootstrapContextFiles, p as BILLING_ERROR_USER_MESSAGE, q as trimToUndefined$1, r as pickFallbackThinkingLevel, rt as resolveToolProfilePolicy, s as sanitizeSessionMessagesImages, st as ensureSessionHeader, t as validateAnthropicTurns, tt as expandToolGroups, u as sanitizeToolCallIdsForCloudCodeAssist, ut as sanitizeGoogleTurnOrdering, v as getApiErrorPayloadFingerprint, w as isFailoverAssistantError, x as isCloudCodeAssistFormatError, y as isAuthAssistantError, z as resolveBrowserConfig } from "./pi-embedded-helpers-BdkmD3wR.js";
    28→import { $ as resolveSafeBinProfiles, A as parseConfigPath, B as splitCommandChain, C as isSupportedLocalAvatarExtension, D as setConfigOverride, E as resetConfigOverrides, F as normalizeTrustedSafeBinDirs, G as extractShellWrapperInlineCommand, H as matchAllowlist, I as validateSafeBinArgv, J as unwrapKnownDispatchWrapperInvocation, K as isDispatchWrapperExecutable, L as analyzeShellCommand, M as unsetConfigValueAtPath, N as getTrustedSafeBinDirs, O as unsetConfigOverride, P as isTrustedSafeBinPath, Q as normalizeSafeBinProfileFixtures, R as buildEnforcedShellCommand, S as isPathWithinRoot, T as getConfigOverrides, U as resolveAllowlistCandidatePath, V as DEFAULT_SAFE_BINS, W as resolveCommandResolutionFromArgv, X as splitShellArgs, Y as unwrapKnownShellMultiplexerInvocation, Z as SAFE_BIN_PROFILES, _ as parseDurationMs, a as resolveConfigSnapshotHash, b as isAvatarDataUrl, c as TELEGRAM_COMMAND_NAME_PATTERN, ct as VERSION, et as isSafeExecutableValue, f as isInboundPathAllowed, g as normalizeScpRemoteHost, h as resolveIMessageRemoteAttachmentRoots, it as resolveSlackStreamingMode, j as setConfigValueAtPath, k as getConfigValueAtPath, l as normalizeTelegramCommandName, lt as resolveOwnerDisplaySetting, m as resolveIMessageAttachmentRoots, n as loadConfig, nt as resolveDiscordPreviewStreamMode, o as writeConfigFile, ot as DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH, q as isShellWrapperExecutable, r as readConfigFileSnapshot, rt as resolveSlackNativeStreaming, s as validateConfigObjectWithPlugins, st as resolveAgentMaxConcurrent, tt as mapStreamingModeToSlackLegacyDraftStreamMode, u as resolveTelegramCustomCommands, w as validateJsonSchemaValue, x as isAvatarHttpUrl, y as AVATAR_MAX_BYTES, z as isWindowsPlatform } from "./config-DvUlTmaK.js";
    29→import { a as applyTestPluginDefaults, c as resolveMemorySlotDecision, i as safeStatSync, n as discoverOpenClawPlugins, o as normalizePluginsConfig, r as isPathInside, s as resolveEffectiveEnableState, t as loadPluginManifestRegistry, u as isPathInsideWithRealpath } from "./manifest-registry-DARtGCWp.js";
    30→import { a as resolveChannelGroupRequireMention, c as normalizeHyphenSlug, i as resolveChannelGroupPolicy, l as normalizeStringEntries, n as listChannelDocks, o as resolveChannelGroupToolsPolicy, r as normalizeSignalMessagingTarget, s as normalizeAtHashSlug, t as getChannelDock, u as normalizeStringEntriesLower } from "./dock-Devv97xs.js";
    31→import { E as isSecureWebSocketUrl, S as ensureChromeExtensionRelayServer, T as isLoopbackHost, k as DEFAULT_AI_SNAPSHOT_MAX_CHARS, w as rawDataToString } from "./chrome-D5YOyhL2.js";
    32→import { i as isBlockedHostnameOrIp, o as normalizeHostname, t as SsrFBlockedError } from "./ssrf-BM54dmk8.js";
    33→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-DOKat65v.js";
    34→import { r as compileSafeRegex, t as redactSensitiveText } from "./redact-C_vdZ7-E.js";
    35→import { n as formatErrorMessage, r as formatUncaughtError } from "./errors-BggFlOL1.js";
    36→import { n as getMediaDir, r as saveMediaBuffer } from "./store-DoCZrlTi.js";
    37→import { A as resolveSessionKey, B as resolveExplicitAgentSessionKey, C as countToolResults, D as applyInputProvenanceToUserMessage, E as INPUT_PROVENANCE_KIND_VALUES, F as resolveThreadFlag, G as resolveSessionLockMaxHoldFromTimeout, H as deriveSessionMetaPatch, I as DEFAULT_RESET_TRIGGERS, L as resolveFreshSessionTotalTokens, M as resolveChannelResetConfig, N as resolveSessionResetPolicy, O as hasInterSessionUserProvenance, P as resolveSessionResetType, R as canonicalizeMainSessionAlias, S as capArrayByJsonBytes, T as parseInlineDirectives$1, U as resolveGroupSessionKey, V as resolveMainSessionKey, W as acquireSessionWriteLock, _ as mergeDeliveryContext, b as normalizeAccountId$3, c as readSessionUpdatedAt, d as updateSessionStore, f as updateSessionStoreEntry, g as deliveryContextKey, h as deliveryContextFromSession, i as appendAssistantMessageToSessionTranscript, j as evaluateSessionFreshness, k as normalizeInputProvenance, l as recordSessionMetaFromInbound, m as resolveCacheTtlMs$1, n as extractDeliveryInfo, o as resolveAndPersistSessionFile, p as isCacheEnabled, r as parseSessionThreadInfo, s as loadSessionStore, u as updateLastRoute, v as normalizeDeliveryContext, w as extractToolCallNames, x as archiveSessionTranscripts, y as normalizeSessionDeliveryFields } from "./sessions-BiWBZ-uj.js";
    38→import { n as resolveConversationLabel } from "./conversation-label-CdWlQX3X.js";
    39→import { t as resolveIMessageAccount } from "./accounts-DKYigdEx.js";
    40→import { a as resolveSessionTranscriptPath, c as resolveSessionTranscriptsDirForAgent, i as resolveSessionFilePathOptions, l as resolveStorePath, n as resolveDefaultSessionStorePath, r as resolveSessionFilePath } from "./paths-CLWDvYDE.js";
    41→import { t as emitSessionTranscriptUpdate } from "./transcript-events-BtNd-j6q.js";
    42→import { a as canonicalizeBase64, i as resolveImageSanitizationLimits, n as sanitizeImageBlocks, o as estimateBase64DecodedBytes, r as sanitizeToolResultImages } from "./tool-images-DeM5viPH.js";
    43→import { a as normalizeReasoningLevel, c as normalizeVerboseLevel, i as normalizeElevatedLevel, l as resolveResponseUsageMode, n as formatXHighModelHint, o as normalizeThinkLevel, s as normalizeUsageDisplay, t as formatThinkingLevels, u as supportsXHighThinking } from "./thinking-CJoHneR6.js";
    44→import { C as extractTextFromChatContent, S as isInsideCode, _ as stripMinimaxToolCallXml, a as decodeDataUrl, b as stripReasoningTagsFromText, c as extractAssistantText$1, d as extractThinkingFromTaggedText, f as formatReasoningMessage, g as stripDowngradedToolCallText, h as promoteThinkingTagsToBlocks, i as coerceImageModelConfig, l as extractAssistantThinking, m as isAssistantMessage, o as resolveProviderVisionModelFromConfig, p as inferToolMetaFromArgs, r as coerceImageAssistantText, s as minimaxUnderstandImage, u as extractThinkingFromTaggedStream, v as stripThinkingTagsFromText, w as ensureOpenClawModelsJson, x as findCodeRegions, y as resolveToolDisplay } from "./image-D9XRntUA.js";
    45→import { a as resolveAgentIdentity, i as resolveAckReaction, o as resolveEffectiveMessagesConfig, r as resolveResponsePrefixTemplate, s as resolveHumanDelayConfig, t as createReplyPrefixOptions } from "./reply-prefix-Cha4QN8H.js";
    46→import { n as resolveMemorySearchConfig } from "./manager-DkvrfiWy.js";
    47→import { n as fetchWithTimeout, t as bindAbortRelay } from "./fetch-timeout-DwuL9y6C.js";
    48→import { t as fetchWithSsrFGuard } from "./fetch-guard-Diq4wbzK.js";
    49→import { _ as runTasksWithConcurrency, f as listMemoryFiles, p as normalizeExtraMemoryPaths } from "./query-expansion-CqHuxZ09.js";
    50→import { n as retryAsync } from "./retry-CpSN4cGC.js";
    51→import { a as createActionGate, c as jsonResult, d as readReactionParams, f as readStringArrayParam, l as parseAvailableTags, m as readStringParam, n as missingTargetError, o as imageResult, p as readStringOrNumberParam, r as unknownTargetError, s as imageResultFromFile, t as ambiguousTargetError, u as readNumberParam } from "./target-errors-C4v9HKnW.js";
    52→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-BK8T_RCs.js";
    53→import { n as resolveMarkdownTableMode } from "./markdown-tables-B8I8M-Et.js";
    54→import { a as readResponseWithLimit, i as fetchRemoteMedia, n as getDefaultMediaLocalRoots, r as MediaFetchError, t as getAgentScopedMediaLocalRoots } from "./local-roots-DS-8ZE_B.js";
    55→import { a as loadWebMedia, i as getDefaultLocalRoots } from "./ir-DQn3JpQE.js";
    56→import { _ as resolveNativeCommandsEnabled, a as listChatCommandsForConfig, c as normalizeCommandBody, d as resolveCommandArgMenu, f as serializeCommandArgs, g as isRestartEnabled, h as isNativeCommandsExplicitlyDisabled, i as listChatCommands, l as parseCommandArgs, m as isCommandFlagEnabled, o as listNativeCommandSpecs, p as shouldHandleTextCommands, r as findCommandByNativeName, s as listNativeCommandSpecsForConfig, t as buildCommandTextFromArgs, u as resolveCommandArgChoices, v as resolveNativeSkillsEnabled } from "./commands-registry-CclRtEXd.js";
    57→import { c as getSkillsSnapshotVersion, d as createAsyncLock, f as readJsonFile, i as resolveSkillCommandInvocation, l as pruneExpiredPending, n as listSkillCommandsForAgents, o as getRemoteSkillEligibility, p as writeJsonAtomic, r as listSkillCommandsForWorkspace, s as ensureSkillsWatcher, t as listReservedChatSlashCommandNames, u as resolvePairingPaths } from "./skill-commands-6qLPyery.js";
    58→import { r as normalizeInboundTextNewlines, t as finalizeInboundContext } from "./inbound-context-3RiUKgll.js";
    59→import { _ as resolveMediaUnderstandingScope, a as resolveMediaAttachmentLocalRoots, c as loadModelCatalog, d as resolveAttachmentKind, f as buildRandomTempFilePath, g as normalizeMediaUnderstandingChatType, h as resolveTimeoutMs$1, i as resolveAutoImageModel, l as modelSupportsVision, m as resolveConcurrency, n as createMediaAttachmentCache, o as runCapability, p as registerUnhandledRejectionHandler, r as normalizeMediaAttachments, s as findModelInCatalog, t as buildProviderRegistry, v as CLI_OUTPUT_MAX_BUFFER, y as applyTemplate } from "./runner-Bb2G1wrS.js";
    60→import { n as wrapFetchWithAbortSignal, t as resolveFetch } from "./fetch-CSgvhNYZ.js";
    61→import { n as recordCommandPoll, r as resetCommandPollCount } from "./command-poll-backoff-CA97QrJY.js";
    62→import { n as recordChannelActivity, r as createDiscordRetryRunner, t as getChannelActivity } from "./channel-activity-mEN8_E9p.js";
    63→import { n as normalizePollInput } from "./polls-DXd67TD8.js";
    64→import { t as convertMarkdownTables } from "./tables-DV7HmexJ.js";
    65→import { a as resolveSignalRpcContext, c as streamSignalEvents, n as sendReadReceiptSignal, o as signalCheck, r as sendTypingSignal, s as signalRpcRequest, t as sendMessageSignal } from "./send-CVwZarG_.js";
    66→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-C01_1hGB.js";
    67→import { n as resolveAgentRoute, t as buildAgentSessionKey } from "./resolve-route-BUlSpAUe.js";
    68→import { i as redactIdentifier, t as getActiveWebListener } from "./active-listener-CF8becvE.js";
    69→import { t as makeProxyFetch } from "./proxy-Bee2aKQk.js";
    70→import { a as createReplyReferencePlanner, i as resolveSlackThreadTs, n as deliverReplies$3, t as createSlackReplyDeliveryPlan } from "./replies-D3ifXz7i.js";
    71→import { createRequire } from "node:module";
    72→import * as fs$2 from "node:fs/promises";
    73→import fs from "node:fs/promises";
    74→import os, { homedir } from "node:os";
    75→import * as path$1 from "node:path";
    76→import path from "node:path";
    77→import fs$1, { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
    78→import JSON5 from "json5";
    79→import { inspect, promisify } from "node:util";
    80→import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
    81→import { fileURLToPath } from "node:url";
    82→import crypto, { X509Certificate, createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
    83→import { complete, completeSimple, streamSimple } from "@mariozechner/pi-ai";
    84→import { CURRENT_SESSION_VERSION, DefaultResourceLoader, SessionManager, SettingsManager, codingTools, createAgentSession, createEditTool, createReadTool, createWriteTool, estimateTokens, generateSummary, readTool } from "@mariozechner/pi-coding-agent";
    85→import { EdgeTTS } from "node-edge-tts";
    86→import AjvPkg from "ajv";
    87→import { createServer } from "node:http";
    88→import { ProxyAgent, fetch as fetch$1 } from "undici";
    89→import WebSocket, { WebSocket as WebSocket$1 } from "ws";
    90→import { Buffer as Buffer$1 } from "node:buffer";
    91→import { createJiti } from "jiti";
    92→import { Type } from "@sinclair/typebox";
    93→import readline from "node:readline";
    94→import { ApplicationCommandOptionType, ButtonStyle, ChannelType, PermissionFlagsBits, Routes, StickerFormatType } from "discord-api-types/v10";
    95→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";
    96→import { API_CONSTANTS, Bot, GrammyError, InputFile, webhookCallback } from "grammy";
    97→import { spinner } from "@clack/prompts";
    98→import { createOscProgressController, supportsOscProgress } from "osc-progress";
    99→import { GatewayCloseCodes, GatewayIntents, GatewayPlugin } from "@buape/carbon/gateway";
   100→import { VoicePlugin } from "@buape/carbon/voice";
   101→import { AudioPlayerStatus, EndBehaviorType, VoiceConnectionStatus, createAudioPlayer, createAudioResource, entersState, joinVoiceChannel } from "@discordjs/voice";
   102→import { HttpsProxyAgent } from "https-proxy-agent";
   103→import { setTimeout as setTimeout$1 } from "node:timers/promises";
   104→import { messagingApi } from "@line/bot-sdk";
   105→import SlackBolt from "@slack/bolt";
   106→import { run, sequentialize } from "@grammyjs/runner";
   107→import { apiThrottler } from "@grammyjs/transformer-throttler";
   108→import { EventEmitter } from "node:events";
   109→
   110→//#region src/auto-reply/heartbeat.ts
   111→const HEARTBEAT_PROMPT = "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.";
   112→const DEFAULT_HEARTBEAT_ACK_MAX_CHARS = 300;
   113→function resolveHeartbeatPrompt(raw) {
   114→	return (typeof raw === "string" ? raw.trim() : "") || HEARTBEAT_PROMPT;
   115→}
   116→function stripTokenAtEdges(raw) {
   117→	let text = raw.trim();
   118→	if (!text) return {
   119→		text: "",
   120→		didStrip: false
   121→	};
   122→	const token = HEARTBEAT_TOKEN;
   123→	const tokenAtEndWithOptionalTrailingPunctuation = new RegExp(`${escapeRegExp(token)}[^\\w]{0,4}$`);
   124→	if (!text.includes(token)) return {
   125→		text,
   126→		didStrip: false
   127→	};
   128→	let didStrip = false;
   129→	let changed = true;
   130→	while (changed) {
   131→		changed = false;
   132→		const next = text.trim();
   133→		if (next.startsWith(token)) {
   134→			text = next.slice(token.length).trimStart();
   135→			didStrip = true;
   136→			changed = true;
   137→			continue;
   138→		}
   139→		if (tokenAtEndWithOptionalTrailingPunctuation.test(next)) {
   140→			const idx = next.lastIndexOf(token);
   141→			const before = next.slice(0, idx).trimEnd();
   142→			if (!before) text = "";
   143→			else text = `${before}${next.slice(idx + token.length).trimStart()}`.trimEnd();
   144→			didStrip = true;
   145→			changed = true;
   146→		}
   147→	}
   148→	return {
   149→		text: text.replace(/\s+/g, " ").trim(),
   150→		didStrip

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


This is compiled JavaScript. Let me look for better type definitions that show the message dispatch flow:


Bash

find /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk -name "*.d.ts" -exec grep -l "dispatchPreparedSlackMessage\|dispatch.*Message" {} \;


grep -r "dispatchMessage\|sendToAgent" /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk --include="*.d.ts" | head -20


     1→import type { OpenClawConfig } from "../config/config.js";
     2→import type { DispatchFromConfigResult } from "./reply/dispatch-from-config.js";
     3→import { type ReplyDispatcher, type ReplyDispatcherOptions, type ReplyDispatcherWithTypingOptions } from "./reply/reply-dispatcher.js";
     4→import type { FinalizedMsgContext, MsgContext } from "./templating.js";
     5→import type { GetReplyOptions } from "./types.js";
     6→export type DispatchInboundResult = DispatchFromConfigResult;
     7→export declare function withReplyDispatcher<T>(params: {
     8→    dispatcher: ReplyDispatcher;
     9→    run: () => Promise<T>;
    10→    onSettled?: () => void | Promise<void>;
    11→}): Promise<T>;
    12→export declare function dispatchInboundMessage(params: {
    13→    ctx: MsgContext | FinalizedMsgContext;
    14→    cfg: OpenClawConfig;
    15→    dispatcher: ReplyDispatcher;
    16→    replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
    17→    replyResolver?: typeof import("./reply.js").getReplyFromConfig;
    18→}): Promise<DispatchInboundResult>;
    19→export declare function dispatchInboundMessageWithBufferedDispatcher(params: {
    20→    ctx: MsgContext | FinalizedMsgContext;
    21→    cfg: OpenClawConfig;
    22→    dispatcherOptions: ReplyDispatcherWithTypingOptions;
    23→    replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
    24→    replyResolver?: typeof import("./reply.js").getReplyFromConfig;
    25→}): Promise<DispatchInboundResult>;
    26→export declare function dispatchInboundMessageWithDispatcher(params: {
    27→    ctx: MsgContext | FinalizedMsgContext;
    28→    cfg: OpenClawConfig;
    29→    dispatcherOptions: ReplyDispatcherOptions;
    30→    replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
    31→    replyResolver?: typeof import("./reply.js").getReplyFromConfig;
    32→}): Promise<DispatchInboundResult>;
    33→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Now let me check the core reply dispatch and how agents are invoked:


find /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/auto-reply -name "*.d.ts" | sort


Let me check the agent-runner to understand the LLM invocation:


     1→import { type SessionEntry } from "../../config/sessions.js";
     2→import type { TypingMode } from "../../config/types.js";
     3→import type { TemplateContext } from "../templating.js";
     4→import { type VerboseLevel } from "../thinking.js";
     5→import type { GetReplyOptions, ReplyPayload } from "../types.js";
     6→import { type FollowupRun, type QueueSettings } from "./queue.js";
     7→import type { TypingController } from "./typing.js";
     8→export declare function runReplyAgent(params: {
     9→    commandBody: string;
    10→    followupRun: FollowupRun;
    11→    queueKey: string;
    12→    resolvedQueue: QueueSettings;
    13→    shouldSteer: boolean;
    14→    shouldFollowup: boolean;
    15→    isActive: boolean;
    16→    isStreaming: boolean;
    17→    opts?: GetReplyOptions;
    18→    typing: TypingController;
    19→    sessionEntry?: SessionEntry;
    20→    sessionStore?: Record<string, SessionEntry>;
    21→    sessionKey?: string;
    22→    storePath?: string;
    23→    defaultModel: string;
    24→    agentCfgContextTokens?: number;
    25→    resolvedVerboseLevel: VerboseLevel;
    26→    isNewSession: boolean;
    27→    blockStreamingEnabled: boolean;
    28→    blockReplyChunking?: {
    29→        minChars: number;
    30→        maxChars: number;
    31→        breakPreference: "paragraph" | "newline" | "sentence";
    32→        flushOnParagraph?: boolean;
    33→    };
    34→    resolvedBlockStreamingBreak: "text_end" | "message_end";
    35→    sessionCtx: TemplateContext;
    36→    shouldInjectGroupIntro: boolean;
    37→    typingMode: TypingMode;
    38→}): Promise<ReplyPayload | ReplyPayload[] | undefined>;
    39→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Now let me create a comprehensive summary by looking at key flow points. Let me check the core message handler to see the full picture:


     1→import type { OpenClawConfig } from "../../config/config.js";
     2→import { getReplyFromConfig } from "../reply.js";
     3→import type { FinalizedMsgContext } from "../templating.js";
     4→import type { GetReplyOptions } from "../types.js";
     5→import type { ReplyDispatcher, ReplyDispatchKind } from "./reply-dispatcher.js";
     6→export type DispatchFromConfigResult = {
     7→    queuedFinal: boolean;
     8→    counts: Record<ReplyDispatchKind, number>;
     9→};
    10→export declare function dispatchReplyFromConfig(params: {
    11→    ctx: FinalizedMsgContext;
    12→    cfg: OpenClawConfig;
    13→    dispatcher: ReplyDispatcher;
    14→    replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
    15→    replyResolver?: typeof getReplyFromConfig;
    16→}): Promise<DispatchFromConfigResult>;
    17→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


     1→import type { HumanDelayConfig } from "../../config/types.js";
     2→import type { GetReplyOptions, ReplyPayload } from "../types.js";
     3→import { type NormalizeReplySkipReason } from "./normalize-reply.js";
     4→import type { ResponsePrefixContext } from "./response-prefix-template.js";
     5→export type ReplyDispatchKind = "tool" | "block" | "final";
     6→type ReplyDispatchErrorHandler = (err: unknown, info: {
     7→    kind: ReplyDispatchKind;
     8→}) => void;
     9→type ReplyDispatchSkipHandler = (payload: ReplyPayload, info: {
    10→    kind: ReplyDispatchKind;
    11→    reason: NormalizeReplySkipReason;
    12→}) => void;
    13→type ReplyDispatchDeliverer = (payload: ReplyPayload, info: {
    14→    kind: ReplyDispatchKind;
    15→}) => Promise<void>;
    16→export type ReplyDispatcherOptions = {
    17→    deliver: ReplyDispatchDeliverer;
    18→    responsePrefix?: string;
    19→    /** Static context for response prefix template interpolation. */
    20→    responsePrefixContext?: ResponsePrefixContext;
    21→    /** Dynamic context provider for response prefix template interpolation.
    22→     * Called at normalization time, after model selection is complete. */
    23→    responsePrefixContextProvider?: () => ResponsePrefixContext;
    24→    onHeartbeatStrip?: () => void;
    25→    onIdle?: () => void;
    26→    onError?: ReplyDispatchErrorHandler;
    27→    onSkip?: ReplyDispatchSkipHandler;
    28→    /** Human-like delay between block replies for natural rhythm. */
    29→    humanDelay?: HumanDelayConfig;
    30→};
    31→export type ReplyDispatcherWithTypingOptions = Omit<ReplyDispatcherOptions, "onIdle"> & {
    32→    onReplyStart?: () => Promise<void> | void;
    33→    onIdle?: () => void;
    34→    /** Called when the typing controller is cleaned up (e.g., on NO_REPLY). */
    35→    onCleanup?: () => void;
    36→};
    37→type ReplyDispatcherWithTypingResult = {
    38→    dispatcher: ReplyDispatcher;
    39→    replyOptions: Pick<GetReplyOptions, "onReplyStart" | "onTypingController" | "onTypingCleanup">;
    40→    markDispatchIdle: () => void;
    41→};
    42→export type ReplyDispatcher = {
    43→    sendToolResult: (payload: ReplyPayload) => boolean;
    44→    sendBlockReply: (payload: ReplyPayload) => boolean;
    45→    sendFinalReply: (payload: ReplyPayload) => boolean;
    46→    waitForIdle: () => Promise<void>;
    47→    getQueuedCounts: () => Record<ReplyDispatchKind, number>;
    48→    markComplete: () => void;
    49→};
    50→export declare function createReplyDispatcher(options: ReplyDispatcherOptions): ReplyDispatcher;
    51→export declare function createReplyDispatcherWithTyping(options: ReplyDispatcherWithTypingOptions): ReplyDispatcherWithTypingResult;
    52→export {};
    53→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Perfect! Now let me check the websocket gateway handling as well:


grep -r "WebSocket\|websocket\|ws.*handler" /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway --include="*.d.ts" | head -20


/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/net.d.ts: * Security check for WebSocket URLs (CWE-319: Cleartext Transmission of Sensitive Information).
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/net.d.ts:export declare function isSecureWebSocketUrl(url: string): boolean;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/server/ws-types.d.ts:import type { WebSocket } from "ws";
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/server/ws-types.d.ts:    socket: WebSocket;


find /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/server -name "*.d.ts" | sort


     1→import type { WebSocket } from "ws";
     2→import type { ConnectParams } from "../protocol/index.js";
     3→export type GatewayWsClient = {
     4→    socket: WebSocket;
     5→    connect: ConnectParams;
     6→    connId: string;
     7→    presenceKey?: string;
     8→    clientIp?: string;
     9→    canvasCapability?: string;
    10→    canvasCapabilityExpiresAtMs?: number;
    11→};
    12→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Excellent! Now let me search the config for ack-related settings and compile the findings:


grep -r "ackReaction\|ack_reaction" /root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config --include="*.d.ts" 2>/dev/null | head -20


/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.discord.d.ts:    ackReaction?: string;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.messages.d.ts:    ackReaction?: string;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.messages.d.ts:    ackReactionScope?: "group-mentions" | "group-all" | "direct" | "all";
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.slack.d.ts:export type SlackReactionNotificationMode = "off" | "own" | "all" | "allowlist";
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.slack.d.ts:    reactionNotifications?: SlackReactionNotificationMode;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.slack.d.ts:    ackReaction?: string;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.telegram.d.ts:    ackReaction?: string;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/types.whatsapp.d.ts:    ackReaction?: WhatsAppAckReactionConfig;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:        ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:        ackReactionScope: z.ZodOptional<z.ZodEnum<{
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:            ackReaction: z.ZodOptional<z.ZodObject<{
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:                ackReaction: z.ZodOptional<z.ZodObject<{
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:            ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:                ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:            ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:                ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:            ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.d.ts:                ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.providers-core.d.ts:    ackReaction: z.ZodOptional<z.ZodString>;
/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/config/zod-schema.providers-core.d.ts:    ackReaction: z.ZodOptional<z.ZodString>;


Perfect! Let me check the messages config more closely:


     1→import type { QueueDropPolicy, QueueMode, QueueModeByProvider } from "./types.queue.js";
     2→import type { TtsConfig } from "./types.tts.js";
     3→export type GroupChatConfig = {
     4→    mentionPatterns?: string[];
     5→    historyLimit?: number;
     6→};
     7→export type DmConfig = {
     8→    historyLimit?: number;
     9→};
    10→export type QueueConfig = {
    11→    mode?: QueueMode;
    12→    byChannel?: QueueModeByProvider;
    13→    debounceMs?: number;
    14→    /** Per-channel debounce overrides (ms). */
    15→    debounceMsByChannel?: InboundDebounceByProvider;
    16→    cap?: number;
    17→    drop?: QueueDropPolicy;
    18→};
    19→export type InboundDebounceByProvider = Record<string, number>;
    20→export type InboundDebounceConfig = {
    21→    debounceMs?: number;
    22→    byChannel?: InboundDebounceByProvider;
    23→};
    24→export type BroadcastStrategy = "parallel" | "sequential";
    25→export type BroadcastConfig = {
    26→    /** Default processing strategy for broadcast peers. */
    27→    strategy?: BroadcastStrategy;
    28→    /**
    29→     * Map peer IDs to arrays of agent IDs that should ALL process messages.
    30→     *
    31→     * Note: the index signature includes `undefined` so `strategy?: ...` remains type-safe.
    32→     */
    33→    [peerId: string]: string[] | BroadcastStrategy | undefined;
    34→};
    35→export type AudioConfig = {
    36→    /** @deprecated Use tools.media.audio.models instead. */
    37→    transcription?: {
    38→        command: string[];
    39→        timeoutSeconds?: number;
    40→    };
    41→};
    42→export type StatusReactionsEmojiConfig = {
    43→    thinking?: string;
    44→    tool?: string;
    45→    coding?: string;
    46→    web?: string;
    47→    done?: string;
    48→    error?: string;
    49→    stallSoft?: string;
    50→    stallHard?: string;
    51→};
    52→export type StatusReactionsTimingConfig = {
    53→    /** Debounce interval for intermediate states (ms). Default: 700. */
    54→    debounceMs?: number;
    55→    /** Soft stall warning timeout (ms). Default: 25000. */
    56→    stallSoftMs?: number;
    57→    /** Hard stall warning timeout (ms). Default: 60000. */
    58→    stallHardMs?: number;
    59→    /** How long to hold done emoji before cleanup (ms). Default: 1500. */
    60→    doneHoldMs?: number;
    61→    /** How long to hold error emoji before cleanup (ms). Default: 2500. */
    62→    errorHoldMs?: number;
    63→};
    64→export type StatusReactionsConfig = {
    65→    /** Enable lifecycle status reactions (default: false). */
    66→    enabled?: boolean;
    67→    /** Override default emojis. */
    68→    emojis?: StatusReactionsEmojiConfig;
    69→    /** Override default timing. */
    70→    timing?: StatusReactionsTimingConfig;
    71→};
    72→export type MessagesConfig = {
    73→    /** @deprecated Use `whatsapp.messagePrefix` (WhatsApp-only inbound prefix). */
    74→    messagePrefix?: string;
    75→    /**
    76→     * Prefix auto-added to all outbound replies.
    77→     *
    78→     * - string: explicit prefix (may include template variables)
    79→     * - special value: `"auto"` derives `[{agents.list[].identity.name}]` for the routed agent (when set)
    80→     *
    81→     * Supported template variables (case-insensitive):
    82→     * - `{model}` - short model name (e.g., `claude-opus-4-6`, `gpt-4o`)
    83→     * - `{modelFull}` - full model identifier (e.g., `anthropic/claude-opus-4-6`)
    84→     * - `{provider}` - provider name (e.g., `anthropic`, `openai`)
    85→     * - `{thinkingLevel}` or `{think}` - current thinking level (`high`, `low`, `off`)
    86→     * - `{identity.name}` or `{identityName}` - agent identity name
    87→     *
    88→     * Example: `"[{model} | think:{thinkingLevel}]"` → `"[claude-opus-4-6 | think:high]"`
    89→     *
    90→     * Unresolved variables remain as literal text (e.g., `{model}` if context unavailable).
    91→     *
    92→     * Default: none
    93→     */
    94→    responsePrefix?: string;
    95→    groupChat?: GroupChatConfig;
    96→    queue?: QueueConfig;
    97→    /** Debounce rapid inbound messages per sender (global + per-channel overrides). */
    98→    inbound?: InboundDebounceConfig;
    99→    /** Emoji reaction used to acknowledge inbound messages (empty disables). */
   100→    ackReaction?: string;
   101→    /** When to send ack reactions. Default: "group-mentions". */
   102→    ackReactionScope?: "group-mentions" | "group-all" | "direct" | "all";
   103→    /** Remove ack reaction after reply is sent (default: false). */
   104→    removeAckAfterReply?: boolean;
   105→    /** Lifecycle status reactions configuration. */
   106→    statusReactions?: StatusReactionsConfig;
   107→    /** When true, suppress ⚠ tool-error warnings from being shown to the user. Default: false. */
   108→    suppressToolErrors?: boolean;
   109→    /** Text-to-speech settings for outbound replies. */
   110→    tts?: TtsConfig;
   111→};
   112→export type NativeCommandsSetting = boolean | "auto";
   113→export type CommandOwnerDisplay = "raw" | "hash";
   114→/**
   115→ * Per-provider allowlist for command authorization.
   116→ * Keys are channel IDs (e.g., "discord", "whatsapp") or "*" for global default.
   117→ * Values are arrays of sender IDs allowed to use commands on that channel.
   118→ */
   119→export type CommandAllowFrom = Record<string, Array<string | number>>;
   120→export type CommandsConfig = {
   121→    /** Enable native command registration when supported (default: "auto"). */
   122→    native?: NativeCommandsSetting;
   123→    /** Enable native skill command registration when supported (default: "auto"). */
   124→    nativeSkills?: NativeCommandsSetting;
   125→    /** Enable text command parsing (default: true). */
   126→    text?: boolean;
   127→    /** Allow bash chat command (`!`; `/bash` alias) (default: false). */
   128→    bash?: boolean;
   129→    /** How long bash waits before backgrounding (default: 2000; 0 backgrounds immediately). */
   130→    bashForegroundMs?: number;
   131→    /** Allow /config command (default: false). */
   132→    config?: boolean;
   133→    /** Allow /debug command (default: false). */
   134→    debug?: boolean;
   135→    /** Allow restart commands/tools (default: true). */
   136→    restart?: boolean;
   137→    /** Enforce access-group allowlists/policies for commands (default: true). */
   138→    useAccessGroups?: boolean;
   139→    /** Explicit owner allowlist for owner-only tools/commands (channel-native IDs). */
   140→    ownerAllowFrom?: Array<string | number>;
   141→    /** How owner IDs are rendered in system prompts. */
   142→    ownerDisplay?: CommandOwnerDisplay;
   143→    /** Secret used to key owner ID hashes when ownerDisplay is "hash". */
   144→    ownerDisplaySecret?: string;
   145→    /**
   146→     * Per-provider allowlist restricting who can use slash commands.
   147→     * If set, overrides the channel's allowFrom for command authorization.
   148→     * Use "*" key for global default, provider-specific keys override the global.
   149→     * Example: { "*": ["user1"], discord: ["user:123"] }
   150→     */
   151→    allowFrom?: CommandAllowFrom;
   152→};
   153→export type ProviderCommandsConfig = {
   154→    /** Override native command registration for this provider (bool or "auto"). */
   155→    native?: NativeCommandsSetting;
   156→    /** Override native skill command registration for this provider (bool or "auto"). */
   157→    nativeSkills?: NativeCommandsSetting;
   158→};
   159→

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>


Perfect! Now I have a complete picture. Let me compile my findings into a comprehensive report:

## Summary Report: OpenClaw Message Handling and LLM Invocation Flow

Based on my thorough exploration of the OpenClaw codebase at `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw`, here's where incoming messages are received, processed, and trigger LLM calls:

### 1. MAIN ENTRY POINT: Gateway and WebSocket Handler

**Binary Location:**
- `/root/.nvm/versions/node/v22.22.0/bin/openclaw` → symlink to `openclaw.mjs`
- **Main entry:** `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/entry.js`

**Gateway Configuration** (`/root/.openclaw/openclaw.json`):
```json
"gateway": {
  "port": 18789,
  "mode": "local",
  "bind": "loopback"
}
```

**WebSocket Types** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/gateway/server/ws-types.d.ts`):
- WebSocket messages handled via `GatewayWsClient` interface with `socket: WebSocket`
- `ConnectParams` protocol for connection handshake

### 2. SLACK MESSAGE HANDLER (Primary Inbound Handler)

**Location:** `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/extensions/slack/`

**Entry Points:**
1. **Plugin Registration** (`index.ts` → `channel.ts`):
   - Slack plugin registers via `api.registerChannel({ plugin: slackPlugin })`
   - Gateway start: `gateway.startAccount()` → calls `monitorSlackProvider()`

2. **Message Reception Flow**:
   ```
   monitorSlackProvider()
     → creates SlackMonitorContext
     → createSlackMessageHandler()
     → prepareSlackMessage()
     → dispatchPreparedSlackMessage()
   ```

**Key Handler Files:**
- `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/slack/monitor/message-handler.d.ts`
  - `createSlackMessageHandler(params)` → `SlackMessageHandler`
  - Handles both `message` and `app_mention` source events

- `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/slack/monitor/message-handler/prepare.d.ts`
  - `prepareSlackMessage()` → `PreparedSlackMessage`
  - Resolves agent routing and prepares context

- `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/slack/monitor/message-handler/dispatch.d.ts`
  - `dispatchPreparedSlackMessage()` → **triggers LLM call**

### 3. ACK/ACKNOWLEDGMENT MECHANISM

**Configuration** (`openclaw.json`):
```json
"messages": {
  "ackReaction": "eyes",           // Emoji reaction sent immediately
  "ackReactionScope": "all"        // When to send: "all", "direct", "group-all", "group-mentions"
}

"channels": {
  "slack": {
    "ackReaction": "eyes"          // Can override per-channel
  }
}
```

**Ack Implementation** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/channels/ack-reactions.d.ts`):
```typescript
type AckReactionScope = "all" | "direct" | "group-all" | "group-mentions" | "off" | "none";

function shouldAckReaction(params: AckReactionGateParams): boolean
function removeAckReactionAfterReply(params: {
    removeAfterReply: boolean;
    ackReactionPromise: Promise<boolean> | null;
    ackReactionValue: string | null;
    remove: () => Promise<void>;
    onError?: (err: unknown) => void;
}): void
```

**Message Preparation** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/slack/monitor/message-handler/types.d.ts`):
```typescript
type PreparedSlackMessage = {
    ackReactionMessageTs?: string;
    ackReactionValue: string;
    ackReactionPromise: Promise<boolean> | null;
    // ... other fields
}
```

**Flow**: Message received → ack reaction added (if config allows) → message queued for processing

### 4. MESSAGE QUEUING AND LLM INVOCATION

**Queue Configuration** (`/root/.openclaw/openclaw.json`):
```json
"messages": {
  "queue": {
    "mode": "...",           // Queue behavior
    "debounceMs": "...",     // Debounce rapid messages
    "cap": "..."             // Max queue size
  }
}
```

**Queue Types** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/auto-reply/reply/queue.d.ts`):
- Queue enqueue/dequeue logic with settings
- Drain queue → dispatch messages

**LLM Trigger Chain**:
```
dispatchReplyFromConfig()
  → getReplyFromConfig()
    → runReplyAgent()
      → [LLM CALL via agent-runner]
        → Complete, streamSimple, etc.
```

**Agent Runner** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/auto-reply/reply/agent-runner.d.ts`):
```typescript
function runReplyAgent(params: {
    commandBody: string;
    sessionKey?: string;
    defaultModel: string;
    isStreaming: boolean;
    isNewSession: boolean;
    // ... 20+ other parameters
}): Promise<ReplyPayload | ReplyPayload[] | undefined>
```

### 5. REPLY DISPATCH AND DELIVERY

**Reply Dispatcher** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/auto-reply/reply/reply-dispatcher.d.ts`):
```typescript
type ReplyDispatchKind = "tool" | "block" | "final";

type ReplyDispatcher = {
    sendToolResult: (payload: ReplyPayload) => boolean;
    sendBlockReply: (payload: ReplyPayload) => boolean;
    sendFinalReply: (payload: ReplyPayload) => boolean;
    waitForIdle: () => Promise<void>;
    getQueuedCounts: () => Record<ReplyDispatchKind, number>;
    markComplete: () => void;
};
```

**Dispatch Result** (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/auto-reply/dispatch.d.ts`):
```typescript
function dispatchInboundMessage(params: {
    ctx: MsgContext | FinalizedMsgContext;
    cfg: OpenClawConfig;
    dispatcher: ReplyDispatcher;
    replyOptions?: Omit<GetReplyOptions, "onToolResult" | "onBlockReply">;
}): Promise<DispatchInboundResult>
```

**Post-LLM Flow**:
- Tool results sent
- Block replies sent (streaming chunks)
- Final reply sent (complete message)
- Optionally: remove ack reaction after reply (`removeAckAfterReply`)

### 6. KEY CONFIGURATION FILES

**Main Config:** `/root/.openclaw/openclaw.json`
- `agents.defaults.model` - primary/fallback LLM models
- `agents.defaults.maxConcurrent` - concurrent message processing (default: 4)
- `channels.slack.mode: "socket"` - WebSocket mode (not webhook)
- `channels.slack.streaming: "partial"` - streaming mode
- `messages.ackReaction` & `messages.ackReactionScope` - ack behavior
- `gateway.port: 18789` - local gateway port

**Plugin Config:** `/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/extensions/slack/openclaw.plugin.json`

### 7. MESSAGE FLOW DIAGRAM

```
┌─────────────────────────────────────┐
│   Slack App Event (WebSocket)       │
│   - message_create                  │
│   - app_mention                     │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  monitorSlackProvider()             │
│  - App setup via Slack Bolt         │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  createSlackMessageHandler()        │
│  - Parses message event             │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  shouldAckReaction() check          │
│  ↓ YES                              │
│  - React with emoji (e.g., 👀)      │
│  - Store ackReactionPromise         │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  prepareSlackMessage()              │
│  - Resolve agent route              │
│  - Build FinalizedMsgContext        │
│  - Create ReplyDispatcher           │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  dispatchPreparedSlackMessage()     │
│  → dispatchInboundMessage()         │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  dispatchReplyFromConfig()          │
│  → getReplyFromConfig()             │
└──────────────┬──────────────────────┘
               │
               ▼
┌──────────────────────────────────────┐
│  🔴 runReplyAgent()                  │
│  ┌─ LLM CALL TRIGGERED ─┐           │
│  │ complete() or         │           │
│  │ streamSimple()        │           │
│  │ via provider-ai       │           │
│  └───────────────────────┘           │
│  - Uses model from config            │
│  - Loads session context             │
│  - Executes tools if needed          │
└──────────────┬──────────────────────┘
               │
        ┌──────┴──────┐
        ▼             ▼
   [Tool Calls]  [Final Response]
        │             │
        └──────┬──────┘
               ▼
┌─────────────────────────────────────┐
│  dispatcher.sendToolResult()        │
│  dispatcher.sendBlockReply()        │
│  dispatcher.sendFinalReply()        │
│  - Send chunks back to Slack        │
└──────────────┬──────────────────────┘
               │
               ▼
┌─────────────────────────────────────┐
│  removeAckReactionAfterReply()      │
│  (if configured)                    │
│  - Remove emoji once done           │
└─────────────────────────────────────┘
```

### 8. PLUGIN HOOK SYSTEM

Available hooks (`/root/.nvm/versions/node/v22.22.0/lib/node_modules/openclaw/dist/plugin-sdk/plugins/types.d.ts`):
```typescript
type PluginHookName =
  | "message_received"        // After message reaches handler
  | "llm_input"              // Before LLM call
  | "llm_output"             // After LLM call
  | "agent_end"              // When agent turn complete
  | "message_sending"        // Before sending reply
  | "message_sent"           // After reply delivered
  | "before_tool_call"
  | "after_tool_call"
  // ... 15+ more
```

This is the complete message-to-LLM flow in OpenClaw. The ack reaction provides immediate visual feedback, while the queue and dispatcher system manage concurrent processing of multiple messages with proper sequencing and delivery.