export declare class VeniceRequestError extends Error { readonly status: number; readonly body: unknown; constructor(message: string, status: number, body: unknown); } /** * Pull the human-readable reason out of a Venice error body. * * The API uses three shapes depending on where the request failed, and reading * only `error.message` -- as this client used to -- threw away the two most * useful ones: * * {"error": {"message": "..."}} upstream provider error * {"error": "Specified model not found: x. Did routing error, including * you mean: a, b, c?"} the suggestion list * {"issues": [{"message": "Image content is not request validation * supported by this model..."}]} * * Losing those turned "this model cannot see images" into a bare HTTP 400. */ export declare function describeApiError(errorBody: unknown, status: number): string; /** * Pull the JSON document out of a chat reply. * * Models fence JSON in ```json blocks inconsistently, and some prepend a line * of narration despite being told not to. Stripping fences handles the common * case; falling back to the outermost brace pair handles the rest. */ export declare function extractJsonBlock(raw: string): string; export interface VeniceDeprecationNotice { modelId: string | null; modelName: string | null; warning: string; date: string | null; } /** * Inspect a Response's headers for Venice deprecation notices and emit * a structured stderr warning the first time each unique notice is seen * in this process. Returns the parsed notice when present (mostly for * testing), otherwise null. * * Exported for tests; callers in this file invoke it from each request * path so every response shape (json, binary, json-or-binary) is covered. */ export declare function reportVeniceDeprecation(headers: Headers, requestPath: string): VeniceDeprecationNotice | null; /** * Test-only: reset the per-process deduplication state so unit tests can * exercise the warn-once behavior across multiple invocations. */ export declare function _resetDeprecationDedupeForTests(): void; export declare class VeniceClient { private readonly apiKey; private readonly baseUrl; /** * Timestamp (epoch ms) of the last request that completed. Used by the * simple rate-limiter to ensure a minimum gap between consecutive calls. */ private lastRequestAt; /** * @param apiKey Bearer token for the Venice API. Falls back to the * `VENICE_API_KEY` environment variable when omitted. * @param baseUrl Root URL for the API (no trailing slash). */ constructor(apiKey?: string, baseUrl?: string); /** Send a GET request and return parsed JSON. Used by setup/doctor checks. */ get(path: string): Promise; /** * Send a POST request to `path` with a JSON body and return the parsed * response. * * Automatically retries on transient failures (HTTP 429 / 5xx) up to * {@link MAX_RETRIES} times using exponential back-off. A small delay is * inserted between consecutive requests to stay within rate limits. * * @typeParam T Expected shape of the parsed JSON response. * @param path API path **including** the leading slash (e.g. `/api/v1/image/generate`). * @param body Request payload -- will be JSON-stringified. * @returns Parsed JSON response body. * @throws {VeniceRequestError} On non-retryable HTTP errors (4xx other than 429). * @throws {Error} When all retry attempts are exhausted. */ post(path: string, body: Record): Promise; /** * POST with JSON body, receive raw binary (e.g. image/png from multi-edit). * Same retry/rate-limit logic as {@link post}. */ postBinary(path: string, body: Record): Promise; /** * POST with JSON body, receive either JSON status data or raw binary media. * Useful for async retrieval endpoints that return JSON while processing and * switch to binary once the asset is ready for download. */ postBinaryOrJson(path: string, body: Record): Promise<{ contentType: string; value: T | Buffer; }>; /** * Send a chat completion request with multimodal content (text + images). * Uses the OpenAI-compatible chat completions endpoint. */ chatWithVision(model: string, systemPrompt: string, imageDataUris: string[], userPrompt: string, maxTokens?: number): Promise; /** * Chat completion that must come back as JSON, with one corrective retry. * * Every reasoning step in the harness -- workshop, script, storyboard QA -- * asks for JSON and parses the reply. Three things make that fragile, and * this handles all of them in one place: * * - Models fence their JSON in ```json blocks inconsistently. * - A model can emit *almost* valid JSON. GLM 5.2 drops a closing brace * roughly one attempt in three, which used to fail the whole command. * A single retry quoting the parse error fixes it. * - A model with no real vision returns EMPTY content rather than an error * when handed an image, which reads as an unhelpful parse failure. That * case is named explicitly so the operator can change models. * - A model WITH vision can still return empty content intermittently * (kimi-k3 did this on 4 of 12 storyboard-QA panels, 2026-08-10, while * reading the other 8 fine). Empty content therefore consumes a retry * attempt instead of failing immediately; only a repeat emptiness throws. * * Reasoning text arrives in a separate `reasoning_content` field on every * model checked, so it never pollutes what gets parsed. */ chatJson(options: { model: string; systemPrompt: string; userPrompt: string; /** Data URIs. Supplying any makes this a vision request. */ images?: string[]; maxTokens?: number; temperature?: number; /** What is being generated, for error messages, e.g. 'workshop'. */ label?: string; /** * Ask the model to answer directly, with no chain of thought * (`venice_parameters.disable_thinking`). For short, latency-bound * generations (the stream writer) this is the difference between ~4s and * ~35s on the same model. Thinking-only models (GLM 5.3) reject the flag * with a 400; callers that pass it should pick a model that honors it. */ disableThinking?: boolean; }): Promise; /** * Ensure at least {@link RATE_LIMIT_DELAY_MS} ms have elapsed since the * previous request completed. */ private applyRateLimit; } //# sourceMappingURL=client.d.ts.map