@visgate_ai/client 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Visgate AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # @visgate_ai/client
2
+
3
+ JavaScript/TypeScript SDK for the [Visgate API](https://visgateai.com) — one client for image and video generation across Fal, Replicate, and Runway.
4
+
5
+ Works in Node.js (18+), browsers, and with React, Vite, Next.js, and vanilla JS.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @visgate_ai/client
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```javascript
16
+ import { Client } from "@visgate_ai/client";
17
+
18
+ const client = new Client(); // reads VISGATE_API_KEY from env (Node)
19
+
20
+ const result = await client.generate("a sunset over Istanbul");
21
+ console.log(result.imageUrl, result.cost, result.provider);
22
+
23
+ client.close();
24
+ ```
25
+
26
+ With explicit API key:
27
+
28
+ ```javascript
29
+ const client = new Client({ apiKey: "vg-..." });
30
+ const result = await client.generate("a sunset", { model: "fal-ai/flux/schnell" });
31
+ console.log(result.imageUrl);
32
+ ```
33
+
34
+ ## Features
35
+
36
+ - **One client, three providers.** Fal, Replicate, and Runway behind a single API.
37
+ - **Managed and BYOK modes.** Use Visgate-managed keys or bring your own.
38
+ - **Promise-based API.** All methods return Promises; use `async/await` or `.then()`.
39
+ - **Automatic retries.** Transient errors (429, 5xx) are retried with exponential backoff.
40
+ - **Typed exceptions.** Catch `AuthenticationError`, `RateLimitError`, `ProviderError`, etc.
41
+ - **TypeScript.** Full type definitions included.
42
+ - **Framework-agnostic.** Use in vanilla JS, React, Vite, Next.js.
43
+ - **Async generation.** Video/image async mode with `client.requests.get()` for status polling; usage and billing resources.
44
+
45
+ ## Authentication
46
+
47
+ **Node.js:** Set `VISGATE_API_KEY` in the environment or pass `apiKey` in options.
48
+
49
+ ```bash
50
+ export VISGATE_API_KEY="vg-..."
51
+ ```
52
+
53
+ **Browser / Vite:** Pass `apiKey` in options (or use `import.meta.env.VITE_VISGATE_API_KEY` in Vite and pass it to the client).
54
+
55
+ ```javascript
56
+ const client = new Client({ apiKey: "vg-..." });
57
+ ```
58
+
59
+ ### Production / proxy (recommended for browser apps)
60
+
61
+ Do not put your Visgate API key in the client. Use a server-side proxy that adds the key:
62
+
63
+ ```javascript
64
+ const client = new Client({ proxyUrl: "/api/visgate" });
65
+ // No apiKey needed — the proxy adds Authorization on the server
66
+ ```
67
+
68
+ Set `VISGATE_API_KEY` on the server. This repo includes a ready-made proxy package: **`server-proxy/`** (published as `@visgate_ai/server-proxy` on npm). See [server-proxy/README.md](server-proxy/README.md) for setup; or implement your own forward that injects the key.
69
+
70
+ ## BYOK (Bring Your Own Key)
71
+
72
+ ```javascript
73
+ const client = new Client({
74
+ apiKey: "vg-...",
75
+ falKey: "fal_...",
76
+ replicateKey: "r8_...",
77
+ runwayKey: "rw_...",
78
+ });
79
+ ```
80
+
81
+ ## API Reference
82
+
83
+ ### Image Generation
84
+
85
+ ```javascript
86
+ // Quick generation (unified POST /generate)
87
+ const result = await client.generate("a cat in space", { model: "fal-ai/flux/schnell" });
88
+ console.log(result.status, result.imageUrl, result.cost);
89
+
90
+ // Full control (POST /images/generate) — matches API ImageGenerateRequest
91
+ const result = await client.images.generate("fal-ai/flux/schnell", "a cat in space", {
92
+ width: 1024,
93
+ height: 1024,
94
+ numImages: 1,
95
+ negativePrompt: null,
96
+ seed: null,
97
+ imageUrl: null, // optional: input image for img2img
98
+ preferCache: true, // use cache (exact or semantic match)
99
+ maxLatencyMs: null, // optional: max acceptable latency (ms)
100
+ webhookUrl: null, // optional: callback URL when done
101
+ callbackId: null, // optional: id in callback payload
102
+ });
103
+ // result: id, status, images, model, provider, cost, cacheHit, cacheSource?, latencyMs, savedAmount?, marginPercent?, createdAt
104
+ ```
105
+
106
+ ### Video Generation
107
+
108
+ Video generation can take several minutes. To **avoid 502** when the request takes longer than proxy/Cloudflare timeout, use **async mode** (`preferAsync: true`): the API returns 202 immediately, then poll `client.requests.get(requestId)` until completed.
109
+
110
+ Use `VIDEO_MODEL_PRESETS` for provider model IDs (Fal, Replicate, Runway), or pass a model string (e.g. `fal-ai/veo3`, `replicate/lucataco/cogvideox-5b`, `runway/gen4_turbo`). For **image-to-video**, set `imageUrl` or `imageFile` in options.
111
+
112
+ ```javascript
113
+ import { Client, VIDEO_MODEL_PRESETS } from "@visgate_ai/client";
114
+
115
+ const client = new Client({ proxyUrl: "/api/visgate", timeout: 300_000 });
116
+
117
+ // Sync (wait for result; may hit proxy timeout on long videos)
118
+ const syncResult = await client.videos.generate(VIDEO_MODEL_PRESETS.fal, "waves on a beach", {
119
+ durationSeconds: 6,
120
+ skipGcsUpload: true,
121
+ });
122
+ console.log(syncResult.videoUrl, syncResult.cacheHit, syncResult.cost);
123
+
124
+ // Async (recommended): returns 202, poll client.requests.get(requestId)
125
+ const result = await client.videos.generate("fal-ai/veo3", "waves on a beach", {
126
+ durationSeconds: 6,
127
+ skipGcsUpload: true, // faster; return provider URL directly
128
+ preferAsync: true, // avoids 502 — returns 202, poll client.requests.get(requestId)
129
+ imageUrl: null, // optional: input image for img2vid (or use imageFile)
130
+ webhookUrl: null, // optional: callback URL when done
131
+ callbackId: null, // optional: id in callback payload
132
+ params: {}, // optional: extra provider params
133
+ });
134
+ if (result.status === "accepted") {
135
+ let status = await client.requests.get(result.requestId);
136
+ while (status.status === "pending" || status.status === "processing") {
137
+ await new Promise((r) => setTimeout(r, 3000));
138
+ status = await client.requests.get(result.requestId);
139
+ }
140
+ console.log(status.status, status.outputUrl);
141
+ } else {
142
+ console.log(result.videoUrl, result.cacheHit, result.status);
143
+ }
144
+ ```
145
+
146
+ On the server, set the proxy route’s `maxDuration` (e.g. 300 seconds) so the request is not cut off — see [server-proxy/README.md](server-proxy/README.md).
147
+
148
+ ### Async request status (Requests)
149
+
150
+ After starting an async generation (video or image with `preferAsync: true`), poll the request status until completion:
151
+
152
+ ```javascript
153
+ const status = await client.requests.get(result.requestId);
154
+ // status: requestId, status ("pending" | "processing" | "completed" | "failed"),
155
+ // mediaType, provider, model, outputUrl, errorMessage, createdAt, completedAt
156
+ ```
157
+
158
+ ### Model Discovery
159
+
160
+ ```javascript
161
+ const resp = await client.models.list({ provider: "fal", mediaType: "image", limit: 20 });
162
+ for (const m of resp.models) console.log(m.id, m.name);
163
+
164
+ const model = await client.models.get("fal-ai/flux/schnell");
165
+ ```
166
+
167
+ ### Usage and Billing
168
+
169
+ ```javascript
170
+ const usage = await client.usage.get("month");
171
+ console.log(usage.totalRequests, usage.totalBilledCost, usage.cacheHitRate, usage.avgLatency, usage.history);
172
+
173
+ const logs = await client.usage.logs({ limit: 50 });
174
+ const dashboard = await client.usage.dashboard("week");
175
+
176
+ // Track download event (POST /usage/downloads)
177
+ await client.usage.trackDownload("request-id", "https://...", { mediaType: "image" });
178
+ ```
179
+
180
+ ### Billing
181
+
182
+ ```javascript
183
+ const stats = await client.billing.getStats(); // public stats
184
+ const info = await client.billing.getInfo(); // org billing info (tier, balance, etc.)
185
+ const pricing = await client.billing.getPricing(); // model pricing list
186
+ await client.billing.checkout(10, "https://...", { customerEmail: "..." });
187
+ await client.billing.updateSubscription("starter");
188
+ ```
189
+
190
+ ### Provider Management
191
+
192
+ ```javascript
193
+ const keys = await client.providers.listKeys();
194
+ const balances = await client.providers.balances();
195
+ ```
196
+
197
+ ### Health Check
198
+
199
+ ```javascript
200
+ const health = await client.health();
201
+ console.log(health.status);
202
+ ```
203
+
204
+ ## Error Handling
205
+
206
+ ```javascript
207
+ import { Client, AuthenticationError, RateLimitError, ProviderError, ValidationError, VisgateError } from "@visgate_ai/client";
208
+
209
+ const client = new Client({ apiKey: "vg-..." });
210
+
211
+ try {
212
+ const result = await client.generate("a sunset");
213
+ } catch (err) {
214
+ if (err instanceof AuthenticationError) console.error("Invalid API key");
215
+ else if (err instanceof RateLimitError) console.error("Rate limit", err.retryAfter);
216
+ else if (err instanceof ProviderError) console.error("Provider error", err.provider);
217
+ else if (err instanceof ValidationError) console.error("Validation", err.field);
218
+ else if (err instanceof VisgateError) console.error(err.message, err.errorCode);
219
+ }
220
+ ```
221
+
222
+ ## Configuration
223
+
224
+ | Option | Default | Description |
225
+ | ------------ | --------------------------- | ------------------------------ |
226
+ | `apiKey` | `process.env.VISGATE_API_KEY` | Visgate API key (optional when using `proxyUrl`) |
227
+ | `proxyUrl` | — | Server proxy URL; when set, no key or BYOK is sent |
228
+ | `baseUrl` | `https://visgateai.com/api/v1` | API base URL |
229
+ | `timeout` | `120000` (ms) | Request timeout |
230
+ | `maxRetries` | `2` | Retries for 429 and 5xx |
231
+ | `falKey` | — | Fal BYOK key |
232
+ | `replicateKey` | — | Replicate BYOK key |
233
+ | `runwayKey` | — | Runway BYOK key |
234
+
235
+ ## AsyncClient
236
+
237
+ For API parity with the Python SDK, `AsyncClient` is also exported; it has the same interface as `Client` (all methods return Promises).
238
+
239
+ ```javascript
240
+ import { AsyncClient } from "@visgate_ai/client";
241
+
242
+ const client = new AsyncClient();
243
+ const result = await client.generate("a sunset");
244
+ ```
245
+
246
+ ## Repository structure
247
+
248
+ - **`src/`** — @visgate_ai/client (client library): `generate`, `images`, `videos`, `models`, `requests` (async status), `usage`, `providers`, `billing`
249
+ - **`server-proxy/`** — `@visgate_ai/server-proxy`: server-side proxy for Next.js and other Node runtimes. Install with `npm install @visgate_ai/server-proxy` or use locally from this repo.
250
+ - **`examples/`** — Next.js, vanilla, and Vite examples
251
+
252
+ ## License
253
+
254
+ MIT — see [LICENSE](LICENSE).