chub-dev 0.1.0 → 0.1.2-beta.0

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.
Files changed (139) hide show
  1. package/README.md +55 -0
  2. package/bin/chub-mcp +2 -0
  3. package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
  4. package/dist/airtable/docs/database/python/DOC.md +1735 -0
  5. package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
  6. package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
  7. package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
  8. package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
  9. package/dist/asana/docs/tasks/DOC.md +1396 -0
  10. package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
  11. package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
  12. package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
  13. package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
  14. package/dist/auth0/docs/identity/python/DOC.md +1199 -0
  15. package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
  16. package/dist/aws/docs/s3/python/DOC.md +1807 -0
  17. package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
  18. package/dist/binance/docs/trading/python/DOC.md +1454 -0
  19. package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
  20. package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
  21. package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
  22. package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
  23. package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
  24. package/dist/clerk/docs/auth/python/DOC.md +274 -0
  25. package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
  26. package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
  27. package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
  28. package/dist/cohere/docs/llm/DOC.md +1335 -0
  29. package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
  30. package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
  31. package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
  32. package/dist/deepgram/docs/speech/python/DOC.md +685 -0
  33. package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
  34. package/dist/deepl/docs/translation/python/DOC.md +944 -0
  35. package/dist/deepseek/docs/llm/DOC.md +1220 -0
  36. package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
  37. package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
  38. package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
  39. package/dist/discord/docs/bot/python/DOC.md +1130 -0
  40. package/dist/elasticsearch/docs/search/DOC.md +1634 -0
  41. package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
  42. package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
  43. package/dist/firebase/docs/auth/DOC.md +1015 -0
  44. package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
  45. package/dist/gemini/docs/genai/python/DOC.md +555 -0
  46. package/dist/github/docs/octokit/DOC.md +1560 -0
  47. package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
  48. package/dist/google/docs/bigquery/python/DOC.md +1503 -0
  49. package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
  50. package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
  51. package/dist/huggingface/docs/transformers/DOC.md +948 -0
  52. package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
  53. package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
  54. package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
  55. package/dist/jira/docs/issues/python/DOC.md +1492 -0
  56. package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
  57. package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
  58. package/dist/landingai-ade/docs/api/DOC.md +620 -0
  59. package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
  60. package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
  61. package/dist/landingai-ade/skills/SKILL.md +489 -0
  62. package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
  63. package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
  64. package/dist/linear/docs/tracker/DOC.md +1554 -0
  65. package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
  66. package/dist/livekit/docs/realtime/python/DOC.md +163 -0
  67. package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
  68. package/dist/meilisearch/docs/search/DOC.md +1241 -0
  69. package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
  70. package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
  71. package/dist/mongodb/docs/atlas/DOC.md +2041 -0
  72. package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
  73. package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
  74. package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
  75. package/dist/okta/docs/identity/python/DOC.md +1401 -0
  76. package/dist/openai/docs/chat/javascript/DOC.md +407 -0
  77. package/dist/openai/docs/chat/python/DOC.md +568 -0
  78. package/dist/paypal/docs/checkout/DOC.md +278 -0
  79. package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
  80. package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
  81. package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
  82. package/dist/plaid/docs/banking/python/DOC.md +1203 -0
  83. package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
  84. package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
  85. package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
  86. package/dist/prisma/docs/orm/python/DOC.md +1317 -0
  87. package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
  88. package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
  89. package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
  90. package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
  91. package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
  92. package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
  93. package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
  94. package/dist/redis/docs/key-value/python/DOC.md +2054 -0
  95. package/dist/registry.json +2817 -0
  96. package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
  97. package/dist/resend/docs/email/DOC.md +1271 -0
  98. package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
  99. package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
  100. package/dist/search-index.json +1 -0
  101. package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
  102. package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
  103. package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
  104. package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
  105. package/dist/shopify/docs/storefront/DOC.md +457 -0
  106. package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
  107. package/dist/slack/docs/workspace/python/DOC.md +271 -0
  108. package/dist/square/docs/payments/javascript/DOC.md +1855 -0
  109. package/dist/square/docs/payments/python/DOC.md +1728 -0
  110. package/dist/stripe/docs/api/DOC.md +1727 -0
  111. package/dist/stripe/docs/payments/DOC.md +1726 -0
  112. package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
  113. package/dist/stytch/docs/auth/python/DOC.md +1962 -0
  114. package/dist/supabase/docs/client/DOC.md +1606 -0
  115. package/dist/twilio/docs/messaging/python/DOC.md +469 -0
  116. package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
  117. package/dist/vercel/docs/platform/DOC.md +1940 -0
  118. package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
  119. package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
  120. package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
  121. package/dist/zendesk/docs/support/python/DOC.md +2297 -0
  122. package/package.json +22 -6
  123. package/skills/get-api-docs/SKILL.md +84 -0
  124. package/src/commands/annotate.js +83 -0
  125. package/src/commands/build.js +12 -1
  126. package/src/commands/feedback.js +150 -0
  127. package/src/commands/get.js +83 -42
  128. package/src/commands/search.js +7 -0
  129. package/src/index.js +43 -17
  130. package/src/lib/analytics.js +90 -0
  131. package/src/lib/annotations.js +57 -0
  132. package/src/lib/bm25.js +170 -0
  133. package/src/lib/cache.js +69 -6
  134. package/src/lib/config.js +8 -3
  135. package/src/lib/identity.js +99 -0
  136. package/src/lib/registry.js +103 -20
  137. package/src/lib/telemetry.js +86 -0
  138. package/src/mcp/server.js +177 -0
  139. package/src/mcp/tools.js +251 -0
