UNPKG

@gguf/claw

Version:

WhatsApp gateway CLI (Baileys web) with Pi RPC agent

128 lines (117 loc) 4.25 kB
export type DmPolicy = "pairing" | "allowlist" | "open" | "disabled"; export type GroupPolicy = "open" | "disabled" | "allowlist"; export type BlueBubblesGroupConfig = { /** If true, only respond in this group when mentioned. */ requireMention?: boolean; /** Optional tool policy overrides for this group. */ tools?: { allow?: string[]; deny?: string[] }; }; export type BlueBubblesAccountConfig = { /** Optional display name for this account (used in CLI/UI lists). */ name?: string; /** Optional provider capability tags used for agent/runtime guidance. */ capabilities?: string[]; /** Allow channel-initiated config writes (default: true). */ configWrites?: boolean; /** If false, do not start this BlueBubbles account. Default: true. */ enabled?: boolean; /** Base URL for the BlueBubbles API. */ serverUrl?: string; /** Password for BlueBubbles API authentication. */ password?: string; /** Webhook path for the gateway HTTP server. */ webhookPath?: string; /** Direct message access policy (default: pairing). */ dmPolicy?: DmPolicy; allowFrom?: Array<string | number>; /** Optional allowlist for group senders. */ groupAllowFrom?: Array<string | number>; /** Group message handling policy. */ groupPolicy?: GroupPolicy; /** Max group messages to keep as history context (0 disables). */ historyLimit?: number; /** Max DM turns to keep as history context. */ dmHistoryLimit?: number; /** Per-DM config overrides keyed by user ID. */ dms?: Record<string, unknown>; /** Outbound text chunk size (chars). Default: 4000. */ textChunkLimit?: number; /** Chunking mode: "newline" (default) splits on every newline; "length" splits by size. */ chunkMode?: "length" | "newline"; blockStreaming?: boolean; /** Merge streamed block replies before sending. */ blockStreamingCoalesce?: Record<string, unknown>; /** Max outbound media size in MB. */ mediaMaxMb?: number; /** Send read receipts for incoming messages (default: true). */ sendReadReceipts?: boolean; /** Per-group configuration keyed by chat GUID or identifier. */ groups?: Record<string, BlueBubblesGroupConfig>; }; export type BlueBubblesActionConfig = { reactions?: boolean; edit?: boolean; unsend?: boolean; reply?: boolean; sendWithEffect?: boolean; renameGroup?: boolean; addParticipant?: boolean; removeParticipant?: boolean; leaveGroup?: boolean; sendAttachment?: boolean; }; export type BlueBubblesConfig = { /** Optional per-account BlueBubbles configuration (multi-account). */ accounts?: Record<string, BlueBubblesAccountConfig>; /** Per-action tool gating (default: true for all). */ actions?: BlueBubblesActionConfig; } & BlueBubblesAccountConfig; export type BlueBubblesSendTarget = | { kind: "chat_id"; chatId: number } | { kind: "chat_guid"; chatGuid: string } | { kind: "chat_identifier"; chatIdentifier: string } | { kind: "handle"; address: string; service?: "imessage" | "sms" | "auto" }; export type BlueBubblesAttachment = { guid?: string; uti?: string; mimeType?: string; transferName?: string; totalBytes?: number; height?: number; width?: number; originalROWID?: number; }; const DEFAULT_TIMEOUT_MS = 10_000; export function normalizeBlueBubblesServerUrl(raw: string): string { const trimmed = raw.trim(); if (!trimmed) { throw new Error("BlueBubbles serverUrl is required"); } const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`; return withScheme.replace(/\/+$/, ""); } export function buildBlueBubblesApiUrl(params: { baseUrl: string; path: string; password?: string; }): string { const normalized = normalizeBlueBubblesServerUrl(params.baseUrl); const url = new URL(params.path, `${normalized}/`); if (params.password) { url.searchParams.set("password", params.password); } return url.toString(); } export async function blueBubblesFetchWithTimeout( url: string, init: RequestInit, timeoutMs = DEFAULT_TIMEOUT_MS, ) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); try { return await fetch(url, { ...init, signal: controller.signal }); } finally { clearTimeout(timer); } }