UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

1,105 lines (1,077 loc) 2.25 MB
import { A as buildBootstrapContextFiles, B as normalizeThinkLevel, C as isLikelyContextOverflowError, D as parseImageDimensionError, E as isTimeoutErrorMessage, F as formatXHighModelHint, H as normalizeVerboseLevel, M as resolveBootstrapMaxChars, N as sanitizeGoogleTurnOrdering, O as parseImageSizeError, P as formatThinkingLevels, R as normalizeElevatedLevel, S as isFailoverErrorMessage, T as isRawApiErrorPayload, U as resolveResponseUsageMode, V as normalizeUsageDisplay, W as supportsXHighThinking, _ as isAuthAssistantError, a as isMessagingToolDuplicateNormalized, b as isContextOverflowError, c as sanitizeImageBlocks, d as isAntigravityClaude, f as isGoogleModelApi, g as getApiErrorPayloadFingerprint, h as formatRawAssistantErrorForUi, j as ensureSessionHeader, k as sanitizeUserFacingText, l as sanitizeToolResultImages, m as formatAssistantErrorText, n as validateGeminiTurns, o as normalizeTextForComparison, p as classifyFailoverReason, r as pickFallbackThinkingLevel, s as sanitizeSessionMessagesImages, t as validateAnthropicTurns, u as downgradeOpenAIReasoningBlocks, v as isCloudCodeAssistFormatError, w as isRateLimitAssistantError, x as isFailoverAssistantError, y as isCompactionFailureError, z as normalizeReasoningLevel } from "./pi-embedded-helpers-CC00lEFI.js"; import { g as resolveStateDir, r as STATE_DIR, t as CONFIG_PATH } from "./paths-BDd7_JUB.js"; import { A as buildAgentPeerSessionKey, B as isAcpSessionKey, C as loadWorkspaceBootstrapFiles, D as DEFAULT_AGENT_ID, E as DEFAULT_ACCOUNT_ID$1, F as resolveAgentIdFromSessionKey, H as parseAgentSessionKey, I as resolveThreadSessionKeys, L as sanitizeAgentId, M as normalizeAccountId$3, N as normalizeAgentId, O as DEFAULT_MAIN_KEY, P as normalizeMainKey, S as filterBootstrapFilesForSession, U as resolveThreadParentSessionKey, V as isSubagentSessionKey, c as resolveDefaultAgentId, f as DEFAULT_AGENT_WORKSPACE_DIR, i as resolveAgentModelFallbacksOverride, j as buildGroupHistoryKey, k as buildAgentMainSessionKey, l as resolveSessionAgentId, n as resolveAgentConfig, o as resolveAgentSkillsFilter, p as DEFAULT_BOOTSTRAP_FILENAME, r as resolveAgentDir, s as resolveAgentWorkspaceDir, t as listAgentIds, u as resolveSessionAgentIds, x as ensureAgentWorkspace } from "./agent-scope-CrgUOY3f.js"; import { A as logVerbose, D as info, E as danger, F as warn, I as colorize, L as isRich, M as setVerbose, N as shouldLogVerbose, P as success, R as theme, T as setActivePluginRegistry, U as normalizeLogLevel, b as normalizeAnyChannelId, c as defaultRuntime, m as CHAT_CHANNEL_ORDER, t as createSubsystemLogger, w as requireActivePluginRegistry, x as normalizeChannelId, z as getChildLogger } from "./subsystem-46MXi6Ip.js"; import { _ as shortenHomePath, b as toWhatsappJid, d as normalizeE164, g as shortenHomeInString, h as resolveUserPath, l as isSelfChatMode, m as resolveJidToE164, r as clampInt, t as CONFIG_DIR, u as jidToE164, v as sleep, x as truncateUtf16Safe, y as sliceUtf16Safe } from "./utils-Dg0Xbl6w.js"; import { a as logDebug, c as logWarn, i as spawnWithFallback, n as runExec, o as logError, r as formatSpawnError, s as logInfo, t as runCommandWithTimeout } from "./exec-CTo4hK94.js"; import { t as resolveOpenClawPackageRoot } from "./openclaw-root-CJKDUIBP.js"; import { A as getCustomProviderApiKey, F as resolveModelAuthMode, G as resolveAuthProfileOrder, J as markAuthProfileFailure, L as getShellPathFromLoginShell, M as resolveApiKeyForProvider, P as resolveEnvApiKey, Y as markAuthProfileUsed, Z as resolveApiKeyForProfile, a as modelKey, at as listProfilesForProvider, bt as DEFAULT_MODEL, f as resolveModelRefFromString, g as normalizeGoogleModelId, gt as resolveAuthProfileDisplayLabel, ht as resolveOpenClawAgentDir, i as isCliProvider, j as requireApiKey, k as getApiKeyForModel, l as resolveConfiguredModelRef, lt as ensureAuthProfileStore, mt as resolveAuthStorePathForDisplay, n as buildModelAliasIndex, o as normalizeProviderId, ot as markAuthProfileGood, p as resolveThinkingDefault, q as isProfileInCooldown, s as parseModelRef, t as buildAllowedModelSet, u as resolveDefaultModelForAgent, xt as DEFAULT_PROVIDER, yt as DEFAULT_CONTEXT_TOKENS, z as resolveShellEnvFallbackTimeoutMs } from "./model-selection-Cp1maz7B.js"; import { a as saveJsonFile, i as loadJsonFile } from "./github-copilot-token-VZsS4013.js"; import { t as formatCliCommand } from "./command-format-BQK1OIvH.js"; import { t as parseBooleanValue$1 } from "./boolean-CE7i9tBR.js"; import { t as isTruthyEnvValue } from "./env-DOcCob95.js"; import { A as resolveAgentMaxConcurrent, C as parseConfigPath, M as VERSION, S as getConfigValueAtPath, T as unsetConfigValueAtPath, a as readConfigFileSnapshot, b as setConfigOverride, d as TELEGRAM_COMMAND_NAME_PATTERN, f as normalizeTelegramCommandName, g as validateJsonSchemaValue, h as parseDurationMs, l as validateConfigObjectWithPlugins, m as isSafeExecutableValue, o as resolveConfigSnapshotHash, p as resolveTelegramCustomCommands, r as loadConfig, s as writeConfigFile, v as getConfigOverrides, w as setConfigValueAtPath, x as unsetConfigOverride, y as resetConfigOverrides } from "./config-qgIz1lbh.js"; import { c as resolveEnableState, l as resolveMemorySlotDecision, n as discoverOpenClawPlugins, s as normalizePluginsConfig, t as loadPluginManifestRegistry } from "./manifest-registry-BFpLJJDB.js"; import { _ as listEnabledDiscordAccounts, a as normalizeWhatsAppTarget, b as normalizeChatType, c as resolveTelegramAccount, d as listBindings, g as resolveSlackBotToken, h as resolveSlackAppToken, i as isWhatsAppGroupJid, l as resolveTelegramToken, n as listChannelPlugins, o as listEnabledTelegramAccounts, p as resolveSlackAccount, r as normalizeChannelId$1, s as listTelegramAccountIds, t as getChannelPlugin, v as resolveDiscordAccount, y as normalizeDiscordToken } from "./plugins-D1CxUobm.js"; import { A as resolveSessionResetPolicy, C as normalizeDeliveryContext, D as resolveSessionKey$1, H as listChannelDocks, J as resolveIMessageAccount, K as listEnabledSignalAccounts, L as resolveMainSessionKey, M as resolveThreadFlag, N as DEFAULT_RESET_TRIGGERS, O as evaluateSessionFreshness, P as canonicalizeMainSessionAlias, S as mergeDeliveryContext, U as resolveChannelGroupPolicy, V as getChannelDock, W as resolveChannelGroupRequireMention, X as resolveGroupSessionKey, Y as buildGroupDisplayName, Z as resolveSandboxConfigForAgent, _ as updateSessionStoreEntry, a as ensureSandboxWorkspaceForSession, at as resolveToolProfilePolicy, b as deliveryContextFromSession, c as resolveSandboxRuntimeStatus, d as loadSessionStore, et as buildPluginToolGroups, f as readSessionUpdatedAt, g as updateSessionStore, h as updateLastRoute, it as normalizeToolName, j as resolveSessionResetType, k as resolveChannelResetConfig, l as appendAssistantMessageToSessionTranscript, nt as expandPolicyWithPluginGroups, o as resolveSandboxContext, ot as stripPluginOnlyAllowlist, p as recordSessionMetaFromInbound, q as resolveSignalAccount, tt as collectExplicitAllowlist, ut as resolveConversationLabel, v as isCacheEnabled, w as normalizeSessionDeliveryFields, x as deliveryContextKey, y as resolveCacheTtlMs$1, z as deriveSessionMetaPatch } from "./sandbox-BXUfp_qv.js"; import { _ as minimaxUnderstandImage, a as resolveProviderVisionModelFromConfig, c as extractThinkingFromTaggedStream, d as inferToolMetaFromArgs, f as promoteThinkingTagsToBlocks, g as ensureOpenClawModelsJson, h as stripThinkingTagsFromText, i as decodeDataUrl, l as extractThinkingFromTaggedText, m as stripMinimaxToolCallXml, n as coerceImageAssistantText, o as extractAssistantText$1, p as stripDowngradedToolCallText, r as coerceImageModelConfig, s as extractAssistantThinking, t as describeImageWithModel, u as formatReasoningMessage } from "./image-ClOB6QDJ.js"; import { i as discoverModels, r as discoverAuthStorage } from "./pi-model-discovery-DjGamP_B.js"; import { E as formatUncaughtError, T as formatErrorMessage, k as DEFAULT_AI_SNAPSHOT_MAX_CHARS, w as extractErrorCode } from "./chrome-D2LUApAY.js"; import { a as resolveSkillsPromptForRun, i as loadWorkspaceSkillEntries, l as applySkillEnvOverrides, n as buildWorkspaceSkillCommandSpecs, r as buildWorkspaceSkillSnapshot, s as resolvePluginSkillDirs, u as applySkillEnvOverridesFromSnapshot } from "./skills-C4b1FA1e.js"; import { c as saveMediaBuffer, d as getFileExtension, f as imageMimeFromFormat, g as MAX_IMAGE_BYTES, h as kindFromMime, l as detectMime, m as isGifMedia, o as resizeToJpeg, p as isAudioFileName, r as getImageMetadata, s as getMediaDir, u as extensionForMime, v as mediaKindFromMime, y as SsrFBlockedError } from "./routes-Ds-tIZFJ.js"; import { i as resolveBrowserConfig } from "./server-context-D2cv-pIA.js"; import { a as isInternalMessageChannel, c as listDeliverableMessageChannels, d as resolveMessageChannel, f as GATEWAY_CLIENT_IDS, l as normalizeMessageChannel, m as GATEWAY_CLIENT_NAMES, n as isDeliverableMessageChannel, o as isMarkdownCapableMessageChannel, p as GATEWAY_CLIENT_MODES, t as INTERNAL_MESSAGE_CHANNEL, u as resolveGatewayMessageChannel } from "./message-channel-CQGWXVL4.js"; import { a as logoutWeb, d as webAuthExists, i as logWebSelfId, n as resolveWhatsAppAccount, r as getWebAuthAgeMs, s as readWebSelfId } from "./accounts-BlHoTziG.js"; import { a as resolveSessionTranscriptsDirForAgent, n as resolveSessionFilePath, o as resolveStorePath, r as resolveSessionTranscriptPath } from "./paths-50eo6DV6.js"; import { t as emitSessionTranscriptUpdate } from "./transcript-events-fUhPZcB5.js"; import { n as redactSensitiveText } from "./redact-BKh-zp-c.js"; import { n as resolveToolDisplay } from "./tool-display-rIUh61kT.js"; import { A as loadWebMedia, B as findFenceSpanAt, C as signalRpcRequest, D as chunkMarkdownIR, E as wrapFetchWithAbortSignal, F as chunkMarkdownTextWithMode, G as isSilentReplyText, H as parseFenceSpans, I as chunkText, J as fetchWithSsrFGuard, K as MediaFetchError, L as chunkTextWithMode, M as resolveMarkdownTableMode, N as chunkByNewline, O as markdownToIR, P as chunkMarkdownText, R as resolveChunkMode, S as signalCheck, T as resolveFetch, U as HEARTBEAT_TOKEN, V as isSafeFenceBreak, W as SILENT_REPLY_TOKEN, _ as splitMediaFromOutput, a as normalizeReplyPayloadsForDelivery, b as sendReadReceiptSignal, c as filterMessagingToolDuplicates, d as createReplyToModeFilterForChannel, f as resolveReplyToMode, g as parseReplyDirectives, h as normalizeTargetForProvider, j as loadWebMediaRaw, k as markdownToIRWithMeta, l as isRenderablePayload, m as normalizeChannelTargetInput, o as applyReplyTagsToPayload, p as buildTargetResolverSignature, q as fetchRemoteMedia, s as applyReplyThreading, t as deliverOutboundPayloads, u as shouldSuppressMessagingToolReplies, v as parseInlineDirectives$1, w as streamSignalEvents, x as sendTypingSignal, y as sendMessageSignal, z as resolveTextChunkLimit } from "./deliver-Bsvrattg.js"; import { i as getMachineDisplayName, n as isWSL, t as createBrowserRouteDispatcher } from "./dispatcher-BNB5aCZ6.js"; import { i as resolveMemorySearchConfig, n as resolveRetryConfig, r as retryAsync } from "./manager-BArueSTR.js"; import { c as listMemoryFiles, l as normalizeExtraMemoryPaths } from "./sqlite-Dz6S6ijV.js"; import { C as parseCommandArgs, D as shouldHandleTextCommands, E as serializeCommandArgs, S as normalizeCommandBody, T as resolveCommandArgMenu, _ as findCommandByNativeName, b as listNativeCommandSpecs, f as estimateUsageCost, g as buildCommandTextFromArgs, h as resolveModelCostConfig, m as formatUsd$1, o as extractTextFromMessage, p as formatTokenCount$2, t as buildChannelSummary, v as listChatCommands, w as resolveCommandArgChoices, x as listNativeCommandSpecsForConfig, y as listChatCommandsForConfig } from "./channel-summary-C8GoEKgH.js"; import { Tt as SESSION_LABEL_MAX_LENGTH, t as GatewayClient } from "./client-zqMhLTAX.js"; import { t as pickPrimaryTailnetIPv4 } from "./tailnet-Bk5cGmwE.js"; import { n as callGateway, r as randomIdempotencyKey } from "./call-CPBhMXxo.js"; import { a as getStatusCode$1, i as formatError$1, n as waitForWebLogin, o as waitForWaConnection, r as createWaSocket, t as startWebLoginWithQr } from "./login-qr-C2H_iQJU.js"; import { a as removeChannelAllowFromStoreEntry, c as listPairingChannels, i as readChannelAllowFromStore, o as upsertChannelPairingRequest, t as addChannelAllowFromStoreEntry } from "./pairing-store-BnMngoWQ.js"; import { t as formatDocsLink } from "./links-C9fyAH-V.js"; import { i as withManager, t as formatErrorMessage$1 } from "./cli-utils-CukoNm8O.js"; import { n as withProgress, r as withProgressTotals } from "./progress-uNDQDtGB.js"; import { a as resolveSubagentToolPolicy, c as resolveNativeSkillsEnabled, i as resolveGroupToolPolicy, n as isToolAllowedByPolicies, o as isNativeCommandsExplicitlyDisabled, r as resolveEffectiveToolPolicy, s as resolveNativeCommandsEnabled, t as filterToolsByPolicy } from "./pi-tools.policy-DleRi9eC.js"; import { r as stylePromptTitle } from "./prompt-style-gfROyHgB.js"; import { t as resolvePairingIdLabel } from "./pairing-labels-DK2aLSd2.js"; import { a as evaluateShellAllowlist, d as requiresExecApproval, f as resolveExecApprovals, h as resolveSafeBins, o as maxAsk, p as resolveExecApprovalsFromFile, s as minSecurity, t as addAllowlistEntry, u as recordAllowlistUse } from "./exec-approvals-CK-Umdr3.js"; import { a as canvasSnapshotTempPath, c as parseCameraClipPayload, d as buildNodeShellCommand, i as parseEnvPairs, l as parseCameraSnapPayload, n as screenRecordTempPath, o as parseCanvasSnapshotPayload, r as writeScreenRecordToFile, s as cameraTempPath, t as parseScreenRecordPayload, u as writeBase64ToFile } from "./nodes-screen-Ln98EX_f.js"; import { r as startBrowserControlServiceFromConfig, t as createBrowserControlContext } from "./control-service-BW5sW2U1.js"; import { t as parseAbsoluteTimeMs } from "./parse-DLFPuO7w.js"; import { n as formatDoctorNonInteractiveHint, s as writeRestartSentinel } from "./restart-sentinel-CdcBcziq.js"; import { d as resolveGatewaySystemdServiceName, l as resolveGatewayLaunchAgentLabel } from "./constants-3er_81qc.js"; import { n as resolveMessageChannelSelection, t as listConfiguredMessageChannels } from "./channel-selection-BCn8_qun.js"; import { t as parseTimeoutMs } from "./parse-timeout-CmBmmqZZ.js"; import { createRequire } from "node:module"; import process$1 from "node:process"; import { fileURLToPath } from "node:url"; import os, { homedir, tmpdir } from "node:os"; import path from "node:path"; import fs, { constants, existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs"; import fs$1 from "node:fs/promises"; import { execSync, spawn, spawnSync } from "node:child_process"; import { inspect } from "node:util"; import crypto, { randomUUID } from "node:crypto"; import { complete, completeSimple, streamSimple } from "@mariozechner/pi-ai"; import { CURRENT_SESSION_VERSION, SessionManager, SettingsManager, codingTools, createAgentSession, createEditTool, createReadTool, createWriteTool, estimateTokens, readTool } from "@mariozechner/pi-coding-agent"; import { createServer } from "node:http"; import { ProxyAgent, fetch as fetch$1 } from "undici"; import { Buffer as Buffer$1 } from "node:buffer"; import * as net$1 from "node:net"; import { EdgeTTS } from "node-edge-tts"; import { createJiti } from "jiti"; import { Type } from "@sinclair/typebox"; import chokidar from "chokidar"; import { WebClient } from "@slack/web-api"; import { ApplicationCommandOptionType, ButtonStyle, ChannelType, PermissionFlagsBits, Routes } from "discord-api-types/v10"; import { Button, ChannelType as ChannelType$1, Client, Command, MessageCreateListener, MessageReactionAddListener, MessageReactionRemoveListener, MessageType, PresenceUpdateListener, RateLimitError, RequestClient, Row } from "@buape/carbon"; import { PollLayoutType } from "discord-api-types/payloads/v10"; import { API_CONSTANTS, Bot, GrammyError, HttpError, InputFile, webhookCallback } from "grammy"; import { setTimeout as setTimeout$1 } from "node:timers/promises"; import { DisconnectReason, downloadMediaMessage, extractMessageContent, getContentType, isJidGroup, normalizeMessageContent } from "@whiskeysockets/baileys"; import { cancel, isCancel } from "@clack/prompts"; import { GatewayIntents, GatewayPlugin } from "@buape/carbon/gateway"; import readline, { createInterface } from "node:readline"; 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/auto-reply/reply/exec/directive.ts function normalizeExecHost$1(value) { const normalized = value?.trim().toLowerCase(); if (normalized === "sandbox" || normalized === "gateway" || normalized === "node") return normalized; } function normalizeExecSecurity$1(value) { const normalized = value?.trim().toLowerCase(); if (normalized === "deny" || normalized === "allowlist" || normalized === "full") return normalized; } function normalizeExecAsk$1(value) { const normalized = value?.trim().toLowerCase(); if (normalized === "off" || normalized === "on-miss" || normalized === "always") return normalized; } function parseExecDirectiveArgs(raw) { let i = 0; const len = raw.length; while (i < len && /\s/.test(raw[i])) i += 1; if (raw[i] === ":") { i += 1; while (i < len && /\s/.test(raw[i])) i += 1; } let consumed = i; let execHost; let execSecurity; let execAsk; let execNode; let rawExecHost; let rawExecSecurity; let rawExecAsk; let rawExecNode; let hasExecOptions = false; let invalidHost = false; let invalidSecurity = false; let invalidAsk = false; let invalidNode = false; const takeToken = () => { if (i >= len) return null; const start = i; while (i < len && !/\s/.test(raw[i])) i += 1; if (start === i) return null; const token = raw.slice(start, i); while (i < len && /\s/.test(raw[i])) i += 1; return token; }; const splitToken = (token) => { const eq = token.indexOf("="); const colon = token.indexOf(":"); const idx = eq === -1 ? colon : colon === -1 ? eq : Math.min(eq, colon); if (idx === -1) return null; const key = token.slice(0, idx).trim().toLowerCase(); const value = token.slice(idx + 1).trim(); if (!key) return null; return { key, value }; }; while (i < len) { const token = takeToken(); if (!token) break; const parsed = splitToken(token); if (!parsed) break; const { key, value } = parsed; if (key === "host") { rawExecHost = value; execHost = normalizeExecHost$1(value); if (!execHost) invalidHost = true; hasExecOptions = true; consumed = i; continue; } if (key === "security") { rawExecSecurity = value; execSecurity = normalizeExecSecurity$1(value); if (!execSecurity) invalidSecurity = true; hasExecOptions = true; consumed = i; continue; } if (key === "ask") { rawExecAsk = value; execAsk = normalizeExecAsk$1(value); if (!execAsk) invalidAsk = true; hasExecOptions = true; consumed = i; continue; } if (key === "node") { rawExecNode = value; const trimmed = value.trim(); if (!trimmed) invalidNode = true; else execNode = trimmed; hasExecOptions = true; consumed = i; continue; } break; } return { consumed, execHost, execSecurity, execAsk, execNode, rawExecHost, rawExecSecurity, rawExecAsk, rawExecNode, hasExecOptions, invalidHost, invalidSecurity, invalidAsk, invalidNode }; } function extractExecDirective(body) { if (!body) return { cleaned: "", hasDirective: false, hasExecOptions: false, invalidHost: false, invalidSecurity: false, invalidAsk: false, invalidNode: false }; const match = /(?:^|\s)\/exec(?=$|\s|:)/i.exec(body); if (!match) return { cleaned: body.trim(), hasDirective: false, hasExecOptions: false, invalidHost: false, invalidSecurity: false, invalidAsk: false, invalidNode: false }; const start = match.index + match[0].indexOf("/exec"); const argsStart = start + 5; const parsed = parseExecDirectiveArgs(body.slice(argsStart)); return { cleaned: `${body.slice(0, start)} ${body.slice(argsStart + parsed.consumed)}`.replace(/\s+/g, " ").trim(), hasDirective: true, execHost: parsed.execHost, execSecurity: parsed.execSecurity, execAsk: parsed.execAsk, execNode: parsed.execNode, rawExecHost: parsed.rawExecHost, rawExecSecurity: parsed.rawExecSecurity, rawExecAsk: parsed.rawExecAsk, rawExecNode: parsed.rawExecNode, hasExecOptions: parsed.hasExecOptions, invalidHost: parsed.invalidHost, invalidSecurity: parsed.invalidSecurity, invalidAsk: parsed.invalidAsk, invalidNode: parsed.invalidNode }; } //#endregion //#region src/auto-reply/reply/directives.ts const escapeRegExp$4 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const matchLevelDirective = (body, names) => { const namePattern = names.map(escapeRegExp$4).join("|"); const match = body.match(new RegExp(`(?:^|\\s)\\/(?:${namePattern})(?=$|\\s|:)`, "i")); if (!match || match.index === void 0) return null; const start = match.index; let end = match.index + match[0].length; let i = end; while (i < body.length && /\s/.test(body[i])) i += 1; if (body[i] === ":") { i += 1; while (i < body.length && /\s/.test(body[i])) i += 1; } const argStart = i; while (i < body.length && /[A-Za-z-]/.test(body[i])) i += 1; const rawLevel = i > argStart ? body.slice(argStart, i) : void 0; end = i; return { start, end, rawLevel }; }; const extractLevelDirective = (body, names, normalize) => { const match = matchLevelDirective(body, names); if (!match) return { cleaned: body.trim(), hasDirective: false }; const rawLevel = match.rawLevel; const level = normalize(rawLevel); return { cleaned: body.slice(0, match.start).concat(" ").concat(body.slice(match.end)).replace(/\s+/g, " ").trim(), level, rawLevel, hasDirective: true }; }; const extractSimpleDirective = (body, names) => { const namePattern = names.map(escapeRegExp$4).join("|"); const match = body.match(new RegExp(`(?:^|\\s)\\/(?:${namePattern})(?=$|\\s|:)(?:\\s*:\\s*)?`, "i")); return { cleaned: match ? body.replace(match[0], " ").replace(/\s+/g, " ").trim() : body.trim(), hasDirective: Boolean(match) }; }; function extractThinkDirective(body) { if (!body) return { cleaned: "", hasDirective: false }; const extracted = extractLevelDirective(body, [ "thinking", "think", "t" ], normalizeThinkLevel); return { cleaned: extracted.cleaned, thinkLevel: extracted.level, rawLevel: extracted.rawLevel, hasDirective: extracted.hasDirective }; } function extractVerboseDirective(body) { if (!body) return { cleaned: "", hasDirective: false }; const extracted = extractLevelDirective(body, ["verbose", "v"], normalizeVerboseLevel); return { cleaned: extracted.cleaned, verboseLevel: extracted.level, rawLevel: extracted.rawLevel, hasDirective: extracted.hasDirective }; } function extractElevatedDirective(body) { if (!body) return { cleaned: "", hasDirective: false }; const extracted = extractLevelDirective(body, ["elevated", "elev"], normalizeElevatedLevel); return { cleaned: extracted.cleaned, elevatedLevel: extracted.level, rawLevel: extracted.rawLevel, hasDirective: extracted.hasDirective }; } function extractReasoningDirective(body) { if (!body) return { cleaned: "", hasDirective: false }; const extracted = extractLevelDirective(body, ["reasoning", "reason"], normalizeReasoningLevel); return { cleaned: extracted.cleaned, reasoningLevel: extracted.level, rawLevel: extracted.rawLevel, hasDirective: extracted.hasDirective }; } function extractStatusDirective(body) { if (!body) return { cleaned: "", hasDirective: false }; return extractSimpleDirective(body, ["status"]); } //#endregion //#region src/agents/timeout.ts const DEFAULT_AGENT_TIMEOUT_SECONDS = 600; const normalizeNumber = (value) => typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : void 0; function resolveAgentTimeoutSeconds(cfg) { const seconds = normalizeNumber(cfg?.agents?.defaults?.timeoutSeconds) ?? DEFAULT_AGENT_TIMEOUT_SECONDS; return Math.max(seconds, 1); } function resolveAgentTimeoutMs(opts) { const minMs = Math.max(normalizeNumber(opts.minMs) ?? 1, 1); const defaultMs = resolveAgentTimeoutSeconds(opts.cfg) * 1e3; const NO_TIMEOUT_MS = 720 * 60 * 60 * 1e3; const overrideMs = normalizeNumber(opts.overrideMs); if (overrideMs !== void 0) { if (overrideMs === 0) return NO_TIMEOUT_MS; if (overrideMs < 0) return defaultMs; return Math.max(overrideMs, minMs); } const overrideSeconds = normalizeNumber(opts.overrideSeconds); if (overrideSeconds !== void 0) { if (overrideSeconds === 0) return NO_TIMEOUT_MS; if (overrideSeconds < 0) return defaultMs; return Math.max(overrideSeconds * 1e3, minMs); } return Math.max(defaultMs, minMs); } //#endregion //#region src/channels/sender-label.ts function normalize(value) { const trimmed = value?.trim(); return trimmed ? trimmed : void 0; } function resolveSenderLabel(params) { const name = normalize(params.name); const username = normalize(params.username); const tag = normalize(params.tag); const e164 = normalize(params.e164); const id = normalize(params.id); const display = name ?? username ?? tag ?? ""; const idPart = e164 ?? id ?? ""; if (display && idPart && display !== idPart) return `${display} (${idPart})`; return display || idPart || null; } function listSenderLabelCandidates(params) { const candidates = /* @__PURE__ */ new Set(); const name = normalize(params.name); const username = normalize(params.username); const tag = normalize(params.tag); const e164 = normalize(params.e164); const id = normalize(params.id); if (name) candidates.add(name); if (username) candidates.add(username); if (tag) candidates.add(tag); if (e164) candidates.add(e164); if (id) candidates.add(id); const resolved = resolveSenderLabel(params); if (resolved) candidates.add(resolved); return Array.from(candidates); } //#endregion //#region src/auto-reply/reply/inbound-sender-meta.ts function formatInboundBodyWithSenderMeta(params) { const body = params.body; if (!body.trim()) return body; const chatType = normalizeChatType(params.ctx.ChatType); if (!chatType || chatType === "direct") return body; if (hasSenderMetaLine(body, params.ctx)) return body; const senderLabel = resolveSenderLabel({ name: params.ctx.SenderName, username: params.ctx.SenderUsername, tag: params.ctx.SenderTag, e164: params.ctx.SenderE164, id: params.ctx.SenderId }); if (!senderLabel) return body; return `${body}\n[from: ${senderLabel}]`; } function hasSenderMetaLine(body, ctx) { if (/(^|\n)\[from:/i.test(body)) return true; const candidates = listSenderLabelCandidates({ name: ctx.SenderName, username: ctx.SenderUsername, tag: ctx.SenderTag, e164: ctx.SenderE164, id: ctx.SenderId }); if (candidates.length === 0) return false; return candidates.some((candidate) => { const escaped = escapeRegExp$3(candidate); return new RegExp(`(^|\\n|\\]\\s*)${escaped}:\\s`, "i").test(body); }); } function escapeRegExp$3(value) { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } //#endregion //#region src/auto-reply/reply/inbound-text.ts function normalizeInboundTextNewlines(input) { return input.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("\\n", "\n"); } //#endregion //#region src/auto-reply/reply/inbound-context.ts function normalizeTextField(value) { if (typeof value !== "string") return; return normalizeInboundTextNewlines(value); } function finalizeInboundContext(ctx, opts = {}) { const normalized = ctx; normalized.Body = normalizeInboundTextNewlines(typeof normalized.Body === "string" ? normalized.Body : ""); normalized.RawBody = normalizeTextField(normalized.RawBody); normalized.CommandBody = normalizeTextField(normalized.CommandBody); normalized.Transcript = normalizeTextField(normalized.Transcript); normalized.ThreadStarterBody = normalizeTextField(normalized.ThreadStarterBody); if (Array.isArray(normalized.UntrustedContext)) normalized.UntrustedContext = normalized.UntrustedContext.map((entry) => normalizeInboundTextNewlines(entry)).filter((entry) => Boolean(entry)); const chatType = normalizeChatType(normalized.ChatType); if (chatType && (opts.forceChatType || normalized.ChatType !== chatType)) normalized.ChatType = chatType; normalized.BodyForAgent = normalizeInboundTextNewlines(opts.forceBodyForAgent ? normalized.Body : normalized.BodyForAgent ?? normalized.Body); normalized.BodyForCommands = normalizeInboundTextNewlines(opts.forceBodyForCommands ? normalized.CommandBody ?? normalized.RawBody ?? normalized.Body : normalized.BodyForCommands ?? normalized.CommandBody ?? normalized.RawBody ?? normalized.Body); const explicitLabel = normalized.ConversationLabel?.trim(); if (opts.forceConversationLabel || !explicitLabel) { const resolved = resolveConversationLabel(normalized)?.trim(); if (resolved) normalized.ConversationLabel = resolved; } else normalized.ConversationLabel = explicitLabel; normalized.Body = formatInboundBodyWithSenderMeta({ ctx: normalized, body: normalized.Body }); normalized.BodyForAgent = formatInboundBodyWithSenderMeta({ ctx: normalized, body: normalized.BodyForAgent }); normalized.CommandAuthorized = normalized.CommandAuthorized === true; return normalized; } //#endregion //#region src/link-understanding/format.ts function formatLinkUnderstandingBody(params) { const outputs = params.outputs.map((output) => output.trim()).filter(Boolean); if (outputs.length === 0) return params.body ?? ""; const base = (params.body ?? "").trim(); if (!base) return outputs.join("\n"); return `${base}\n\n${outputs.join("\n")}`; } //#endregion //#region src/auto-reply/templating.ts function formatTemplateValue(value) { if (value == null) return ""; if (typeof value === "string") return value; if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value); if (typeof value === "symbol" || typeof value === "function") return value.toString(); if (Array.isArray(value)) return value.flatMap((entry) => { if (entry == null) return []; if (typeof entry === "string") return [entry]; if (typeof entry === "number" || typeof entry === "boolean" || typeof entry === "bigint") return [String(entry)]; return []; }).join(","); if (typeof value === "object") return ""; return ""; } function applyTemplate(str, ctx) { if (!str) return ""; return str.replace(/{{\s*(\w+)\s*}}/g, (_, key) => { const value = ctx[key]; return formatTemplateValue(value); }); } //#endregion //#region src/media-understanding/defaults.ts const MB = 1024 * 1024; const DEFAULT_MAX_CHARS$2 = 500; const DEFAULT_MAX_CHARS_BY_CAPABILITY = { image: DEFAULT_MAX_CHARS$2, audio: void 0, video: DEFAULT_MAX_CHARS$2 }; const DEFAULT_MAX_BYTES = { image: 10 * MB, audio: 20 * MB, video: 50 * MB }; const DEFAULT_TIMEOUT_SECONDS$1 = { image: 60, audio: 60, video: 120 }; const DEFAULT_PROMPT$1 = { image: "Describe the image.", audio: "Transcribe the audio.", video: "Describe the video." }; const DEFAULT_VIDEO_MAX_BASE64_BYTES = 70 * MB; const DEFAULT_AUDIO_MODELS = { groq: "whisper-large-v3-turbo", openai: "gpt-4o-mini-transcribe", deepgram: "nova-3" }; const CLI_OUTPUT_MAX_BUFFER = 5 * MB; const DEFAULT_MEDIA_CONCURRENCY = 2; //#endregion //#region src/channels/targets.ts function normalizeTargetId(kind, id) { return `${kind}:${id}`.toLowerCase(); } function buildMessagingTarget(kind, id, raw) { return { kind, id, raw, normalized: normalizeTargetId(kind, id) }; } function ensureTargetId(params) { if (!params.pattern.test(params.candidate)) throw new Error(params.errorMessage); return params.candidate; } function requireTargetKind(params) { const kindLabel = params.kind; if (!params.target) throw new Error(`${params.platform} ${kindLabel} id is required.`); if (params.target.kind !== params.kind) throw new Error(`${params.platform} ${kindLabel} id is required (use ${kindLabel}:<id>).`); return params.target.id; } //#endregion //#region src/slack/targets.ts function parseSlackTarget(raw, options = {}) { const trimmed = raw.trim(); if (!trimmed) return; const mentionMatch = trimmed.match(/^<@([A-Z0-9]+)>$/i); if (mentionMatch) return buildMessagingTarget("user", mentionMatch[1], trimmed); if (trimmed.startsWith("user:")) { const id = trimmed.slice(5).trim(); return id ? buildMessagingTarget("user", id, trimmed) : void 0; } if (trimmed.startsWith("channel:")) { const id = trimmed.slice(8).trim(); return id ? buildMessagingTarget("channel", id, trimmed) : void 0; } if (trimmed.startsWith("slack:")) { const id = trimmed.slice(6).trim(); return id ? buildMessagingTarget("user", id, trimmed) : void 0; } if (trimmed.startsWith("@")) return buildMessagingTarget("user", ensureTargetId({ candidate: trimmed.slice(1).trim(), pattern: /^[A-Z0-9]+$/i, errorMessage: "Slack DMs require a user id (use user:<id> or <@id>)" }), trimmed); if (trimmed.startsWith("#")) return buildMessagingTarget("channel", ensureTargetId({ candidate: trimmed.slice(1).trim(), pattern: /^[A-Z0-9]+$/i, errorMessage: "Slack channels require a channel id (use channel:<id>)" }), trimmed); if (options.defaultKind) return buildMessagingTarget(options.defaultKind, trimmed, trimmed); return buildMessagingTarget("channel", trimmed, trimmed); } function resolveSlackChannelId(raw) { return requireTargetKind({ platform: "Slack", target: parseSlackTarget(raw, { defaultKind: "channel" }), kind: "channel" }); } //#endregion //#region src/channels/channel-config.ts function applyChannelMatchMeta(result, match) { if (match.matchKey && match.matchSource) { result.matchKey = match.matchKey; result.matchSource = match.matchSource; } return result; } function resolveChannelMatchConfig(match, resolveEntry) { if (!match.entry) return null; return applyChannelMatchMeta(resolveEntry(match.entry), match); } function buildChannelKeyCandidates(...keys) { const seen = /* @__PURE__ */ new Set(); const candidates = []; for (const key of keys) { if (typeof key !== "string") continue; const trimmed = key.trim(); if (!trimmed || seen.has(trimmed)) continue; seen.add(trimmed); candidates.push(trimmed); } return candidates; } function resolveChannelEntryMatch(params) { const entries = params.entries ?? {}; const match = {}; for (const key of params.keys) { if (!Object.prototype.hasOwnProperty.call(entries, key)) continue; match.entry = entries[key]; match.key = key; break; } if (params.wildcardKey && Object.prototype.hasOwnProperty.call(entries, params.wildcardKey)) { match.wildcardEntry = entries[params.wildcardKey]; match.wildcardKey = params.wildcardKey; } return match; } function resolveChannelEntryMatchWithFallback(params) { const direct = resolveChannelEntryMatch({ entries: params.entries, keys: params.keys, wildcardKey: params.wildcardKey }); if (direct.entry && direct.key) return { ...direct, matchKey: direct.key, matchSource: "direct" }; const normalizeKey = params.normalizeKey; if (normalizeKey) { const normalizedKeys = params.keys.map((key) => normalizeKey(key)).filter(Boolean); if (normalizedKeys.length > 0) for (const [entryKey, entry] of Object.entries(params.entries ?? {})) { const normalizedEntry = normalizeKey(entryKey); if (normalizedEntry && normalizedKeys.includes(normalizedEntry)) return { ...direct, entry, key: entryKey, matchKey: entryKey, matchSource: "direct" }; } } const parentKeys = params.parentKeys ?? []; if (parentKeys.length > 0) { const parent = resolveChannelEntryMatch({ entries: params.entries, keys: parentKeys }); if (parent.entry && parent.key) return { ...direct, entry: parent.entry, key: parent.key, parentEntry: parent.entry, parentKey: parent.key, matchKey: parent.key, matchSource: "parent" }; if (normalizeKey) { const normalizedParentKeys = parentKeys.map((key) => normalizeKey(key)).filter(Boolean); if (normalizedParentKeys.length > 0) for (const [entryKey, entry] of Object.entries(params.entries ?? {})) { const normalizedEntry = normalizeKey(entryKey); if (normalizedEntry && normalizedParentKeys.includes(normalizedEntry)) return { ...direct, entry, key: entryKey, parentEntry: entry, parentKey: entryKey, matchKey: entryKey, matchSource: "parent" }; } } } if (direct.wildcardEntry && direct.wildcardKey) return { ...direct, entry: direct.wildcardEntry, key: direct.wildcardKey, matchKey: direct.wildcardKey, matchSource: "wildcard" }; return direct; } //#endregion //#region src/channels/allowlist-match.ts function formatAllowlistMatchMeta(match) { return `matchKey=${match?.matchKey ?? "none"} matchSource=${match?.matchSource ?? "none"}`; } //#endregion //#region src/media-understanding/providers/anthropic/index.ts const anthropicProvider = { id: "anthropic", capabilities: ["image"], describeImage: describeImageWithModel }; //#endregion //#region src/media-understanding/providers/shared.ts const MAX_ERROR_CHARS = 300; function normalizeBaseUrl(baseUrl, fallback) { return (baseUrl?.trim() || fallback).replace(/\/+$/, ""); } async function fetchWithTimeout$3(url, init, timeoutMs, fetchFn) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), Math.max(1, timeoutMs)); try { return await fetchFn(url, { ...init, signal: controller.signal }); } finally { clearTimeout(timer); } } async function fetchWithTimeoutGuarded(url, init, timeoutMs, fetchFn, options) { return await fetchWithSsrFGuard({ url, fetchImpl: fetchFn, init, timeoutMs, policy: options?.ssrfPolicy, lookupFn: options?.lookupFn, pinDns: options?.pinDns }); } async function readErrorResponse(res) { try { const collapsed = (await res.text()).replace(/\s+/g, " ").trim(); if (!collapsed) return; if (collapsed.length <= MAX_ERROR_CHARS) return collapsed; return `${collapsed.slice(0, MAX_ERROR_CHARS)}…`; } catch { return; } } //#endregion //#region src/media-understanding/providers/deepgram/audio.ts const DEFAULT_DEEPGRAM_AUDIO_BASE_URL = "https://api.deepgram.com/v1"; const DEFAULT_DEEPGRAM_AUDIO_MODEL = "nova-3"; function resolveModel$4(model) { return model?.trim() || DEFAULT_DEEPGRAM_AUDIO_MODEL; } async function transcribeDeepgramAudio(params) { const fetchFn = params.fetchFn ?? fetch; const baseUrl = normalizeBaseUrl(params.baseUrl, DEFAULT_DEEPGRAM_AUDIO_BASE_URL); const allowPrivate = Boolean(params.baseUrl?.trim()); const model = resolveModel$4(params.model); const url = new URL(`${baseUrl}/listen`); url.searchParams.set("model", model); if (params.language?.trim()) url.searchParams.set("language", params.language.trim()); if (params.query) for (const [key, value] of Object.entries(params.query)) { if (value === void 0) continue; url.searchParams.set(key, String(value)); } const headers = new Headers(params.headers); if (!headers.has("authorization")) headers.set("authorization", `Token ${params.apiKey}`); if (!headers.has("content-type")) headers.set("content-type", params.mime ?? "application/octet-stream"); const body = new Uint8Array(params.buffer); const { response: res, release } = await fetchWithTimeoutGuarded(url.toString(), { method: "POST", headers, body }, params.timeoutMs, fetchFn, allowPrivate ? { ssrfPolicy: { allowPrivateNetwork: true } } : void 0); try { if (!res.ok) { const detail = await readErrorResponse(res); const suffix = detail ? `: ${detail}` : ""; throw new Error(`Audio transcription failed (HTTP ${res.status})${suffix}`); } const transcript = (await res.json()).results?.channels?.[0]?.alternatives?.[0]?.transcript?.trim(); if (!transcript) throw new Error("Audio transcription response missing transcript"); return { text: transcript, model }; } finally { await release(); } } //#endregion //#region src/media-understanding/providers/deepgram/index.ts const deepgramProvider = { id: "deepgram", capabilities: ["audio"], transcribeAudio: transcribeDeepgramAudio }; //#endregion //#region src/media-understanding/providers/google/audio.ts const DEFAULT_GOOGLE_AUDIO_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; const DEFAULT_GOOGLE_AUDIO_MODEL = "gemini-3-flash-preview"; const DEFAULT_GOOGLE_AUDIO_PROMPT = "Transcribe the audio."; function resolveModel$3(model) { const trimmed = model?.trim(); if (!trimmed) return DEFAULT_GOOGLE_AUDIO_MODEL; return normalizeGoogleModelId(trimmed); } function resolvePrompt$2(prompt) { return prompt?.trim() || DEFAULT_GOOGLE_AUDIO_PROMPT; } async function transcribeGeminiAudio(params) { const fetchFn = params.fetchFn ?? fetch; const baseUrl = normalizeBaseUrl(params.baseUrl, DEFAULT_GOOGLE_AUDIO_BASE_URL); const allowPrivate = Boolean(params.baseUrl?.trim()); const model = resolveModel$3(params.model); const url = `${baseUrl}/models/${model}:generateContent`; const headers = new Headers(params.headers); if (!headers.has("content-type")) headers.set("content-type", "application/json"); if (!headers.has("x-goog-api-key")) headers.set("x-goog-api-key", params.apiKey); const body = { contents: [{ role: "user", parts: [{ text: resolvePrompt$2(params.prompt) }, { inline_data: { mime_type: params.mime ?? "audio/wav", data: params.buffer.toString("base64") } }] }] }; const { response: res, release } = await fetchWithTimeoutGuarded(url, { method: "POST", headers, body: JSON.stringify(body) }, params.timeoutMs, fetchFn, allowPrivate ? { ssrfPolicy: { allowPrivateNetwork: true } } : void 0); try { if (!res.ok) { const detail = await readErrorResponse(res); const suffix = detail ? `: ${detail}` : ""; throw new Error(`Audio transcription failed (HTTP ${res.status})${suffix}`); } const text = ((await res.json()).candidates?.[0]?.content?.parts ?? []).map((part) => part?.text?.trim()).filter(Boolean).join("\n"); if (!text) throw new Error("Audio transcription response missing text"); return { text, model }; } finally { await release(); } } //#endregion //#region src/media-understanding/providers/google/video.ts const DEFAULT_GOOGLE_VIDEO_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"; const DEFAULT_GOOGLE_VIDEO_MODEL = "gemini-3-flash-preview"; const DEFAULT_GOOGLE_VIDEO_PROMPT = "Describe the video."; function resolveModel$2(model) { const trimmed = model?.trim(); if (!trimmed) return DEFAULT_GOOGLE_VIDEO_MODEL; return normalizeGoogleModelId(trimmed); } function resolvePrompt$1(prompt) { return prompt?.trim() || DEFAULT_GOOGLE_VIDEO_PROMPT; } async function describeGeminiVideo(params) { const fetchFn = params.fetchFn ?? fetch; const baseUrl = normalizeBaseUrl(params.baseUrl, DEFAULT_GOOGLE_VIDEO_BASE_URL); const allowPrivate = Boolean(params.baseUrl?.trim()); const model = resolveModel$2(params.model); const url = `${baseUrl}/models/${model}:generateContent`; const headers = new Headers(params.headers); if (!headers.has("content-type")) headers.set("content-type", "application/json"); if (!headers.has("x-goog-api-key")) headers.set("x-goog-api-key", params.apiKey); const body = { contents: [{ role: "user", parts: [{ text: resolvePrompt$1(params.prompt) }, { inline_data: { mime_type: params.mime ?? "video/mp4", data: params.buffer.toString("base64") } }] }] }; const { response: res, release } = await fetchWithTimeoutGuarded(url, { method: "POST", headers, body: JSON.stringify(body) }, params.timeoutMs, fetchFn, allowPrivate ? { ssrfPolicy: { allowPrivateNetwork: true } } : void 0); try { if (!res.ok) { const detail = await readErrorResponse(res); const suffix = detail ? `: ${detail}` : ""; throw new Error(`Video description failed (HTTP ${res.status})${suffix}`); } const text = ((await res.json()).candidates?.[0]?.content?.parts ?? []).map((part) => part?.text?.trim()).filter(Boolean).join("\n"); if (!text) throw new Error("Video description response missing text"); return { text, model }; } finally { await release(); } } //#endregion //#region src/media-understanding/providers/google/index.ts const googleProvider = { id: "google", capabilities: [ "image", "audio", "video" ], describeImage: describeImageWithModel, transcribeAudio: transcribeGeminiAudio, describeVideo: describeGeminiVideo }; //#endregion //#region src/media-understanding/providers/openai/audio.ts const DEFAULT_OPENAI_AUDIO_BASE_URL = "https://api.openai.com/v1"; const DEFAULT_OPENAI_AUDIO_MODEL = "gpt-4o-mini-transcribe"; function resolveModel$1(model) { return model?.trim() || DEFAULT_OPENAI_AUDIO_MODEL; } async function transcribeOpenAiCompatibleAudio(params) { const fetchFn = params.fetchFn ?? fetch; const baseUrl = normalizeBaseUrl(params.baseUrl, DEFAULT_OPENAI_AUDIO_BASE_URL); const allowPrivate = Boolean(params.baseUrl?.trim()); const url = `${baseUrl}/audio/transcriptions`; const model = resolveModel$1(params.model); const form = new FormData(); const fileName = params.fileName?.trim() || path.basename(params.fileName) || "audio"; const bytes = new Uint8Array(params.buffer); const blob = new Blob([bytes], { type: params.mime ?? "application/octet-stream" }); form.append("file", blob, fileName); form.append("model", model); if (params.language?.trim()) form.append("language", params.language.trim()); if (params.prompt?.trim()) form.append("prompt", params.prompt.trim()); const headers = new Headers(params.headers); if (!headers.has("authorization")) headers.set("authorization", `Bearer ${params.apiKey}`); const { response: res, release } = await fetchWithTimeoutGuarded(url, { method: "POST", headers, body: form }, params.timeoutMs, fetchFn, allowPrivate ? { ssrfPolicy: { allowPrivateNetwork: true } } : void 0); try { if (!res.ok) { const detail = await readErrorResponse(res); const suffix = detail ? `: ${detail}` : ""; throw new Error(`Audio transcription failed (HTTP ${res.status})${suffix}`); } const text = (await res.json()).text?.trim(); if (!text) throw new Error("Audio transcription response missing text"); return { text, model }; } finally { await release(); } } //#endregion //#region src/media-understanding/providers/groq/index.ts const DEFAULT_GROQ_AUDIO_BASE_URL = "https://api.groq.com/openai/v1"; const groqProvider = { id: "groq", capabilities: ["audio"], transcribeAudio: (req) => transcribeOpenAiCompatibleAudio({ ...req, baseUrl: req.baseUrl ?? DEFAULT_GROQ_AUDIO_BASE_URL }) }; //#endregion //#region src/media-understanding/providers/minimax/index.ts const minimaxProvider = { id: "minimax", capabilities: ["image"], describeImage: describeImageWithModel }; //#endregion //#region src/media-understanding/providers/openai/index.ts const openaiProvider = { id: "openai", capabilities: ["image"], describeImage: describeImageWithModel, transcribeAudio: transcribeOpenAiCompatibleAudio }; //#endregion //#region src/media-understanding/providers/index.ts const PROVIDERS = [ groqProvider, openaiProvider, googleProvider, anthropicProvider, minimaxProvider, deepgramProvider ]; function normalizeMediaProviderId(id) { const normalized = normalizeProviderId(id); if (normalized === "gemini") return "google"; return normalized; } function buildMediaUnderstandingRegistry(overrides) { const registry = /* @__PURE__ */ new Map(); for (const provider of PROVIDERS) registry.set(normalizeMediaProviderId(provider.id), provider); if (overrides) for (const [key, provider] of Object.entries(overrides)) { const normalizedKey = normalizeMediaProviderId(key); const existing = registry.get(normalizedKey); const merged = existing ? { ...existing, ...provider, capabilities: provider.capabilities ?? existing.capabilities } : provider; registry.set(normalizedKey, merged); } return registry; } function getMediaUnderstandingProvider(id, registry) { return registry.get(normalizeMediaProviderId(id)); } //#endregion //#region src/media-understanding/scope.ts function normalizeDecision(value) { const normalized = value?.trim().toLowerCase(); if (normalized === "allow") return "allow"; if (normalized === "deny") return "deny"; } function normalizeMatch(value) { return value?.trim().toLowerCase() || void 0; } function normalizeMediaUnderstandingChatType(raw) { return normalizeChatType(raw ?? void 0); } function resolveMediaUnderstandingScope(params) { const scope = params.scope; if (!scope) return "allow"; const channel = normalizeMatch(params.channel); const chatType = normalizeMediaUnderstandingChatType(params.chatType); const sessionKey = normalizeMatch(params.sessionKey) ?? ""; for (const rule of scope.rules ?? []) { if (!rule) continue; const action = normalizeDecision(rule.action) ?? "allow"; const match = rule.match ?? {}; const matchChannel = normalizeMatch(match.channel); const matchChatType = normalizeMediaUnderstandingChatType(match.chatType); const matchPrefix = normalizeMatch(match.keyPrefix); if (matchChannel && matchChannel !== channel) continue; if (matchChatType && matchChatType !== chatType) continue; if (matchPrefix && !sessionKey.startsWith(matchPrefix)) continue; return action; } return normalizeDecision(scope.default) ?? "allow"; } //#endregion //#region src/media-understanding/resolve.ts function resolveTimeoutMs(seconds, fallbackSeconds) { const value = typeof seconds === "number" && Number.isFinite(seconds) ? seconds : fallbackSeconds; return Math.max(1e3, Math.floor(value * 1e3)); } function re