interface RequestOptions { method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; body?: Record | FormData; query?: Record; headers?: Record; rawResponse?: boolean; /** Abort the underlying fetch (e.g. to bound a poll by a caller's deadline). */ signal?: AbortSignal; } export declare function request(path: string, options?: RequestOptions): Promise; /** * Fetch an endpoint that returns binary data (e.g. /v1/speak returns audio/x-wav * bytes directly, NOT a JSON URL). Returns the raw bytes + content type. * Throws BlandError/AuthError on non-2xx (reads the error body as text). */ export declare function requestBinary(path: string, options?: { method?: "GET" | "POST"; body?: Record; query?: Record; }): Promise<{ buffer: Buffer; contentType: string; }>; /** Audio container formats we can positively identify by magic bytes. */ export type AudioFormat = "wav" | "mp3" | "ogg" | "webm" | "flac" | "aiff" | "unknown"; /** Map an audio content-type to a file extension (fallback when magic bytes are unrecognized). */ export declare function extForContentType(ct: string): string; /** * Make an untrusted upstream body safe to embed in an error message that may be * shown to a user or an MCP client/model: decode as UTF-8, drop CSI escape * sequences, then strip every C0/C1 control and DEL byte. Stripping the control * bytes removes the ESC/BEL introducers, so no terminal escape (ANSI, OSC, or * DCS) can execute even if inert text remains; whitespace is collapsed and the * length capped. Without this, a raw error body could inject terminal escapes or * dump binary garbage into the user's terminal or the model's context. */ export declare function safeSnippet(input: Buffer | string, max?: number): string; /** * Validate that a fetched body is plausibly audio before it is written to disk. * Layered by how much we can trust the response: * 1. Audio positively identified by magic bytes is always accepted; the * detected format drives the extension (so we never write MP3 bytes as .wav). * 2. An `audio/*` content-type with unrecognized-but-binary bytes is accepted * (a future codec we don't sniff), but a plainly-text body under audio/* is * a mislabeled error and is rejected. * 3. A neutral (empty / octet-stream) or non-audio content-type with NO audio * magic cannot be proven to be audio, so it is rejected — this is what stops * an untyped PNG/HTML/JSON/error body from being saved as speech.wav. * Throws BlandError on rejection. Internal to requestAudio — call that, not this. */ export declare function validateAudio(buffer: Buffer, contentType: string, max?: number): { format: AudioFormat; ext: string; }; /** * Fetch a Bland audio endpoint and return validated bytes plus the detected * format/extension. Unlike requestBinary this never returns unvalidated audio: * it rejects empty and non-audio (error-page) responses and bounds the size via * a Content-Length pre-check plus a post-read length check. Note the body is * buffered before the post-read check runs, so the cap bounds what reaches disk, * not peak memory; a true streamed abort is a follow-up. Throws BlandError/AuthError. */ export declare function requestAudio(path: string, options?: { method?: "GET" | "POST"; body?: Record; query?: Record; maxBytes?: number; }): Promise<{ buffer: Buffer; contentType: string; format: AudioFormat; ext: string; }>; /** * Extract an array from an API response that may be wrapped in a named key. * Bland API inconsistently returns either `[...]` or `{ key: [...] }`. * This tries the raw value first, then looks for the first array-valued key. */ export declare function extractArray(data: unknown): T[]; export declare const api: { get: (path: string, query?: Record, options?: { signal?: AbortSignal; }) => Promise; post: (path: string, body?: Record) => Promise; put: (path: string, body?: Record) => Promise; patch: (path: string, body?: Record) => Promise; delete: (path: string) => Promise; }; export {}; //# sourceMappingURL=api.d.ts.map