UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

1,098 lines (1,071 loc) 2.26 MB
import { A as parseImageSizeError, B as normalizeElevatedLevel, C as isFailoverAssistantError, D as isRawApiErrorPayload, E as isRateLimitAssistantError, F as sanitizeGoogleTurnOrdering, G as resolveResponseUsageMode, H as normalizeThinkLevel, I as formatThinkingLevels, K as supportsXHighThinking, L as formatXHighModelHint, M as buildBootstrapContextFiles, N as ensureSessionHeader, O as isTimeoutErrorMessage, P as resolveBootstrapMaxChars, S as isContextOverflowError, T as isLikelyContextOverflowError, U as normalizeUsageDisplay, V as normalizeReasoningLevel, W as normalizeVerboseLevel, _ as getApiErrorPayloadFingerprint, a as isMessagingToolDuplicateNormalized, b as isCloudCodeAssistFormatError, c as sanitizeImageBlocks, d as isAntigravityClaude, f as isGoogleModelApi, g as formatRawAssistantErrorForUi, h as formatAssistantErrorText, j as sanitizeUserFacingText, k as parseImageDimensionError, l as sanitizeToolResultImages, m as classifyFailoverReason, n as validateGeminiTurns, o as normalizeTextForComparison, p as BILLING_ERROR_USER_MESSAGE, r as pickFallbackThinkingLevel, s as sanitizeSessionMessagesImages, t as validateAnthropicTurns, u as downgradeOpenAIReasoningBlocks, v as isAuthAssistantError, w as isFailoverErrorMessage, x as isCompactionFailureError, y as isBillingAssistantError } from "./pi-embedded-helpers-BB4uACeq.js"; import { g as resolveStateDir, r as STATE_DIR, t as CONFIG_PATH } from "./paths-scjhy7N2.js"; import { _ as parseAgentSessionKey, a as buildAgentPeerSessionKey, c as normalizeAgentId, d as resolveThreadSessionKeys, f as sanitizeAgentId, g as isSubagentSessionKey, h as isAcpSessionKey, i as buildAgentMainSessionKey, l as normalizeMainKey, n as DEFAULT_AGENT_ID, o as buildGroupHistoryKey, r as DEFAULT_MAIN_KEY, s as normalizeAccountId$3, t as DEFAULT_ACCOUNT_ID$1, u as resolveAgentIdFromSessionKey, v as resolveThreadParentSessionKey } from "./session-key-Dm2EOhrH.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-CAq3uyo7.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-CKSrBNwq.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-HEWTMJ7j.js"; import { t as resolveOpenClawPackageRoot } from "./openclaw-root-Cvotktkd.js"; import { C as loadWorkspaceBootstrapFiles, S as filterBootstrapFilesForSession, c as resolveDefaultAgentId, f as DEFAULT_AGENT_WORKSPACE_DIR, i as resolveAgentModelFallbacksOverride, 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-CMs5Y7l-.js"; import { $ as resolveApiKeyForProfile, I as resolveEnvApiKey, J as resolveAuthProfileOrder, L as resolveModelAuthMode, M as getCustomProviderApiKey, N as requireApiKey, P as resolveApiKeyForProvider, V as resolveShellEnvFallbackTimeoutMs, X as markAuthProfileFailure, Y as isProfileInCooldown, Z as markAuthProfileUsed, a as isCliProvider, at as listProfilesForProvider, bt as DEFAULT_PROVIDER, d as resolveConfiguredModelRef, f as resolveDefaultModelForAgent, h as resolveThinkingDefault, ht as resolveAuthProfileDisplayLabel, j as getApiKeyForModel, lt as ensureAuthProfileStore, m as resolveModelRefFromString, mt as resolveOpenClawAgentDir, n as buildConfiguredAllowlistKeys, o as modelKey, ot as markAuthProfileGood, pt as resolveAuthStorePathForDisplay, r as buildModelAliasIndex, s as normalizeProviderId, t as buildAllowedModelSet, v as normalizeGoogleModelId, vt as DEFAULT_CONTEXT_TOKENS, yt as DEFAULT_MODEL, z as getShellPathFromLoginShell } from "./model-selection-DMUrNhQP.js"; import { a as saveJsonFile, i as loadJsonFile } from "./github-copilot-token-pGSmVaW-.js"; import { t as formatCliCommand } from "./command-format-ChfKqObn.js"; import { t as parseBooleanValue$1 } from "./boolean-BgXe2hyu.js"; import { t as isTruthyEnvValue } from "./env-0_mKbEWW.js"; import { C as setConfigValueAtPath, S as parseConfigPath, _ as getConfigOverrides, b as unsetConfigOverride, c as writeConfigFile, d as TELEGRAM_COMMAND_NAME_PATTERN, f as normalizeTelegramCommandName, g as validateJsonSchemaValue, h as parseDurationMs, i as loadConfig, j as VERSION, k as resolveAgentMaxConcurrent, l as validateConfigObjectWithPlugins, m as isSafeExecutableValue, o as readConfigFileSnapshot, p as resolveTelegramCustomCommands, s as resolveConfigSnapshotHash, v as resetConfigOverrides, w as unsetConfigValueAtPath, x as getConfigValueAtPath, y as setConfigOverride } from "./config-CAuZ-EkU.js"; import { c as resolveEnableState, l as resolveMemorySlotDecision, n as discoverOpenClawPlugins, s as normalizePluginsConfig, t as loadPluginManifestRegistry } from "./manifest-registry-DHaa1SJb.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-BYIWo0Cp.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 normalizeToolName, b as deliveryContextFromSession, c as resolveSandboxRuntimeStatus, d as loadSessionStore, dt as resolveConversationLabel, et as applyOwnerOnlyToolPolicy, f as readSessionUpdatedAt, g as updateSessionStore, h as updateLastRoute, j as resolveSessionResetType, k as resolveChannelResetConfig, l as appendAssistantMessageToSessionTranscript, nt as collectExplicitAllowlist, o as resolveSandboxContext, ot as resolveToolProfilePolicy, p as recordSessionMetaFromInbound, q as resolveSignalAccount, rt as expandPolicyWithPluginGroups, st as stripPluginOnlyAllowlist, tt as buildPluginToolGroups, v as isCacheEnabled, w as normalizeSessionDeliveryFields, x as deliveryContextKey, y as resolveCacheTtlMs$1, z as deriveSessionMetaPatch } from "./sandbox-CV8VwPij.js"; import { _ as ensureOpenClawModelsJson, a as decodeDataUrl, c as extractAssistantThinking, d as formatReasoningMessage, f as inferToolMetaFromArgs, g as stripThinkingTagsFromText, h as stripMinimaxToolCallXml, i as coerceImageModelConfig, l as extractThinkingFromTaggedStream, m as stripDowngradedToolCallText, o as resolveProviderVisionModelFromConfig, p as promoteThinkingTagsToBlocks, r as coerceImageAssistantText, s as extractAssistantText$1, t as describeImageWithModel, u as extractThinkingFromTaggedText, v as minimaxUnderstandImage } from "./image-Ca_PtqY7.js"; import { n as discoverModels, t as discoverAuthStorage } from "./pi-model-discovery-CV2V1HHz.js"; import { E as formatUncaughtError, T as formatErrorMessage, k as DEFAULT_AI_SNAPSHOT_MAX_CHARS, w as extractErrorCode } from "./chrome-BNSd7Bie.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-D5JDj3TR.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-DchZU3EK.js"; import { i as resolveBrowserConfig } from "./server-context-vChIAqjH.js"; import { a as isInternalMessageChannel, c as listDeliverableMessageChannels, d as resolveMessageChannel, h as GATEWAY_CLIENT_NAMES, l as normalizeMessageChannel, m as GATEWAY_CLIENT_MODES, n as isDeliverableMessageChannel, o as isMarkdownCapableMessageChannel, p as GATEWAY_CLIENT_IDS, t as INTERNAL_MESSAGE_CHANNEL, u as resolveGatewayMessageChannel } from "./message-channel-Bpfe5l5f.js"; import { a as logoutWeb, d as webAuthExists, i as logWebSelfId, n as resolveWhatsAppAccount, r as getWebAuthAgeMs, s as readWebSelfId } from "./accounts-BgZmhIm6.js"; import { a as resolveSessionTranscriptsDirForAgent, n as resolveSessionFilePath, o as resolveStorePath, r as resolveSessionTranscriptPath } from "./paths-Bb0nwPeu.js"; import { t as emitSessionTranscriptUpdate } from "./transcript-events-ChU6IQwp.js"; import { n as redactSensitiveText } from "./redact-DJCFY628.js"; import { n as resolveToolDisplay } from "./tool-display-BxZG0o1b.js"; import { A as markdownToIRWithMeta, B as resolveTextChunkLimit, C as signalCheck, D as wrapFetchWithAbortSignal, E as resolveFetch, F as chunkMarkdownText, G as SILENT_REPLY_TOKEN, H as isSafeFenceBreak, I as chunkMarkdownTextWithMode, J as fetchRemoteMedia, K as isSilentReplyText, L as chunkText, M as loadWebMediaRaw, N as resolveMarkdownTableMode, O as chunkMarkdownIR, P as chunkByNewline, R as chunkTextWithMode, S as sendTypingSignal, T as streamSignalEvents, U as parseFenceSpans, V as findFenceSpanAt, W as HEARTBEAT_TOKEN, Y as fetchWithSsrFGuard, _ as parseReplyDirectives, b as sendMessageSignal, c as applyReplyThreading, d as shouldSuppressMessagingToolReplies, f as createReplyToModeFilterForChannel, g as normalizeTargetForProvider, h as normalizeChannelTargetInput, j as loadWebMedia, k as markdownToIR, l as filterMessagingToolDuplicates, m as buildTargetResolverSignature, o as normalizeReplyPayloadsForDelivery, p as resolveReplyToMode, q as MediaFetchError, s as applyReplyTagsToPayload, t as deliverOutboundPayloads, u as isRenderablePayload, v as splitMediaFromOutput, w as signalRpcRequest, x as sendReadReceiptSignal, y as parseInlineDirectives$1, z as resolveChunkMode } from "./deliver-C3bnXkg5.js"; import { i as getMachineDisplayName, n as isWSL, t as createBrowserRouteDispatcher } from "./dispatcher-6oI-H42S.js"; import { i as resolveMemorySearchConfig, n as resolveRetryConfig, r as retryAsync } from "./manager-LpytrxUw.js"; import { c as listMemoryFiles, l as normalizeExtraMemoryPaths } from "./sqlite-BKl1HJFe.js"; import { C as shouldHandleTextCommands, S as serializeCommandArgs, _ as listNativeCommandSpecsForConfig, b as resolveCommandArgChoices, f as buildCommandTextFromArgs, g as listNativeCommandSpecs, h as listChatCommandsForConfig, m as listChatCommands, o as extractTextFromMessage, p as findCommandByNativeName, t as buildChannelSummary, v as normalizeCommandBody, x as resolveCommandArgMenu, y as parseCommandArgs } from "./channel-summary-DUiKDBLv.js"; import { Et as SESSION_LABEL_MAX_LENGTH, t as GatewayClient } from "./client-BYVbRnuQ.js"; import { t as pickPrimaryTailnetIPv4 } from "./tailnet-DLDGNuH2.js"; import { i as randomIdempotencyKey, n as callGateway } from "./call-BTbA5OB4.js"; import { a as formatError$1, i as createWaSocket, n as startWebLoginWithQr, o as getStatusCode$1, r as waitForWebLogin, s as waitForWaConnection } from "./login-qr-BIlr0vwe.js"; import { a as removeChannelAllowFromStoreEntry, c as listPairingChannels, i as readChannelAllowFromStore, o as upsertChannelPairingRequest, t as addChannelAllowFromStoreEntry } from "./pairing-store-DFq7WtOv.js"; import { t as formatDocsLink } from "./links-B5pRdmo1.js"; import { i as withManager, t as formatErrorMessage$1 } from "./cli-utils-BkRQdAoC.js"; import { n as withProgress, r as withProgressTotals } from "./progress-xpLtQsNY.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-BQ8N5y8a.js"; import { r as stylePromptTitle } from "./prompt-style-vzh0MGHs.js"; import { t as resolvePairingIdLabel } from "./pairing-labels-CtqLxbG6.js"; import { c as derivePromptTokens, l as hasNonzeroUsage, n as loadCostUsageSummary, o as extractToolCallNames, r as loadSessionCostSummary, s as hasToolCall, u as normalizeUsage } from "./session-cost-usage-CBP4Hv9D.js"; import { i as resolveModelCostConfig, n as formatTokenCount$2, r as formatUsd$1, t as estimateUsageCost } from "./usage-format-DvowRSs-.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-DZixgolZ.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-DT5HvhJV.js"; import { n as createBrowserControlContext, r as startBrowserControlServiceFromConfig } from "./control-service-CS61Road.js"; import { t as parseAbsoluteTimeMs } from "./parse-BZz5lHzQ.js"; import { d as resolveGatewaySystemdServiceName, l as resolveGatewayLaunchAgentLabel } from "./constants-HPrOsATF.js"; import { n as resolveMessageChannelSelection, t as listConfiguredMessageChannels } from "./channel-selection-CJWYmCLf.js"; import { t as parseTimeoutMs } from "./parse-timeout-Du-wHHNi.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 { 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.d