@@ -0,0 +1,1318 @@
1
+ ---
2
+ name: model-hosting
3
+ description: "Replicate JavaScript SDK coding guide for running ML models via the official Replicate npm package"
4
+ metadata:
5
+ languages: "javascript"
6
+ versions: "1.3.1"
7
+ updated-on: "2026-03-02"
8
+ source: maintainer
9
+ tags: "replicate,model-hosting,ml,inference,ai"
10
+ ---
11
+
12
+ # Replicate JavaScript SDK Coding Guide
13
+
14
+ ## 1. Golden Rule
15
+
16
+ **Always use the official Replicate SDK package:** `replicate` from npm. The GitHub repository is `replicate/replicate-javascript`.
17
+
18
+ **Never use unofficial or deprecated libraries.** The `replicate` package is the only officially supported Node.js/JavaScript SDK maintained by Replicate. Do not use packages like `replicate-api` or other third-party alternatives.
19
+
20
+ **Important version note:** This SDK requires Node.js 18 or later, as it uses the native `fetch` API available in modern Node.js environments.
21
+
22
+ ## 2. Installation
23
+
24
+ ### npm
25
+ ```bash
26
+ npm install replicate
27
+ ```
28
+
29
+ ### yarn
30
+ ```bash
31
+ yarn add replicate
32
+ ```
33
+
34
+ ### pnpm
35
+ ```bash
36
+ pnpm add replicate
37
+ ```
38
+
39
+ **Environment Variables (Required):**
40
+ ```bash
41
+ REPLICATE_API_TOKEN=r8_your_api_token_here
42
+ ```
43
+
44
+ **Optional Environment Variables:**
45
+ ```bash
46
+ REPLICATE_API_BASE_URL=https://api.replicate.com/v1 # Custom API endpoint
47
+ ```
48
+
49
+ **Security Best Practices:** Never hardcode API tokens in source code. Use environment variables or secure secret management services. Use different tokens for development, staging, and production. Refresh tokens periodically. Never commit tokens to version control. Replicate automatically scans GitHub for accidentally committed tokens and disables them.
50
+
51
+ ## 3. Initialization
52
+
53
+ ### Basic Initialization
54
+ ```javascript
55
+ import Replicate from "replicate";
56
+
57
+ const replicate = new Replicate({
58
+ auth: process.env.REPLICATE_API_TOKEN,
59
+ });
60
+ ```
61
+
62
+ ### Custom Configuration
63
+ ```javascript
64
+ import Replicate from "replicate";
65
+
66
+ const replicate = new Replicate({
67
+ auth: process.env.REPLICATE_API_TOKEN,
68
+ userAgent: "my-app/1.0.0",
69
+ baseUrl: "https://api.replicate.com/v1",
70
+ fetch: customFetch, // Custom fetch implementation
71
+ fileEncodingStrategy: "upload", // "upload" or "no-upload"
72
+ });
73
+ ```
74
+
75
+ ### TypeScript Usage
76
+ ```typescript
77
+ import Replicate from "replicate";
78
+ import type { Prediction, Model, Training } from "replicate";
79
+
80
+ const replicate = new Replicate({
81
+ auth: process.env.REPLICATE_API_TOKEN,
82
+ });
83
+ ```
84
+
85
+ **File Encoding Strategy:** `"upload"` (default) automatically uploads file handles to Replicate's file storage. `"no-upload"` does not upload files and is useful when you want to manage file uploads manually.
86
+
87
+ ## 4. Core API Surfaces
88
+
89
+ ### Running Models with `replicate.run()`
90
+
91
+ **Minimal Example:**
92
+ ```javascript
93
+ const output = await replicate.run(
94
+ "black-forest-labs/flux-schnell",
95
+ {
96
+ input: {
97
+ prompt: "a 19th century portrait of a raccoon gentleman wearing a suit"
98
+ }
99
+ }
100
+ );
101
+
102
+ console.log(output);
103
+ ```
104
+
105
+ **Advanced Example with Version and Options:**
106
+ ```javascript
107
+ const output = await replicate.run(
108
+ "stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
109
+ {
110
+ input: {
111
+ prompt: "a futuristic cityscape at sunset",
112
+ negative_prompt: "blurry, low quality",
113
+ num_inference_steps: 50,
114
+ guidance_scale: 7.5,
115
+ width: 1024,
116
+ height: 1024,
117
+ seed: 42
118
+ },
119
+ wait: {
120
+ mode: "block", // "block" or "poll"
121
+ interval: 500, // Polling interval in ms (default 500)
122
+ }
123
+ },
124
+ (progress) => {
125
+ console.log("Progress:", progress);
126
+ }
127
+ );
128
+ ```
129
+
130
+ **Identifier Formats:**
131
+
132
+ The identifier parameter accepts three formats:
133
+
134
+ 1. **Model name only** (uses latest version):
135
+ ```javascript
136
+ "black-forest-labs/flux-schnell"
137
+ ```
138
+
139
+ 2. **Model name with version**:
140
+ ```javascript
141
+ "stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b"
142
+ ```
143
+
144
+ 3. **Version ID only**:
145
+ ```javascript
146
+ "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b"
147
+ ```
148
+
149
+ **Progress Callback:**
150
+ ```javascript
151
+ const output = await replicate.run(
152
+ "meta/llama-2-70b-chat",
153
+ {
154
+ input: {
155
+ prompt: "Write a story about a brave knight"
156
+ }
157
+ },
158
+ (prediction) => {
159
+ console.log("Status:", prediction.status);
160
+ if (prediction.output) {
161
+ console.log("Partial output:", prediction.output);
162
+ }
163
+ }
164
+ );
165
+ ```
166
+
167
+ ### Streaming Output with `replicate.stream()`
168
+
169
+ **Minimal Streaming Example:**
170
+ ```javascript
171
+ for await (const event of replicate.stream(
172
+ "meta/llama-2-70b-chat",
173
+ {
174
+ input: {
175
+ prompt: "Tell me a story about a dragon"
176
+ }
177
+ }
178
+ )) {
179
+ process.stdout.write(event.toString());
180
+ }
181
+ ```
182
+
183
+ **Advanced Streaming with Event Handling:**
184
+ ```javascript
185
+ const stream = await replicate.stream(
186
+ "meta/llama-2-70b-chat",
187
+ {
188
+ input: {
189
+ prompt: "Explain quantum computing",
190
+ max_new_tokens: 500,
191
+ temperature: 0.7
192
+ }
193
+ }
194
+ );
195
+
196
+ let fullOutput = "";
197
+
198
+ for await (const event of stream) {
199
+ if (event.event === "output") {
200
+ fullOutput += event.data;
201
+ process.stdout.write(event.data);
202
+ } else if (event.event === "error") {
203
+ console.error("Error:", event.data);
204
+ } else if (event.event === "done") {
205
+ console.log("\nGeneration complete");
206
+ }
207
+ }
208
+
209
+ console.log("\nFull output:", fullOutput);
210
+ ```
211
+
212
+ **Streaming with EventSource (Server-Sent Events):**
213
+ ```javascript
214
+ import Replicate from "replicate";
215
+
216
+ const replicate = new Replicate({
217
+ auth: process.env.REPLICATE_API_TOKEN,
218
+ });
219
+
220
+ // Create a prediction with streaming enabled
221
+ const prediction = await replicate.predictions.create({
222
+ version: "2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1",
223
+ input: {
224
+ prompt: "Tell me a story"
225
+ },
226
+ stream: true,
227
+ });
228
+
229
+ // For browser environments
230
+ if (typeof EventSource !== 'undefined') {
231
+ const source = new EventSource(prediction.urls.stream, {
232
+ withCredentials: true,
233
+ });
234
+
235
+ source.addEventListener("output", (e) => {
236
+ console.log("Output:", e.data);
237
+ });
238
+
239
+ source.addEventListener("error", (e) => {
240
+ console.error("Error:", JSON.parse(e.data));
241
+ source.close();
242
+ });
243
+
244
+ source.addEventListener("done", (e) => {
245
+ console.log("Done:", JSON.parse(e.data));
246
+ source.close();
247
+ });
248
+ }
249
+ ```
250
+
251
+ ### Predictions API
252
+
253
+ **Create a Prediction:**
254
+ ```javascript
255
+ const prediction = await replicate.predictions.create({
256
+ version: "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
257
+ input: {
258
+ prompt: "a beautiful landscape"
259
+ }
260
+ });
261
+
262
+ console.log(prediction.id);
263
+ console.log(prediction.status); // "starting"
264
+ ```
265
+
266
+ **Advanced Prediction with All Options:**
267
+ ```javascript
268
+ const prediction = await replicate.predictions.create({
269
+ version: "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
270
+ input: {
271
+ prompt: "astronaut riding a horse on mars",
272
+ width: 1024,
273
+ height: 1024,
274
+ num_inference_steps: 50
275
+ },
276
+ webhook: "https://api.myapp.com/webhooks/replicate",
277
+ webhook_events_filter: ["start", "output", "logs", "completed"],
278
+ stream: false,
279
+ wait: {
280
+ mode: "poll",
281
+ interval: 500
282
+ }
283
+ });
284
+ ```
285
+
286
+ **Get Prediction Status:**
287
+ ```javascript
288
+ const prediction = await replicate.predictions.get("gm3qorzdhgbfurvjtvhg6dckhu");
289
+
290
+ console.log(prediction.status); // "succeeded", "processing", "failed", "canceled"
291
+ console.log(prediction.output);
292
+ console.log(prediction.logs);
293
+ console.log(prediction.metrics);
294
+ ```
295
+
296
+ **Wait for Prediction to Complete:**
297
+ ```javascript
298
+ let prediction = await replicate.predictions.create({
299
+ version: "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
300
+ input: { prompt: "a serene lake" }
301
+ });
302
+
303
+ // Poll until completion
304
+ prediction = await replicate.wait(prediction);
305
+
306
+ console.log(prediction.status); // "succeeded" or "failed"
307
+ console.log(prediction.output);
308
+ ```
309
+
310
+ **Cancel a Prediction:**
311
+ ```javascript
312
+ const canceled = await replicate.predictions.cancel("gm3qorzdhgbfurvjtvhg6dckhu");
313
+
314
+ console.log(canceled.status); // "canceled"
315
+ ```
316
+
317
+ **Important:** If you cancel a prediction before it starts, there's no charge. If you cancel after it starts, you're billed for the time used.
318
+
319
+ **List Predictions:**
320
+ ```javascript
321
+ // Automatic pagination
322
+ for await (const prediction of replicate.predictions.list()) {
323
+ console.log(prediction.id, prediction.status);
324
+ }
325
+
326
+ // Manual pagination
327
+ let page = await replicate.predictions.list();
328
+ for (const prediction of page.results) {
329
+ console.log(prediction.id);
330
+ }
331
+
332
+ while (page.next) {
333
+ page = await replicate.predictions.list({ cursor: page.next });
334
+ for (const prediction of page.results) {
335
+ console.log(prediction.id);
336
+ }
337
+ }
338
+ ```
339
+
340
+ ### Models API
341
+
342
+ **Get Model Information:**
343
+ ```javascript
344
+ const model = await replicate.models.get("stability-ai", "sdxl");
345
+
346
+ console.log(model.name);
347
+ console.log(model.description);
348
+ console.log(model.latest_version);
349
+ console.log(model.visibility); // "public" or "private"
350
+ ```
351
+
352
+ **List All Models:**
353
+ ```javascript
354
+ // Automatic pagination
355
+ const allModels = [];
356
+ for await (const model of replicate.models.list()) {
357
+ allModels.push(model);
358
+ }
359
+
360
+ // Manual pagination
361
+ let page = await replicate.models.list();
362
+ for (const model of page.results) {
363
+ console.log(model.owner, model.name);
364
+ }
365
+
366
+ while (page.hasNextPage()) {
367
+ page = await page.getNextPage();
368
+ for (const model of page.results) {
369
+ console.log(model.owner, model.name);
370
+ }
371
+ }
372
+ ```
373
+
374
+ **Get Model Versions:**
375
+ ```javascript
376
+ const versions = await replicate.models.versions.list(
377
+ "stability-ai",
378
+ "sdxl"
379
+ );
380
+
381
+ for await (const version of versions) {
382
+ console.log(version.id);
383
+ console.log(version.created_at);
384
+ }
385
+ ```
386
+
387
+ **Get Specific Version:**
388
+ ```javascript
389
+ const version = await replicate.models.versions.get(
390
+ "stability-ai",
391
+ "sdxl",
392
+ "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b"
393
+ );
394
+
395
+ console.log(version.openapi_schema); // Input/output schema
396
+ ```
397
+
398
+ **Create a Model:**
399
+ ```javascript
400
+ const model = await replicate.models.create({
401
+ owner: "your-username",
402
+ name: "my-custom-model",
403
+ description: "A custom model for specific tasks",
404
+ visibility: "private", // "public" or "private"
405
+ hardware: "gpu-a40-large"
406
+ });
407
+ ```
408
+
409
+ ### Collections API
410
+
411
+ **Get Collection:**
412
+ ```javascript
413
+ const collection = await replicate.collections.get("text-to-image");
414
+
415
+ console.log(collection.name);
416
+ console.log(collection.description);
417
+
418
+ for (const model of collection.models) {
419
+ console.log(model.owner, model.name);
420
+ }
421
+ ```
422
+
423
+ **List Featured Collections:**
424
+ ```javascript
425
+ // Collections are curated lists of models available at replicate.com/collections
426
+ const collection = await replicate.collections.get("super-resolution");
427
+
428
+ collection.models.forEach(model => {
429
+ console.log(`${model.owner}/${model.name}: ${model.description}`);
430
+ });
431
+ ```
432
+
433
+ ### Deployments API
434
+
435
+ **Create a Deployment:**
436
+ ```javascript
437
+ const deployment = await replicate.deployments.create({
438
+ name: "my-production-deployment",
439
+ model: "stability-ai/sdxl",
440
+ version: "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
441
+ hardware: "gpu-a40-large",
442
+ min_instances: 1,
443
+ max_instances: 5
444
+ });
445
+
446
+ console.log(deployment.url);
447
+ ```
448
+
449
+ **Available Hardware SKUs:** To list all available hardware SKUs and their specifications programmatically, use `await replicate.hardware.list()`. Common options include `"cpu"`, `"gpu-t4"`, `"gpu-a40-small"`, `"gpu-a40-large"`, and `"gpu-a100"`. From the CLI, run `replicate hardware list` to see all available hardware types with their SKUs, names, and specifications.
450
+
451
+ **Get Deployment:**
452
+ ```javascript
453
+ const deployment = await replicate.deployments.get(
454
+ "your-username",
455
+ "my-production-deployment"
456
+ );
457
+
458
+ console.log(deployment.current_version);
459
+ console.log(deployment.hardware);
460
+ console.log(deployment.min_instances);
461
+ console.log(deployment.max_instances);
462
+ ```
463
+
464
+ **Update Deployment:**
465
+ ```javascript
466
+ const updated = await replicate.deployments.update(
467
+ "your-username",
468
+ "my-production-deployment",
469
+ {
470
+ version: "new-version-id",
471
+ min_instances: 2,
472
+ max_instances: 10
473
+ }
474
+ );
475
+ ```
476
+
477
+ **List Deployments:**
478
+ ```javascript
479
+ for await (const deployment of replicate.deployments.list()) {
480
+ console.log(deployment.owner, deployment.name);
481
+ }
482
+ ```
483
+
484
+ **Run Prediction on Deployment:**
485
+ ```javascript
486
+ const prediction = await replicate.deployments.predictions.create(
487
+ "your-username",
488
+ "my-production-deployment",
489
+ {
490
+ input: {
491
+ prompt: "a beautiful sunset"
492
+ }
493
+ }
494
+ );
495
+
496
+ console.log(prediction.output);
497
+ ```
498
+
499
+ **Delete Deployment:**
500
+ ```javascript
501
+ await replicate.deployments.delete(
502
+ "your-username",
503
+ "my-production-deployment"
504
+ );
505
+ ```
506
+
507
+ ### Training API
508
+
509
+ **Create Training:**
510
+ ```javascript
511
+ const training = await replicate.trainings.create(
512
+ "stability-ai",
513
+ "sdxl",
514
+ "39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
515
+ {
516
+ destination: "your-username/my-fine-tuned-model",
517
+ input: {
518
+ input_images: "https://example.com/training-data.zip",
519
+ learning_rate: 1e-6,
520
+ num_train_epochs: 100
521
+ },
522
+ webhook: "https://api.myapp.com/webhooks/training-complete"
523
+ }
524
+ );
525
+
526
+ console.log(training.id);
527
+ console.log(training.status); // "starting"
528
+ ```
529
+
530
+ **Get Training Status:**
531
+ ```javascript
532
+ const training = await replicate.trainings.get("zz4ibbonubfz7carwiefibzgga");
533
+
534
+ console.log(training.status); // "succeeded", "processing", "failed", "canceled"
535
+ console.log(training.output); // New model version created
536
+ console.log(training.logs);
537
+ ```
538
+
539
+ **Cancel Training:**
540
+ ```javascript
541
+ const canceled = await replicate.trainings.cancel("zz4ibbonubfz7carwiefibzgga");
542
+ console.log(canceled.status); // "canceled"
543
+ ```
544
+
545
+ **List Trainings:**
546
+ ```javascript
547
+ for await (const training of replicate.trainings.list()) {
548
+ console.log(training.id, training.status);
549
+ }
550
+ ```
551
+
552
+ ### Files API
553
+
554
+ **Upload File:**
555
+ ```javascript
556
+ import fs from "fs";
557
+
558
+ const file = await replicate.files.create(
559
+ fs.readFileSync("path/to/image.png")
560
+ );
561
+
562
+ console.log(file.id);
563
+ console.log(file.urls.get); // URL to download the file
564
+ ```
565
+
566
+ **Use File in Prediction:**
567
+ ```javascript
568
+ import fs from "fs";
569
+
570
+ // Upload file first
571
+ const file = await replicate.files.create(
572
+ fs.readFileSync("input-image.png")
573
+ );
574
+
575
+ // Use file handle in prediction
576
+ const prediction = await replicate.predictions.create({
577
+ version: "image-to-image-model-version-id",
578
+ input: {
579
+ image: file.urls.get,
580
+ prompt: "turn this into a watercolor painting"
581
+ }
582
+ });
583
+ ```
584
+
585
+ **File Encoding Strategy:**
586
+ ```javascript
587
+ // Automatically upload files (default behavior)
588
+ const replicateAutoUpload = new Replicate({
589
+ auth: process.env.REPLICATE_API_TOKEN,
590
+ fileEncodingStrategy: "upload"
591
+ });
592
+
593
+ // Manual file management (no automatic upload)
594
+ const replicateManual = new Replicate({
595
+ auth: process.env.REPLICATE_API_TOKEN,
596
+ fileEncodingStrategy: "no-upload"
597
+ });
598
+ ```
599
+
600
+ **Get File:**
601
+ ```javascript
602
+ const file = await replicate.files.get("file-id-here");
603
+ console.log(file.urls.get);
604
+ ```
605
+
606
+ **List Files:**
607
+ ```javascript
608
+ for await (const file of replicate.files.list()) {
609
+ console.log(file.id, file.created_at);
610
+ }
611
+ ```
612
+
613
+ **Delete File:**
614
+ ```javascript
615
+ await replicate.files.delete("file-id-here");
616
+ ```
617
+
618
+ ### Hardware API
619
+
620
+ **List Available Hardware:**
621
+ ```javascript
622
+ const hardware = await replicate.hardware.list();
623
+
624
+ for (const sku of hardware) {
625
+ console.log(sku.name);
626
+ console.log(sku.sku);
627
+ }
628
+ ```
629
+
630
+ ### Account API
631
+
632
+ **Get Account Information:**
633
+ ```javascript
634
+ const account = await replicate.account.get();
635
+
636
+ console.log(account.type); // "user" or "organization"
637
+ console.log(account.username);
638
+ console.log(account.name);
639
+ ```
640
+
641
+ ## 5. Webhooks
642
+
643
+ ### Setting Up Webhooks
644
+
645
+ **Create Prediction with Webhook:**
646
+ ```javascript
647
+ const prediction = await replicate.predictions.create({
648
+ version: "model-version-id",
649
+ input: {
650
+ prompt: "a painting of a cat"
651
+ },
652
+ webhook: "https://api.myapp.com/webhooks/replicate",
653
+ webhook_events_filter: ["start", "output", "logs", "completed"]
654
+ });
655
+ ```
656
+
657
+ **Webhook Event Types:** `"start"` fires when prediction starts processing. `"output"` fires each time prediction generates output (throttled to max 1 per 500ms). `"logs"` fires each time log output is generated (throttled to max 1 per 500ms). `"completed"` fires when prediction reaches terminal state (succeeded/failed/canceled).
658
+
659
+ **Webhook Payload Example:**
660
+ ```javascript
661
+ {
662
+ "id": "gm3qorzdhgbfurvjtvhg6dckhu",
663
+ "status": "succeeded",
664
+ "output": ["https://replicate.delivery/output.png"],
665
+ "created_at": "2024-01-15T10:30:00.000Z",
666
+ "started_at": "2024-01-15T10:30:01.000Z",
667
+ "completed_at": "2024-01-15T10:30:05.000Z",
668
+ "metrics": {
669
+ "predict_time": 4.2
670
+ },
671
+ "logs": "Processing complete",
672
+ "error": null
673
+ }
674
+ ```
675
+
676
+ **Webhook Handler (Express.js):**
677
+ ```javascript
678
+ import express from "express";
679
+ import crypto from "crypto";
680
+
681
+ const app = express();
682
+ app.use(express.json());
683
+
684
+ app.post("/webhooks/replicate", async (req, res) => {
685
+ const prediction = req.body;
686
+
687
+ console.log("Webhook received:", prediction.id);
688
+ console.log("Status:", prediction.status);
689
+
690
+ if (prediction.status === "succeeded") {
691
+ console.log("Output:", prediction.output);
692
+ // Process the output
693
+ await processOutput(prediction.output);
694
+ } else if (prediction.status === "failed") {
695
+ console.error("Prediction failed:", prediction.error);
696
+ // Handle failure
697
+ }
698
+
699
+ // Always respond quickly to webhooks
700
+ res.status(200).json({ received: true });
701
+ });
702
+ ```
703
+
704
+ **Webhook Best Practices:** Respond to webhooks within 30 seconds with 200 OK. Process webhook payloads asynchronously (don't block the response). Implement idempotency since webhooks may be retried. Replicate will retry failed webhooks automatically. Use HTTPS endpoints for webhooks. Validate webhook authenticity in production.
705
+
706
+ ### Webhook Security
707
+
708
+ **Implement Webhook Signature Verification (recommended for production):**
709
+ ```javascript
710
+ // Note: Replicate webhook signature verification details
711
+ // Check Replicate's documentation for current signature scheme
712
+
713
+ app.post("/webhooks/replicate", (req, res) => {
714
+ const signature = req.headers['x-replicate-signature'];
715
+ const secret = process.env.WEBHOOK_SECRET;
716
+
717
+ // Verify signature (implementation depends on Replicate's scheme)
718
+ if (!verifySignature(signature, req.body, secret)) {
719
+ return res.status(401).json({ error: "Invalid signature" });
720
+ }
721
+
722
+ // Process webhook
723
+ const prediction = req.body;
724
+ processWebhook(prediction);
725
+
726
+ res.status(200).json({ received: true });
727
+ });
728
+ ```
729
+
730
+ ## 6. Advanced Features
731
+
732
+ ### Error Handling
733
+
734
+ **Comprehensive Error Handling:**
735
+ ```javascript
736
+ import Replicate from "replicate";
737
+
738
+ async function runModelSafely() {
739
+ try {
740
+ const output = await replicate.run(
741
+ "stability-ai/sdxl",
742
+ {
743
+ input: {
744
+ prompt: "a beautiful landscape"
745
+ }
746
+ }
747
+ );
748
+
749
+ return output;
750
+ } catch (error) {
751
+ // Handle specific error types
752
+ if (error.response) {
753
+ // API error response
754
+ console.error("Status:", error.response.status);
755
+ console.error("Error:", error.response.data);
756
+
757
+ if (error.response.status === 401) {
758
+ throw new Error("Invalid API token");
759
+ } else if (error.response.status === 402) {
760
+ throw new Error("Insufficient credits");
761
+ } else if (error.response.status === 429) {
762
+ throw new Error("Rate limit exceeded");
763
+ } else if (error.response.status === 500) {
764
+ throw new Error("Replicate server error");
765
+ }
766
+ } else if (error.request) {
767
+ // Network error
768
+ console.error("Network error:", error.message);
769
+ throw new Error("Failed to connect to Replicate API");
770
+ } else {
771
+ // Other errors
772
+ console.error("Error:", error.message);
773
+ throw error;
774
+ }
775
+ }
776
+ }
777
+ ```
778
+
779
+ **Retry Logic with Exponential Backoff:**
780
+ ```javascript
781
+ async function runWithRetry(identifier, options, maxRetries = 3) {
782
+ let lastError;
783
+
784
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
785
+ try {
786
+ const output = await replicate.run(identifier, options);
787
+ return output;
788
+ } catch (error) {
789
+ lastError = error;
790
+
791
+ // Only retry on transient errors
792
+ const isRetryable =
793
+ error.response?.status === 429 || // Rate limit
794
+ error.response?.status === 500 || // Server error
795
+ error.response?.status === 503 || // Service unavailable
796
+ !error.response; // Network error
797
+
798
+ if (!isRetryable || attempt === maxRetries - 1) {
799
+ throw error;
800
+ }
801
+
802
+ // Exponential backoff: 1s, 2s, 4s, etc.
803
+ const delay = Math.pow(2, attempt) * 1000;
804
+ console.log(`Retry attempt ${attempt + 1} after ${delay}ms`);
805
+ await new Promise(resolve => setTimeout(resolve, delay));
806
+ }
807
+ }
808
+
809
+ throw lastError;
810
+ }
811
+ ```
812
+
813
+ ### Polling vs Blocking
814
+
815
+ **Blocking Mode (holds connection open):**
816
+ ```javascript
817
+ const output = await replicate.run(
818
+ "meta/llama-2-70b-chat",
819
+ {
820
+ input: { prompt: "Hello" },
821
+ wait: {
822
+ mode: "block", // Hold connection open
823
+ interval: 60000 // Fallback to polling after 60s
824
+ }
825
+ }
826
+ );
827
+ ```
828
+
829
+ **Polling Mode (repeated requests):**
830
+ ```javascript
831
+ const output = await replicate.run(
832
+ "meta/llama-2-70b-chat",
833
+ {
834
+ input: { prompt: "Hello" },
835
+ wait: {
836
+ mode: "poll", // Make repeated requests
837
+ interval: 500 // Check every 500ms
838
+ }
839
+ }
840
+ );
841
+ ```
842
+
843
+ ### Async/Await Patterns
844
+
845
+ **Parallel Predictions:**
846
+ ```javascript
847
+ const prompts = [
848
+ "a sunset over mountains",
849
+ "a city at night",
850
+ "a forest in autumn"
851
+ ];
852
+
853
+ const predictions = await Promise.all(
854
+ prompts.map(prompt =>
855
+ replicate.predictions.create({
856
+ version: "model-version-id",
857
+ input: { prompt }
858
+ })
859
+ )
860
+ );
861
+
862
+ // Wait for all to complete
863
+ const results = await Promise.all(
864
+ predictions.map(p => replicate.wait(p))
865
+ );
866
+
867
+ results.forEach((result, i) => {
868
+ console.log(`Result ${i}:`, result.output);
869
+ });
870
+ ```
871
+
872
+ **Sequential Processing with Rate Limiting:**
873
+ ```javascript
874
+ async function processSequentially(prompts, delayMs = 1000) {
875
+ const results = [];
876
+
877
+ for (const prompt of prompts) {
878
+ const output = await replicate.run(
879
+ "stability-ai/sdxl",
880
+ { input: { prompt } }
881
+ );
882
+
883
+ results.push(output);
884
+
885
+ // Delay between requests
886
+ if (prompts.indexOf(prompt) < prompts.length - 1) {
887
+ await new Promise(resolve => setTimeout(resolve, delayMs));
888
+ }
889
+ }
890
+
891
+ return results;
892
+ }
893
+ ```
894
+
895
+ ## 7. Best Practices
896
+
897
+ ### Request Structure
898
+
899
+ **Always specify exact versions in production:**
900
+ ```javascript
901
+ // Good - pinned version
902
+ const output = await replicate.run(
903
+ "stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b",
904
+ { input: { prompt: "a cat" } }
905
+ );
906
+
907
+ // Avoid - uses latest version (can change unexpectedly)
908
+ const output = await replicate.run(
909
+ "stability-ai/sdxl",
910
+ { input: { prompt: "a cat" } }
911
+ );
912
+ ```
913
+
914
+ **Validate inputs before sending:**
915
+ ```javascript
916
+ function validateInput(input) {
917
+ if (!input.prompt || input.prompt.trim().length === 0) {
918
+ throw new Error("Prompt is required");
919
+ }
920
+
921
+ if (input.width && (input.width < 256 || input.width > 2048)) {
922
+ throw new Error("Width must be between 256 and 2048");
923
+ }
924
+
925
+ if (input.height && (input.height < 256 || input.height > 2048)) {
926
+ throw new Error("Height must be between 256 and 2048");
927
+ }
928
+
929
+ return true;
930
+ }
931
+
932
+ // Use validation
933
+ const input = { prompt: "a landscape", width: 1024, height: 1024 };
934
+ validateInput(input);
935
+
936
+ const output = await replicate.run("stability-ai/sdxl", { input });
937
+ ```
938
+
939
+ ### Rate Limits and Retries
940
+
941
+ **Implement exponential backoff:**
942
+ ```javascript
943
+ async function callWithBackoff(fn, maxRetries = 3) {
944
+ for (let i = 0; i < maxRetries; i++) {
945
+ try {
946
+ return await fn();
947
+ } catch (error) {
948
+ if (error.response?.status === 429) {
949
+ const retryAfter = error.response.headers['retry-after'];
950
+ const delay = retryAfter
951
+ ? parseInt(retryAfter) * 1000
952
+ : Math.pow(2, i) * 1000;
953
+
954
+ console.log(`Rate limited. Retrying after ${delay}ms`);
955
+ await new Promise(resolve => setTimeout(resolve, delay));
956
+ } else {
957
+ throw error;
958
+ }
959
+ }
960
+ }
961
+
962
+ throw new Error("Max retries exceeded");
963
+ }
964
+
965
+ // Usage
966
+ const output = await callWithBackoff(() =>
967
+ replicate.run("model-name", { input: { prompt: "test" } })
968
+ );
969
+ ```
970
+
971
+ **Respect Retry-After headers:**
972
+ ```javascript
973
+ catch (error) {
974
+ if (error.response?.status === 429) {
975
+ const retryAfter = error.response.headers['retry-after'];
976
+ if (retryAfter) {
977
+ const delaySeconds = parseInt(retryAfter);
978
+ console.log(`Waiting ${delaySeconds}s before retry`);
979
+ await new Promise(resolve => setTimeout(resolve, delaySeconds * 1000));
980
+ }
981
+ }
982
+ }
983
+ ```
984
+
985
+ ### Safety and Compliance
986
+
987
+ **Content moderation:**
988
+ ```javascript
989
+ function checkContentSafety(prompt) {
990
+ // Implement your content policy
991
+ const blockedTerms = ['harmful', 'illegal'];
992
+
993
+ const normalized = prompt.toLowerCase();
994
+ for (const term of blockedTerms) {
995
+ if (normalized.includes(term)) {
996
+ throw new Error("Content policy violation");
997
+ }
998
+ }
999
+
1000
+ return true;
1001
+ }
1002
+
1003
+ // Use before API calls
1004
+ try {
1005
+ checkContentSafety(userPrompt);
1006
+ const output = await replicate.run("model", { input: { prompt: userPrompt } });
1007
+ } catch (error) {
1008
+ console.error("Safety check failed:", error.message);
1009
+ }
1010
+ ```
1011
+
1012
+ **Monitor and log predictions:**
1013
+ ```javascript
1014
+ async function runWithLogging(identifier, options) {
1015
+ const startTime = Date.now();
1016
+
1017
+ try {
1018
+ const prediction = await replicate.predictions.create({
1019
+ version: identifier,
1020
+ input: options.input
1021
+ });
1022
+
1023
+ console.log({
1024
+ event: "prediction_created",
1025
+ id: prediction.id,
1026
+ model: identifier,
1027
+ timestamp: new Date().toISOString()
1028
+ });
1029
+
1030
+ const result = await replicate.wait(prediction);
1031
+ const duration = Date.now() - startTime;
1032
+
1033
+ console.log({
1034
+ event: "prediction_completed",
1035
+ id: result.id,
1036
+ status: result.status,
1037
+ duration_ms: duration,
1038
+ cost_estimate: result.metrics?.predict_time,
1039
+ timestamp: new Date().toISOString()
1040
+ });
1041
+
1042
+ return result.output;
1043
+ } catch (error) {
1044
+ console.error({
1045
+ event: "prediction_failed",
1046
+ error: error.message,
1047
+ duration_ms: Date.now() - startTime,
1048
+ timestamp: new Date().toISOString()
1049
+ });
1050
+ throw error;
1051
+ }
1052
+ }
1053
+ ```
1054
+
1055
+ ### Cost Management
1056
+
1057
+ **Estimate costs before running:**
1058
+ ```javascript
1059
+ // Pricing varies by hardware
1060
+ const PRICING = {
1061
+ "cpu": 0.0001, // $0.0001/sec
1062
+ "gpu-t4": 0.000225, // $0.000225/sec for public models
1063
+ "gpu-a40-small": 0.000575,
1064
+ "gpu-a40-large": 0.00118,
1065
+ "gpu-a100": 0.00385
1066
+ };
1067
+
1068
+ function estimateCost(hardwareSku, estimatedSeconds) {
1069
+ const pricePerSecond = PRICING[hardwareSku] || 0;
1070
+ return pricePerSecond * estimatedSeconds;
1071
+ }
1072
+
1073
+ // Use deployments for predictable costs
1074
+ const deployment = await replicate.deployments.create({
1075
+ name: "cost-controlled-deployment",
1076
+ model: "stability-ai/sdxl",
1077
+ version: "version-id",
1078
+ hardware: "gpu-t4", // Choose appropriate hardware
1079
+ min_instances: 0, // Scale to zero when not in use
1080
+ max_instances: 2 // Cap maximum concurrent instances
1081
+ });
1082
+ ```
1083
+
1084
+ **Cancel long-running predictions:**
1085
+ ```javascript
1086
+ const prediction = await replicate.predictions.create({
1087
+ version: "model-version",
1088
+ input: { prompt: "test" }
1089
+ });
1090
+
1091
+ // Set timeout to prevent excessive costs
1092
+ const timeout = setTimeout(async () => {
1093
+ console.log("Prediction taking too long, canceling...");
1094
+ await replicate.predictions.cancel(prediction.id);
1095
+ }, 60000); // Cancel after 60 seconds
1096
+
1097
+ try {
1098
+ const result = await replicate.wait(prediction);
1099
+ clearTimeout(timeout);
1100
+ return result.output;
1101
+ } catch (error) {
1102
+ clearTimeout(timeout);
1103
+ throw error;
1104
+ }
1105
+ ```
1106
+
1107
+ ## 8. Production Patterns
1108
+
1109
+ ### Checking SDK and Model Versions
1110
+
1111
+ To check the latest SDK version:
1112
+ ```bash
1113
+ npm view replicate version
1114
+ ```
1115
+
1116
+ To list model versions programmatically:
1117
+ ```javascript
1118
+ const versions = await replicate.models.versions.list("owner", "model-name");
1119
+ ```
1120
+
1121
+ To check model schema and version details from CLI:
1122
+ ```bash
1123
+ replicate model schema owner/model-name
1124
+ ```
1125
+
1126
+ ### Error Tracking Integration
1127
+
1128
+ ```javascript
1129
+ import * as Sentry from "@sentry/node";
1130
+
1131
+ try {
1132
+ const output = await replicate.run(identifier, options);
1133
+ } catch (error) {
1134
+ Sentry.captureException(error, {
1135
+ tags: {
1136
+ service: "replicate",
1137
+ model: identifier
1138
+ },
1139
+ contexts: {
1140
+ prediction: {
1141
+ input: options.input
1142
+ }
1143
+ }
1144
+ });
1145
+ throw error;
1146
+ }
1147
+ ```
1148
+
1149
+ ### Account Information
1150
+
1151
+ ```javascript
1152
+ const account = await replicate.account.get();
1153
+ console.log(account.type); // "user" or "organization"
1154
+ console.log(account.username);
1155
+ console.log(account.name);
1156
+ ```
1157
+
1158
+ ### Testing with Mocks
1159
+
1160
+ ```javascript
1161
+ import { jest } from '@jest/globals';
1162
+
1163
+ jest.mock('replicate');
1164
+
1165
+ test('handles prediction success', async () => {
1166
+ const mockRun = jest.fn().mockResolvedValue(['output.png']);
1167
+ const replicate = { run: mockRun };
1168
+
1169
+ const result = await myFunction(replicate);
1170
+
1171
+ expect(mockRun).toHaveBeenCalledWith(
1172
+ expect.any(String),
1173
+ expect.objectContaining({
1174
+ input: expect.any(Object)
1175
+ })
1176
+ );
1177
+ expect(result).toBeDefined();
1178
+ });
1179
+ ```
1180
+
1181
+ ### Input Validation
1182
+
1183
+ To inspect a model's expected input/output schema:
1184
+ ```javascript
1185
+ const version = await replicate.models.versions.get("owner", "model", "version-id");
1186
+ console.log(version.openapi_schema);
1187
+ ```
1188
+
1189
+ From CLI:
1190
+ ```bash
1191
+ replicate model schema owner/model-name
1192
+ ```
1193
+
1194
+ Validation example:
1195
+ ```javascript
1196
+ import validator from 'validator';
1197
+
1198
+ function validatePredictionInput(input) {
1199
+ if (!input.prompt || typeof input.prompt !== 'string') {
1200
+ throw new Error('Invalid prompt');
1201
+ }
1202
+
1203
+ if (input.prompt.length > 10000) {
1204
+ throw new Error('Prompt too long');
1205
+ }
1206
+
1207
+ if (input.image_url && !validator.isURL(input.image_url)) {
1208
+ throw new Error('Invalid image URL');
1209
+ }
1210
+
1211
+ return true;
1212
+ }
1213
+ ```
1214
+
1215
+ ### Monitoring with Metrics
1216
+
1217
+ List and monitor predictions:
1218
+ ```javascript
1219
+ for await (const prediction of replicate.predictions.list()) {
1220
+ console.log(prediction.id, prediction.status);
1221
+ }
1222
+ ```
1223
+
1224
+ Monitor trainings:
1225
+ ```javascript
1226
+ for await (const training of replicate.trainings.list()) {
1227
+ console.log(training.id, training.status);
1228
+ }
1229
+ ```
1230
+
1231
+ Prometheus integration:
1232
+ ```javascript
1233
+ import prometheus from 'prom-client';
1234
+
1235
+ const predictionCounter = new prometheus.Counter({
1236
+ name: 'replicate_predictions_total',
1237
+ help: 'Total number of predictions',
1238
+ labelNames: ['model', 'status']
1239
+ });
1240
+
1241
+ const predictionDuration = new prometheus.Histogram({
1242
+ name: 'replicate_prediction_duration_seconds',
1243
+ help: 'Prediction duration in seconds',
1244
+ labelNames: ['model']
1245
+ });
1246
+
1247
+ async function runWithMetrics(identifier, options) {
1248
+ const startTime = Date.now();
1249
+
1250
+ try {
1251
+ const output = await replicate.run(identifier, options);
1252
+ predictionCounter.inc({ model: identifier, status: 'success' });
1253
+ return output;
1254
+ } catch (error) {
1255
+ predictionCounter.inc({ model: identifier, status: 'error' });
1256
+ throw error;
1257
+ } finally {
1258
+ const duration = (Date.now() - startTime) / 1000;
1259
+ predictionDuration.observe({ model: identifier }, duration);
1260
+ }
1261
+ }
1262
+ ```
1263
+
1264
+ ### Deployment Management
1265
+
1266
+ Create deployment:
1267
+ ```javascript
1268
+ const deployment = await replicate.deployments.create({
1269
+ name: "production-deployment",
1270
+ model: "stability-ai/sdxl",
1271
+ version: "pinned-version-id",
1272
+ hardware: "gpu-a40-large",
1273
+ min_instances: 2,
1274
+ max_instances: 10
1275
+ });
1276
+ ```
1277
+
1278
+ Update deployment:
1279
+ ```javascript
1280
+ const updated = await replicate.deployments.update(
1281
+ "your-username",
1282
+ "deployment-name",
1283
+ {
1284
+ version: "new-version-id",
1285
+ min_instances: 0,
1286
+ max_instances: 5
1287
+ }
1288
+ );
1289
+ ```
1290
+
1291
+ Delete deployment:
1292
+ ```javascript
1293
+ await replicate.deployments.delete("your-username", "deployment-name");
1294
+ ```
1295
+
1296
+ List deployments:
1297
+ ```javascript
1298
+ for await (const deployment of replicate.deployments.list()) {
1299
+ console.log(deployment.owner, deployment.name);
1300
+ }
1301
+ ```
1302
+
1303
+ From CLI:
1304
+ ```bash
1305
+ replicate model create yourname/model --private --hardware gpu-a40-small
1306
+ ```
1307
+
1308
+ ### Canceling Predictions
1309
+
1310
+ Cancel programmatically:
1311
+ ```javascript
1312
+ await replicate.predictions.cancel(prediction_id);
1313
+ ```
1314
+
1315
+ From CLI:
1316
+ ```bash
1317
+ replicate prediction cancel <id>
1318
+ ```