@ai2aim.ai/hivemind-sdk 1.0.1
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/README.md +655 -0
- package/dist/cli-config.d.ts +12 -0
- package/dist/cli-config.d.ts.map +1 -0
- package/dist/cli-config.js +93 -0
- package/dist/cli-config.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +309 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +576 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +871 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +553 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +34 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
|
+
};
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.HivemindClient = exports.HivemindError = void 0;
|
|
43
|
+
const node_https_1 = __importDefault(require("node:https"));
|
|
44
|
+
// Re-export all types for consumers
|
|
45
|
+
__exportStar(require("./types"), exports);
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when an API request fails.
|
|
48
|
+
* Contains the HTTP status code and the raw response body for inspection.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* try {
|
|
53
|
+
* await client.query("my-org", { query: "hello" });
|
|
54
|
+
* } catch (err) {
|
|
55
|
+
* if (err instanceof HivemindError) {
|
|
56
|
+
* console.error(`HTTP ${err.statusCode}:`, err.detail);
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
class HivemindError extends Error {
|
|
62
|
+
statusCode;
|
|
63
|
+
detail;
|
|
64
|
+
constructor(statusCode, detail, message) {
|
|
65
|
+
super(message ?? `API request failed with status ${statusCode}`);
|
|
66
|
+
this.statusCode = statusCode;
|
|
67
|
+
this.detail = detail;
|
|
68
|
+
this.name = "HivemindError";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.HivemindError = HivemindError;
|
|
72
|
+
function resolveClientConfig(input) {
|
|
73
|
+
const baseUrl = (input.baseUrl ??
|
|
74
|
+
process.env.HIVEMIND_BASE_URL ??
|
|
75
|
+
process.env.HIVEMIND_API_URL ??
|
|
76
|
+
"").replace(/\/+$/, "");
|
|
77
|
+
const iapClientId = input.iapClientId ?? process.env.IAP_CLIENT_ID ?? "";
|
|
78
|
+
if (!baseUrl || !iapClientId) {
|
|
79
|
+
throw new HivemindError(0, null, "baseUrl and iapClientId are required. Set them in config or in env: HIVEMIND_BASE_URL (or HIVEMIND_API_URL) and IAP_CLIENT_ID.");
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
...input,
|
|
83
|
+
baseUrl,
|
|
84
|
+
iapClientId,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
class HivemindClient {
|
|
88
|
+
baseUrl;
|
|
89
|
+
prefix;
|
|
90
|
+
config;
|
|
91
|
+
iapToken = null;
|
|
92
|
+
iapTokenExpiry = 0;
|
|
93
|
+
fetchAgent;
|
|
94
|
+
constructor(config) {
|
|
95
|
+
this.config = resolveClientConfig(config);
|
|
96
|
+
this.baseUrl = this.config.baseUrl;
|
|
97
|
+
this.prefix = this.config.apiPrefix ?? "/v1";
|
|
98
|
+
if (this.config.insecure) {
|
|
99
|
+
this.fetchAgent = new node_https_1.default.Agent({ rejectUnauthorized: false });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// -----------------------------------------------------------------------
|
|
103
|
+
// IAP token helper
|
|
104
|
+
// -----------------------------------------------------------------------
|
|
105
|
+
async getIapToken() {
|
|
106
|
+
if (!this.config.iapClientId)
|
|
107
|
+
return null;
|
|
108
|
+
if (this.iapToken && Date.now() < this.iapTokenExpiry - 60_000) {
|
|
109
|
+
return this.iapToken;
|
|
110
|
+
}
|
|
111
|
+
const { GoogleAuth } = await Promise.resolve().then(() => __importStar(require("google-auth-library")));
|
|
112
|
+
const auth = new GoogleAuth({
|
|
113
|
+
...(this.config.iapServiceAccountKeyPath
|
|
114
|
+
? { keyFile: this.config.iapServiceAccountKeyPath }
|
|
115
|
+
: {}),
|
|
116
|
+
});
|
|
117
|
+
const client = await auth.getIdTokenClient(this.config.iapClientId);
|
|
118
|
+
const headers = await client.getRequestHeaders();
|
|
119
|
+
const bearer = headers["Authorization"] ?? headers["authorization"] ?? "";
|
|
120
|
+
this.iapToken = bearer.replace(/^Bearer\s+/i, "");
|
|
121
|
+
this.iapTokenExpiry = Date.now() + 55 * 60_000;
|
|
122
|
+
return this.iapToken;
|
|
123
|
+
}
|
|
124
|
+
// -----------------------------------------------------------------------
|
|
125
|
+
// Generic HTTP helpers
|
|
126
|
+
// -----------------------------------------------------------------------
|
|
127
|
+
async request(method, path, opts = {}) {
|
|
128
|
+
const url = new URL(`${this.prefix}${path}`, this.baseUrl);
|
|
129
|
+
if (opts.query) {
|
|
130
|
+
for (const [k, v] of Object.entries(opts.query)) {
|
|
131
|
+
if (v !== undefined && v !== null)
|
|
132
|
+
url.searchParams.set(k, v);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const headers = { ...opts.headers };
|
|
136
|
+
const apiKey = opts.apiKey ?? this.config.apiKey;
|
|
137
|
+
// IAP token (outermost Bearer); org API key as X-API-Key or Bearer when no IAP
|
|
138
|
+
const iapToken = await this.getIapToken();
|
|
139
|
+
if (iapToken) {
|
|
140
|
+
headers["Authorization"] = `Bearer ${iapToken}`;
|
|
141
|
+
if (apiKey)
|
|
142
|
+
headers["X-API-Key"] = apiKey;
|
|
143
|
+
}
|
|
144
|
+
else if (apiKey) {
|
|
145
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
146
|
+
}
|
|
147
|
+
if (this.config.adminKey) {
|
|
148
|
+
headers["X-Admin-Key"] = this.config.adminKey;
|
|
149
|
+
}
|
|
150
|
+
if (this.config.webhookSecret) {
|
|
151
|
+
headers["X-Webhook-Secret"] = this.config.webhookSecret;
|
|
152
|
+
}
|
|
153
|
+
if (this.config.employeeId) {
|
|
154
|
+
headers["X-Employee-Id"] = this.config.employeeId;
|
|
155
|
+
}
|
|
156
|
+
let bodyPayload;
|
|
157
|
+
if (opts.formData) {
|
|
158
|
+
bodyPayload = opts.formData;
|
|
159
|
+
}
|
|
160
|
+
else if (opts.body !== undefined) {
|
|
161
|
+
headers["Content-Type"] = "application/json";
|
|
162
|
+
bodyPayload = JSON.stringify(opts.body);
|
|
163
|
+
}
|
|
164
|
+
const controller = new AbortController();
|
|
165
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeoutMs ?? 30_000);
|
|
166
|
+
try {
|
|
167
|
+
const fetchOpts = {
|
|
168
|
+
method,
|
|
169
|
+
headers,
|
|
170
|
+
body: bodyPayload,
|
|
171
|
+
signal: controller.signal,
|
|
172
|
+
};
|
|
173
|
+
if (this.fetchAgent) {
|
|
174
|
+
fetchOpts.agent = this.fetchAgent;
|
|
175
|
+
}
|
|
176
|
+
const res = await fetch(url.toString(), fetchOpts);
|
|
177
|
+
if (res.status === 204)
|
|
178
|
+
return undefined;
|
|
179
|
+
const text = await res.text();
|
|
180
|
+
let json;
|
|
181
|
+
try {
|
|
182
|
+
json = JSON.parse(text);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
json = text;
|
|
186
|
+
}
|
|
187
|
+
if (!res.ok) {
|
|
188
|
+
throw new HivemindError(res.status, json);
|
|
189
|
+
}
|
|
190
|
+
return json;
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
clearTimeout(timeoutId);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
get(path, query, options) {
|
|
197
|
+
return this.request("GET", path, { query, apiKey: options?.apiKey });
|
|
198
|
+
}
|
|
199
|
+
post(path, body, options) {
|
|
200
|
+
return this.request("POST", path, { body, apiKey: options?.apiKey });
|
|
201
|
+
}
|
|
202
|
+
del(path, options) {
|
|
203
|
+
return this.request("DELETE", path, { apiKey: options?.apiKey });
|
|
204
|
+
}
|
|
205
|
+
// -----------------------------------------------------------------------
|
|
206
|
+
// Health
|
|
207
|
+
// -----------------------------------------------------------------------
|
|
208
|
+
/**
|
|
209
|
+
* Check service health status. No authentication required.
|
|
210
|
+
*
|
|
211
|
+
* @returns Service name, version, status, and aggregate statistics.
|
|
212
|
+
*
|
|
213
|
+
* **Endpoint:** `GET /v1/health`
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* const health = await client.health();
|
|
218
|
+
* console.log(health.status); // "ok"
|
|
219
|
+
* console.log(health.stats); // { organizations: 12, documents: 450, total_chunks: 3200 }
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
health() {
|
|
223
|
+
return this.get("/health");
|
|
224
|
+
}
|
|
225
|
+
// -----------------------------------------------------------------------
|
|
226
|
+
// Admin auth
|
|
227
|
+
// -----------------------------------------------------------------------
|
|
228
|
+
/**
|
|
229
|
+
* Exchange the bootstrap admin key for a signed session token.
|
|
230
|
+
* The token can be used as `Authorization: Bearer <token>` for admin endpoints
|
|
231
|
+
* instead of sending the raw admin key on every request.
|
|
232
|
+
*
|
|
233
|
+
* @param params - Object containing the `admin_key`.
|
|
234
|
+
* @returns Signed session token with type and expiry.
|
|
235
|
+
* @throws {@link HivemindError} 400 if admin key is not configured on the server.
|
|
236
|
+
* @throws {@link HivemindError} 401 if the admin key is invalid.
|
|
237
|
+
*
|
|
238
|
+
* **Endpoint:** `POST /v1/admin/login`
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const { access_token, expires_in_seconds } = await client.adminLogin({
|
|
243
|
+
* admin_key: "your-bootstrap-admin-key",
|
|
244
|
+
* });
|
|
245
|
+
* // Use access_token as Bearer token for subsequent admin requests
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
adminLogin(params) {
|
|
249
|
+
return this.post("/admin/login", params);
|
|
250
|
+
}
|
|
251
|
+
// -----------------------------------------------------------------------
|
|
252
|
+
// Organizations (admin)
|
|
253
|
+
// -----------------------------------------------------------------------
|
|
254
|
+
/**
|
|
255
|
+
* Create a new organization. Returns the organization details and a generated API key.
|
|
256
|
+
*
|
|
257
|
+
* **Auth:** Requires `adminKey` in client config (sends `X-Admin-Key` header).
|
|
258
|
+
*
|
|
259
|
+
* @param params - Organization creation parameters (org_id, name, tier, settings).
|
|
260
|
+
* @returns The created organization and its API key.
|
|
261
|
+
* @throws {@link HivemindError} 400 if validation fails or org already exists.
|
|
262
|
+
* @throws {@link HivemindError} 401 if admin credentials are invalid.
|
|
263
|
+
*
|
|
264
|
+
* **Endpoint:** `POST /v1/organizations`
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* const { organization, api_key } = await admin.createOrganization({
|
|
269
|
+
* org_id: "acme-corp",
|
|
270
|
+
* name: "Acme Corporation",
|
|
271
|
+
* tier: "premium",
|
|
272
|
+
* });
|
|
273
|
+
* console.log("API Key:", api_key); // Store securely — shown only once
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
createOrganization(params) {
|
|
277
|
+
return this.post("/organizations", params);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Retrieve organization details including tier, status, and settings.
|
|
281
|
+
*
|
|
282
|
+
* **Auth:** Requires org-scoped API key (via config or `options.apiKey`).
|
|
283
|
+
*
|
|
284
|
+
* @param orgId - Organization identifier.
|
|
285
|
+
* @param options - Optional per-request overrides (e.g. `{ apiKey }`).
|
|
286
|
+
* @returns Full organization entity.
|
|
287
|
+
* @throws {@link HivemindError} 401 if API key is missing or invalid.
|
|
288
|
+
* @throws {@link HivemindError} 403 if the API key belongs to a different org.
|
|
289
|
+
* @throws {@link HivemindError} 404 if the organization does not exist.
|
|
290
|
+
*
|
|
291
|
+
* **Endpoint:** `GET /v1/organizations/{orgId}`
|
|
292
|
+
*/
|
|
293
|
+
getOrganization(orgId, options) {
|
|
294
|
+
return this.get(`/organizations/${orgId}`, undefined, options);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Rotate the API key for an organization. The previous key remains valid
|
|
298
|
+
* for a 24-hour grace period.
|
|
299
|
+
*
|
|
300
|
+
* **Auth:** Requires `adminKey` in client config.
|
|
301
|
+
*
|
|
302
|
+
* @param orgId - Organization identifier.
|
|
303
|
+
* @param options - Optional per-request overrides.
|
|
304
|
+
* @returns New API key and grace period expiry for the previous key.
|
|
305
|
+
* @throws {@link HivemindError} 401 if admin credentials are invalid.
|
|
306
|
+
* @throws {@link HivemindError} 404 if the organization does not exist.
|
|
307
|
+
*
|
|
308
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/api-keys/rotate`
|
|
309
|
+
*/
|
|
310
|
+
rotateApiKey(orgId, options) {
|
|
311
|
+
return this.post(`/organizations/${orgId}/api-keys/rotate`, undefined, options);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Suspend an organization, blocking all API key access until reactivated.
|
|
315
|
+
*
|
|
316
|
+
* **Auth:** Requires `adminKey` in client config.
|
|
317
|
+
*
|
|
318
|
+
* @param orgId - Organization identifier.
|
|
319
|
+
* @param options - Optional per-request overrides.
|
|
320
|
+
* @returns Updated organization status.
|
|
321
|
+
* @throws {@link HivemindError} 401 if admin credentials are invalid.
|
|
322
|
+
* @throws {@link HivemindError} 404 if the organization does not exist.
|
|
323
|
+
*
|
|
324
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/suspend`
|
|
325
|
+
*/
|
|
326
|
+
suspendOrganization(orgId, options) {
|
|
327
|
+
return this.post(`/organizations/${orgId}/suspend`, undefined, options);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Reactivate a suspended organization, restoring API key access.
|
|
331
|
+
*
|
|
332
|
+
* **Auth:** Requires `adminKey` in client config.
|
|
333
|
+
*
|
|
334
|
+
* @param orgId - Organization identifier.
|
|
335
|
+
* @param options - Optional per-request overrides.
|
|
336
|
+
* @returns Updated organization status.
|
|
337
|
+
* @throws {@link HivemindError} 401 if admin credentials are invalid.
|
|
338
|
+
* @throws {@link HivemindError} 404 if the organization does not exist.
|
|
339
|
+
*
|
|
340
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/reactivate`
|
|
341
|
+
*/
|
|
342
|
+
reactivateOrganization(orgId, options) {
|
|
343
|
+
return this.post(`/organizations/${orgId}/reactivate`, undefined, options);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Permanently delete an organization and all associated data.
|
|
347
|
+
* This action is irreversible.
|
|
348
|
+
*
|
|
349
|
+
* **Auth:** Requires `adminKey` in client config.
|
|
350
|
+
*
|
|
351
|
+
* @param orgId - Organization identifier.
|
|
352
|
+
* @param options - Optional per-request overrides.
|
|
353
|
+
* @throws {@link HivemindError} 401 if admin credentials are invalid.
|
|
354
|
+
* @throws {@link HivemindError} 404 if the organization does not exist.
|
|
355
|
+
*
|
|
356
|
+
* **Endpoint:** `DELETE /v1/organizations/{orgId}`
|
|
357
|
+
*/
|
|
358
|
+
deleteOrganization(orgId, options) {
|
|
359
|
+
return this.del(`/organizations/${orgId}`, options);
|
|
360
|
+
}
|
|
361
|
+
// -----------------------------------------------------------------------
|
|
362
|
+
// Documents
|
|
363
|
+
// -----------------------------------------------------------------------
|
|
364
|
+
/**
|
|
365
|
+
* Upload and ingest a document file (PDF, TXT, DOCX, etc.).
|
|
366
|
+
* The document is stored in GCS, split into chunks, and embedded for RAG retrieval.
|
|
367
|
+
*
|
|
368
|
+
* **Auth:** Requires org-scoped API key.
|
|
369
|
+
*
|
|
370
|
+
* @param orgId - Organization identifier.
|
|
371
|
+
* @param file - Document content as a `Blob` or `Buffer`.
|
|
372
|
+
* @param filename - Original filename (e.g. `"report.pdf"`).
|
|
373
|
+
* @param options - Optional per-request overrides (e.g. `{ apiKey }`).
|
|
374
|
+
* @returns Upload result with document ID, chunk count, and status.
|
|
375
|
+
* @throws {@link HivemindError} 400 if the file exceeds the maximum upload size (default 25 MB).
|
|
376
|
+
* @throws {@link HivemindError} 401 if API key is missing or invalid.
|
|
377
|
+
* @throws {@link HivemindError} 429 if rate limit is exceeded.
|
|
378
|
+
*
|
|
379
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/documents/upload`
|
|
380
|
+
* **Content-Type:** `multipart/form-data`
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* import { readFileSync } from "fs";
|
|
385
|
+
* const file = readFileSync("./report.pdf");
|
|
386
|
+
* const result = await client.uploadDocument("acme-corp", file, "report.pdf");
|
|
387
|
+
* console.log(`Uploaded: ${result.document_id}, ${result.chunks} chunks`);
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
async uploadDocument(orgId, file, filename, options) {
|
|
391
|
+
const form = new FormData();
|
|
392
|
+
const blob = file instanceof Blob ? file : new Blob([file], { type: "application/octet-stream" });
|
|
393
|
+
form.append("file", blob, filename);
|
|
394
|
+
return this.request("POST", `/organizations/${orgId}/documents/upload`, { formData: form, apiKey: options?.apiKey });
|
|
395
|
+
}
|
|
396
|
+
// -----------------------------------------------------------------------
|
|
397
|
+
// Query (RAG)
|
|
398
|
+
// -----------------------------------------------------------------------
|
|
399
|
+
/**
|
|
400
|
+
* Query the organization's document knowledge base using RAG
|
|
401
|
+
* (Retrieval-Augmented Generation). Retrieves relevant document chunks,
|
|
402
|
+
* then generates a response with citations.
|
|
403
|
+
*
|
|
404
|
+
* **Auth:** Requires org-scoped API key.
|
|
405
|
+
*
|
|
406
|
+
* @param orgId - Organization identifier.
|
|
407
|
+
* @param params - Query parameters (query text, model, temperature, strategy).
|
|
408
|
+
* @param options - Optional per-request overrides (e.g. `{ apiKey }`).
|
|
409
|
+
* @returns Generated answer with source citations, confidence, and processing time.
|
|
410
|
+
* @throws {@link HivemindError} 401 if API key is missing or invalid.
|
|
411
|
+
* @throws {@link HivemindError} 403 if cross-organization access is attempted.
|
|
412
|
+
* @throws {@link HivemindError} 429 if rate limit or token quota is exceeded.
|
|
413
|
+
*
|
|
414
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/query`
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* const result = await client.query("acme-corp", {
|
|
419
|
+
* query: "What are the key findings in Q4?",
|
|
420
|
+
* temperature: 0.2,
|
|
421
|
+
* retrieval_strategy: "hybrid",
|
|
422
|
+
* });
|
|
423
|
+
* console.log(result.answer);
|
|
424
|
+
* console.log(result.sources); // citations with doc_id, chunk_id, score, snippet
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
query(orgId, params, options) {
|
|
428
|
+
return this.post(`/organizations/${orgId}/query`, params, options);
|
|
429
|
+
}
|
|
430
|
+
// -----------------------------------------------------------------------
|
|
431
|
+
// Generation
|
|
432
|
+
// -----------------------------------------------------------------------
|
|
433
|
+
/**
|
|
434
|
+
* Start an asynchronous video generation job using Vertex AI Veo.
|
|
435
|
+
* Returns a job ID — poll with `getJob()` or `waitForJob()` for results.
|
|
436
|
+
*
|
|
437
|
+
* **Auth:** Requires org-scoped API key.
|
|
438
|
+
*
|
|
439
|
+
* @param orgId - Organization identifier.
|
|
440
|
+
* @param params - Video generation parameters (prompt, duration, aspect_ratio, style).
|
|
441
|
+
* @param options - Optional per-request overrides.
|
|
442
|
+
* @returns Job ID and estimated processing time (HTTP 202).
|
|
443
|
+
* @throws {@link HivemindError} 429 if rate limit, video quota, or concurrent job limit is exceeded.
|
|
444
|
+
*
|
|
445
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/generate/video`
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```typescript
|
|
449
|
+
* const job = await client.generateVideo("acme-corp", {
|
|
450
|
+
* prompt: "A drone flyover of a mountain lake at sunset",
|
|
451
|
+
* duration: 8,
|
|
452
|
+
* aspect_ratio: "16:9",
|
|
453
|
+
* style: "cinematic",
|
|
454
|
+
* });
|
|
455
|
+
* const result = await client.waitForJob("acme-corp", job.job_id);
|
|
456
|
+
* console.log(result.result); // { output_url, signed_url }
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
generateVideo(orgId, params, options) {
|
|
460
|
+
return this.post(`/organizations/${orgId}/generate/video`, params, options);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Start an asynchronous image generation job using Vertex AI Imagen.
|
|
464
|
+
* Returns a job ID — poll with `getJob()` or `waitForJob()` for results.
|
|
465
|
+
*
|
|
466
|
+
* **Auth:** Requires org-scoped API key.
|
|
467
|
+
*
|
|
468
|
+
* @param orgId - Organization identifier.
|
|
469
|
+
* @param params - Image generation parameters (prompt, aspect_ratio, style, num_images).
|
|
470
|
+
* @param options - Optional per-request overrides.
|
|
471
|
+
* @returns Job ID and estimated processing time (HTTP 202).
|
|
472
|
+
* @throws {@link HivemindError} 429 if rate limit, image quota, or concurrent job limit is exceeded.
|
|
473
|
+
*
|
|
474
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/generate/image`
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const job = await client.generateImage("acme-corp", {
|
|
479
|
+
* prompt: "A futuristic city skyline at dusk",
|
|
480
|
+
* aspect_ratio: "16:9",
|
|
481
|
+
* style: "digital art",
|
|
482
|
+
* num_images: 4,
|
|
483
|
+
* });
|
|
484
|
+
* const result = await client.waitForJob("acme-corp", job.job_id);
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
generateImage(orgId, params, options) {
|
|
488
|
+
return this.post(`/organizations/${orgId}/generate/image`, params, options);
|
|
489
|
+
}
|
|
490
|
+
// -----------------------------------------------------------------------
|
|
491
|
+
// Jobs
|
|
492
|
+
// -----------------------------------------------------------------------
|
|
493
|
+
/**
|
|
494
|
+
* Check the status of an asynchronous job (video or image generation).
|
|
495
|
+
*
|
|
496
|
+
* **Auth:** Requires org-scoped API key.
|
|
497
|
+
*
|
|
498
|
+
* @param orgId - Organization identifier.
|
|
499
|
+
* @param jobId - Job identifier (from `generateVideo()` or `generateImage()`).
|
|
500
|
+
* @param options - Optional per-request overrides.
|
|
501
|
+
* @returns Job status, result URLs (when completed), or error details (when failed).
|
|
502
|
+
* @throws {@link HivemindError} 404 if the job does not exist.
|
|
503
|
+
*
|
|
504
|
+
* **Endpoint:** `GET /v1/organizations/{orgId}/jobs/{jobId}`
|
|
505
|
+
*/
|
|
506
|
+
getJob(orgId, jobId, options) {
|
|
507
|
+
return this.get(`/organizations/${orgId}/jobs/${jobId}`, undefined, options);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Poll a job until it reaches a terminal status (`completed`, `failed`, or `cancelled`).
|
|
511
|
+
*
|
|
512
|
+
* @param orgId - Organization identifier.
|
|
513
|
+
* @param jobId - Job identifier.
|
|
514
|
+
* @param intervalMs - Polling interval in milliseconds. @default 2000
|
|
515
|
+
* @param maxWaitMs - Maximum wait time in milliseconds. @default 300000 (5 min)
|
|
516
|
+
* @param options - Optional per-request overrides.
|
|
517
|
+
* @returns Final job status with result or error.
|
|
518
|
+
* @throws Error if the job does not complete within `maxWaitMs`.
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```typescript
|
|
522
|
+
* const job = await client.generateVideo("acme-corp", { prompt: "..." });
|
|
523
|
+
* const result = await client.waitForJob("acme-corp", job.job_id, 3000, 600_000);
|
|
524
|
+
* if (result.status === "completed") console.log(result.result);
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
async waitForJob(orgId, jobId, intervalMs = 2000, maxWaitMs = 300_000, options) {
|
|
528
|
+
const start = Date.now();
|
|
529
|
+
while (Date.now() - start < maxWaitMs) {
|
|
530
|
+
const job = await this.getJob(orgId, jobId, options);
|
|
531
|
+
if (["completed", "failed", "cancelled"].includes(job.status)) {
|
|
532
|
+
return job;
|
|
533
|
+
}
|
|
534
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
535
|
+
}
|
|
536
|
+
throw new Error(`Job ${jobId} did not complete within ${maxWaitMs}ms`);
|
|
537
|
+
}
|
|
538
|
+
// -----------------------------------------------------------------------
|
|
539
|
+
// Data chat
|
|
540
|
+
// -----------------------------------------------------------------------
|
|
541
|
+
/**
|
|
542
|
+
* Ask a natural-language question over BigQuery datasets.
|
|
543
|
+
* Gemini generates SQL from the question, executes it, and returns formatted results.
|
|
544
|
+
*
|
|
545
|
+
* **Auth:** Requires org-scoped API key.
|
|
546
|
+
*
|
|
547
|
+
* @param orgId - Organization identifier.
|
|
548
|
+
* @param params - Question and optional user ID.
|
|
549
|
+
* @param options - Optional per-request overrides.
|
|
550
|
+
* @returns Generated SQL, natural-language answer, and result rows.
|
|
551
|
+
* @throws {@link HivemindError} 429 if rate limit or token quota is exceeded.
|
|
552
|
+
*
|
|
553
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/data-chat`
|
|
554
|
+
*
|
|
555
|
+
* @example
|
|
556
|
+
* ```typescript
|
|
557
|
+
* const result = await client.dataChat("acme-corp", {
|
|
558
|
+
* question: "How many active users this month?",
|
|
559
|
+
* });
|
|
560
|
+
* console.log(result.answer); // "There are 1,247 active users this month."
|
|
561
|
+
* console.log(result.sql); // Generated SQL
|
|
562
|
+
* console.log(result.rows); // [{ active_users: 1247 }]
|
|
563
|
+
* ```
|
|
564
|
+
*/
|
|
565
|
+
dataChat(orgId, params, options) {
|
|
566
|
+
return this.post(`/organizations/${orgId}/data-chat`, params, options);
|
|
567
|
+
}
|
|
568
|
+
// -----------------------------------------------------------------------
|
|
569
|
+
// Agents
|
|
570
|
+
// -----------------------------------------------------------------------
|
|
571
|
+
/**
|
|
572
|
+
* Create a custom AI agent template with system instructions and optional tool bindings.
|
|
573
|
+
*
|
|
574
|
+
* **Auth:** Requires org-scoped API key.
|
|
575
|
+
*
|
|
576
|
+
* @param orgId - Organization identifier.
|
|
577
|
+
* @param params - Agent name, instructions, and optional tools.
|
|
578
|
+
* @param options - Optional per-request overrides.
|
|
579
|
+
* @returns Created agent with ID, name, and enabled tools.
|
|
580
|
+
*
|
|
581
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/agents/custom`
|
|
582
|
+
*
|
|
583
|
+
* @example
|
|
584
|
+
* ```typescript
|
|
585
|
+
* const agent = await client.createAgent("acme-corp", {
|
|
586
|
+
* name: "Support Bot",
|
|
587
|
+
* instructions: "You are a helpful customer support agent.",
|
|
588
|
+
* tools: ["rag_search", "ticket_create"],
|
|
589
|
+
* });
|
|
590
|
+
* console.log(agent.agent_id);
|
|
591
|
+
* ```
|
|
592
|
+
*/
|
|
593
|
+
createAgent(orgId, params, options) {
|
|
594
|
+
return this.post(`/organizations/${orgId}/agents/custom`, params, options);
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Send a query to an AI agent. Routes to the specified agent type or auto-selects.
|
|
598
|
+
*
|
|
599
|
+
* **Auth:** Requires org-scoped API key.
|
|
600
|
+
*
|
|
601
|
+
* @param orgId - Organization identifier.
|
|
602
|
+
* @param params - Query text, user ID, and optional agent type.
|
|
603
|
+
* @param options - Optional per-request overrides.
|
|
604
|
+
* @returns Agent response text, agent type, and any tool calls made.
|
|
605
|
+
* @throws {@link HivemindError} 429 if rate limit or token quota is exceeded.
|
|
606
|
+
*
|
|
607
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/agents/query`
|
|
608
|
+
*/
|
|
609
|
+
queryAgent(orgId, params, options) {
|
|
610
|
+
return this.post(`/organizations/${orgId}/agents/query`, params, options);
|
|
611
|
+
}
|
|
612
|
+
// -----------------------------------------------------------------------
|
|
613
|
+
// Audio
|
|
614
|
+
// -----------------------------------------------------------------------
|
|
615
|
+
/**
|
|
616
|
+
* Transcribe audio content to text (speech-to-text).
|
|
617
|
+
*
|
|
618
|
+
* **Auth:** Requires org-scoped API key.
|
|
619
|
+
*
|
|
620
|
+
* @param orgId - Organization identifier.
|
|
621
|
+
* @param params - Audio content and optional BCP-47 language code.
|
|
622
|
+
* @param options - Optional per-request overrides.
|
|
623
|
+
* @returns Transcription result with transcript text, confidence, and language.
|
|
624
|
+
* @throws {@link HivemindError} 429 if rate limit is exceeded.
|
|
625
|
+
*
|
|
626
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/audio/transcribe`
|
|
627
|
+
*/
|
|
628
|
+
transcribeAudio(orgId, params, options) {
|
|
629
|
+
return this.post(`/organizations/${orgId}/audio/transcribe`, params, options);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Convert text to speech (text-to-speech synthesis).
|
|
633
|
+
* Returns a signed URL to the generated audio file.
|
|
634
|
+
*
|
|
635
|
+
* **Auth:** Requires org-scoped API key.
|
|
636
|
+
*
|
|
637
|
+
* @param orgId - Organization identifier.
|
|
638
|
+
* @param params - Text to synthesize and optional voice name.
|
|
639
|
+
* @param options - Optional per-request overrides.
|
|
640
|
+
* @returns Audio URL, duration, and voice used.
|
|
641
|
+
* @throws {@link HivemindError} 429 if rate limit is exceeded.
|
|
642
|
+
*
|
|
643
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/audio/synthesize`
|
|
644
|
+
*/
|
|
645
|
+
synthesizeAudio(orgId, params, options) {
|
|
646
|
+
return this.post(`/organizations/${orgId}/audio/synthesize`, params, options);
|
|
647
|
+
}
|
|
648
|
+
// -----------------------------------------------------------------------
|
|
649
|
+
// Analytics / ML
|
|
650
|
+
// -----------------------------------------------------------------------
|
|
651
|
+
/**
|
|
652
|
+
* Train a predictive model on tabular data.
|
|
653
|
+
*
|
|
654
|
+
* **Auth:** Requires org-scoped API key.
|
|
655
|
+
*
|
|
656
|
+
* @param orgId - Organization identifier.
|
|
657
|
+
* @param params - Target column, feature columns, and training data rows.
|
|
658
|
+
* @param options - Optional per-request overrides.
|
|
659
|
+
* @returns Deployed model ID and status.
|
|
660
|
+
*
|
|
661
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/analytics/train`
|
|
662
|
+
*
|
|
663
|
+
* @example
|
|
664
|
+
* ```typescript
|
|
665
|
+
* const model = await client.trainModel("acme-corp", {
|
|
666
|
+
* target_column: "churn",
|
|
667
|
+
* feature_columns: ["tenure", "monthly_charges", "total_charges"],
|
|
668
|
+
* rows: [
|
|
669
|
+
* { tenure: 12, monthly_charges: 50, total_charges: 600, churn: 0 },
|
|
670
|
+
* { tenure: 2, monthly_charges: 80, total_charges: 160, churn: 1 },
|
|
671
|
+
* ],
|
|
672
|
+
* });
|
|
673
|
+
* console.log(model.model_id); // Use with predict()
|
|
674
|
+
* ```
|
|
675
|
+
*/
|
|
676
|
+
trainModel(orgId, params, options) {
|
|
677
|
+
return this.post(`/organizations/${orgId}/analytics/train`, params, options);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Run predictions using a previously trained model.
|
|
681
|
+
*
|
|
682
|
+
* **Auth:** Requires org-scoped API key.
|
|
683
|
+
*
|
|
684
|
+
* @param orgId - Organization identifier.
|
|
685
|
+
* @param params - Model ID and data instances to predict on.
|
|
686
|
+
* @param options - Optional per-request overrides.
|
|
687
|
+
* @returns Predictions for each input instance.
|
|
688
|
+
* @throws {@link HivemindError} 404 if the model does not exist.
|
|
689
|
+
*
|
|
690
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/analytics/predict`
|
|
691
|
+
*/
|
|
692
|
+
predict(orgId, params, options) {
|
|
693
|
+
return this.post(`/organizations/${orgId}/analytics/predict`, params, options);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Generate a time-series forecast from historical data using ARIMA-based modeling.
|
|
697
|
+
*
|
|
698
|
+
* **Auth:** Requires org-scoped API key.
|
|
699
|
+
*
|
|
700
|
+
* @param orgId - Organization identifier.
|
|
701
|
+
* @param params - Historical series values and optional forecast horizon (1–365).
|
|
702
|
+
* @param options - Optional per-request overrides.
|
|
703
|
+
* @returns Predicted future values.
|
|
704
|
+
*
|
|
705
|
+
* **Endpoint:** `POST /v1/organizations/{orgId}/analytics/forecast`
|
|
706
|
+
*/
|
|
707
|
+
forecast(orgId, params, options) {
|
|
708
|
+
return this.post(`/organizations/${orgId}/analytics/forecast`, params, options);
|
|
709
|
+
}
|
|
710
|
+
// -----------------------------------------------------------------------
|
|
711
|
+
// Billing
|
|
712
|
+
// -----------------------------------------------------------------------
|
|
713
|
+
/**
|
|
714
|
+
* Get the monthly usage summary for an organization.
|
|
715
|
+
* Includes token, image, video, storage, and compute usage against tier limits.
|
|
716
|
+
*
|
|
717
|
+
* **Auth:** Requires org-scoped API key.
|
|
718
|
+
*
|
|
719
|
+
* @param orgId - Organization identifier.
|
|
720
|
+
* @param month - Month in `YYYY-MM` format. Defaults to current month.
|
|
721
|
+
* @param options - Optional per-request overrides.
|
|
722
|
+
* @returns Usage counters, tier limits, and quota status.
|
|
723
|
+
*
|
|
724
|
+
* **Endpoint:** `GET /v1/organizations/{orgId}/usage?month={month}`
|
|
725
|
+
*/
|
|
726
|
+
getUsage(orgId, month, options) {
|
|
727
|
+
const query = month ? { month } : undefined;
|
|
728
|
+
return this.get(`/organizations/${orgId}/usage`, query, options);
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Get the monthly invoice with detailed cost breakdown by resource type.
|
|
732
|
+
*
|
|
733
|
+
* **Auth:** Requires org-scoped API key.
|
|
734
|
+
*
|
|
735
|
+
* @param orgId - Organization identifier.
|
|
736
|
+
* @param month - Month in `YYYY-MM` format. Defaults to current month.
|
|
737
|
+
* @param options - Optional per-request overrides.
|
|
738
|
+
* @returns Invoice with itemized costs and total in USD.
|
|
739
|
+
*
|
|
740
|
+
* **Endpoint:** `GET /v1/organizations/{orgId}/invoice?month={month}`
|
|
741
|
+
*/
|
|
742
|
+
getInvoice(orgId, month, options) {
|
|
743
|
+
const query = month ? { month } : undefined;
|
|
744
|
+
return this.get(`/organizations/${orgId}/invoice`, query, options);
|
|
745
|
+
}
|
|
746
|
+
// -----------------------------------------------------------------------
|
|
747
|
+
// Audit
|
|
748
|
+
// -----------------------------------------------------------------------
|
|
749
|
+
/**
|
|
750
|
+
* Retrieve audit log records for an organization.
|
|
751
|
+
*
|
|
752
|
+
* **Auth:** Requires org-scoped API key.
|
|
753
|
+
*
|
|
754
|
+
* @param orgId - Organization identifier.
|
|
755
|
+
* @param options - Optional per-request overrides.
|
|
756
|
+
* @returns Audit log entries with timestamps, actions, and metadata.
|
|
757
|
+
*
|
|
758
|
+
* **Endpoint:** `GET /v1/organizations/{orgId}/audit`
|
|
759
|
+
*/
|
|
760
|
+
getAuditLogs(orgId, options) {
|
|
761
|
+
return this.get(`/organizations/${orgId}/audit`, undefined, options);
|
|
762
|
+
}
|
|
763
|
+
// -----------------------------------------------------------------------
|
|
764
|
+
// Scraping
|
|
765
|
+
// -----------------------------------------------------------------------
|
|
766
|
+
/**
|
|
767
|
+
* Get the current scraping runtime configuration.
|
|
768
|
+
*
|
|
769
|
+
* **Auth:** None required.
|
|
770
|
+
*
|
|
771
|
+
* @returns Execution mode, Cloud Run status, and cache statistics.
|
|
772
|
+
*
|
|
773
|
+
* **Endpoint:** `GET /v1/scraping/config`
|
|
774
|
+
*/
|
|
775
|
+
getScrapingConfig() {
|
|
776
|
+
return this.get("/scraping/config");
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Submit URLs for scraping. JS-heavy sites (Reddit, Twitter, LinkedIn)
|
|
780
|
+
* are auto-routed to Selenium.
|
|
781
|
+
*
|
|
782
|
+
* **Auth:** None required.
|
|
783
|
+
*
|
|
784
|
+
* @param params - Object containing the `urls` array.
|
|
785
|
+
* @returns Task ID and submission status.
|
|
786
|
+
*
|
|
787
|
+
* **Endpoint:** `POST /v1/scraping/scrape`
|
|
788
|
+
*/
|
|
789
|
+
scrape(params) {
|
|
790
|
+
return this.post("/scraping/scrape", params);
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Check the status and results of a scrape task.
|
|
794
|
+
*
|
|
795
|
+
* **Auth:** None required.
|
|
796
|
+
*
|
|
797
|
+
* @param taskId - Task identifier (from `scrape()`).
|
|
798
|
+
* @returns Task status and scraped results (empty while pending).
|
|
799
|
+
*
|
|
800
|
+
* **Endpoint:** `GET /v1/scraping/status/{taskId}`
|
|
801
|
+
*/
|
|
802
|
+
getScrapeStatus(taskId) {
|
|
803
|
+
return this.get(`/scraping/status/${taskId}`);
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Submit a scrape job and poll until results are ready.
|
|
807
|
+
*
|
|
808
|
+
* @param urls - URLs to scrape.
|
|
809
|
+
* @param intervalMs - Polling interval in milliseconds. @default 2000
|
|
810
|
+
* @param maxWaitMs - Maximum wait time in milliseconds. @default 120000 (2 min)
|
|
811
|
+
* @returns Final scrape status with results.
|
|
812
|
+
* @throws Error if the task does not complete within `maxWaitMs`.
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```typescript
|
|
816
|
+
* const result = await client.scrapeAndWait(
|
|
817
|
+
* ["https://example.com", "https://example.org"],
|
|
818
|
+
* 2000,
|
|
819
|
+
* 60_000,
|
|
820
|
+
* );
|
|
821
|
+
* for (const item of result.result) {
|
|
822
|
+
* console.log(item.title, item.full_text?.substring(0, 200));
|
|
823
|
+
* }
|
|
824
|
+
* ```
|
|
825
|
+
*/
|
|
826
|
+
async scrapeAndWait(urls, intervalMs = 2000, maxWaitMs = 120_000) {
|
|
827
|
+
const { task_id } = await this.scrape({ urls });
|
|
828
|
+
const start = Date.now();
|
|
829
|
+
while (Date.now() - start < maxWaitMs) {
|
|
830
|
+
const status = await this.getScrapeStatus(task_id);
|
|
831
|
+
if (["SUCCESS", "FAILURE", "completed"].includes(status.status)) {
|
|
832
|
+
return status;
|
|
833
|
+
}
|
|
834
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
835
|
+
}
|
|
836
|
+
throw new Error(`Scrape ${task_id} did not complete within ${maxWaitMs}ms`);
|
|
837
|
+
}
|
|
838
|
+
// -----------------------------------------------------------------------
|
|
839
|
+
// Webhooks
|
|
840
|
+
// -----------------------------------------------------------------------
|
|
841
|
+
/**
|
|
842
|
+
* Send a video generation completion webhook notification.
|
|
843
|
+
*
|
|
844
|
+
* **Auth:** Requires `webhookSecret` in client config (sends `X-Webhook-Secret` header).
|
|
845
|
+
*
|
|
846
|
+
* @param payload - Webhook payload with job_id, org_id, status, and optional metadata.
|
|
847
|
+
* @returns `{ received: true }` on success.
|
|
848
|
+
* @throws {@link HivemindError} 401 if the webhook secret is invalid.
|
|
849
|
+
*
|
|
850
|
+
* **Endpoint:** `POST /v1/webhook/video-complete`
|
|
851
|
+
*/
|
|
852
|
+
sendVideoCompleteWebhook(payload) {
|
|
853
|
+
return this.post("/webhook/video-complete", payload);
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Send a document processing completion webhook notification.
|
|
857
|
+
*
|
|
858
|
+
* **Auth:** Requires `webhookSecret` in client config (sends `X-Webhook-Secret` header).
|
|
859
|
+
*
|
|
860
|
+
* @param payload - Webhook payload with document_id, org_id, status, and optional metadata.
|
|
861
|
+
* @returns `{ received: true }` on success.
|
|
862
|
+
* @throws {@link HivemindError} 401 if the webhook secret is invalid.
|
|
863
|
+
*
|
|
864
|
+
* **Endpoint:** `POST /v1/webhook/document-processed`
|
|
865
|
+
*/
|
|
866
|
+
sendDocumentProcessedWebhook(payload) {
|
|
867
|
+
return this.post("/webhook/document-processed", payload);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
exports.HivemindClient = HivemindClient;
|
|
871
|
+
//# sourceMappingURL=client.js.map
|