valyu-js 2.5.8 → 2.6.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.
- package/README.md +65 -34
- package/dist/index.d.mts +79 -6
- package/dist/index.d.ts +79 -6
- package/dist/index.js +142 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +140 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
2
3
|
import axios from "axios";
|
|
4
|
+
function normalizeContentsJobResponse(api) {
|
|
5
|
+
return {
|
|
6
|
+
success: api.success ?? true,
|
|
7
|
+
jobId: api.job_id ?? api.jobId,
|
|
8
|
+
status: api.status ?? "pending",
|
|
9
|
+
urlsTotal: api.urls_total ?? api.urlsTotal ?? 0,
|
|
10
|
+
urlsProcessed: api.urls_processed ?? api.urlsProcessed ?? 0,
|
|
11
|
+
urlsFailed: api.urls_failed ?? api.urlsFailed ?? 0,
|
|
12
|
+
createdAt: api.created_at ?? api.createdAt ?? 0,
|
|
13
|
+
updatedAt: api.updated_at ?? api.updatedAt ?? 0,
|
|
14
|
+
currentBatch: api.current_batch ?? api.currentBatch,
|
|
15
|
+
totalBatches: api.total_batches ?? api.totalBatches,
|
|
16
|
+
results: api.results,
|
|
17
|
+
actualCostDollars: api.actual_cost_dollars ?? api.actualCostDollars,
|
|
18
|
+
error: api.error,
|
|
19
|
+
webhookSecret: api.webhook_secret ?? api.webhookSecret
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function normalizeContentsAsyncJobResponse(api) {
|
|
23
|
+
return {
|
|
24
|
+
success: api.success ?? true,
|
|
25
|
+
jobId: api.job_id ?? api.jobId,
|
|
26
|
+
status: "pending",
|
|
27
|
+
urlsTotal: api.urls_total ?? api.urlsTotal ?? 0,
|
|
28
|
+
webhookSecret: api.webhook_secret ?? api.webhookSecret,
|
|
29
|
+
txId: api.tx_id ?? api.txId ?? ""
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function verifyContentsWebhookSignature(payload, signature, timestamp, secret) {
|
|
33
|
+
const expected = createHmac("sha256", secret).update(`${timestamp}.${payload}`).digest("hex");
|
|
34
|
+
const expectedSignature = `sha256=${expected}`;
|
|
35
|
+
if (signature.length !== expectedSignature.length) return false;
|
|
36
|
+
return timingSafeEqual(
|
|
37
|
+
Buffer.from(signature, "utf8"),
|
|
38
|
+
Buffer.from(expectedSignature, "utf8")
|
|
39
|
+
);
|
|
40
|
+
}
|
|
3
41
|
var Valyu = class {
|
|
4
42
|
constructor(apiKey, baseUrl = "https://api.valyu.ai/v1") {
|
|
5
43
|
if (!apiKey) {
|
|
@@ -265,6 +303,9 @@ var Valyu = class {
|
|
|
265
303
|
if (options.excludeSources !== void 0) {
|
|
266
304
|
payload.exclude_sources = options.excludeSources;
|
|
267
305
|
}
|
|
306
|
+
if (options.sourceBiases !== void 0) {
|
|
307
|
+
payload.source_biases = options.sourceBiases;
|
|
308
|
+
}
|
|
268
309
|
if (options.category !== void 0) {
|
|
269
310
|
payload.category = options.category;
|
|
270
311
|
}
|
|
@@ -317,14 +358,16 @@ var Valyu = class {
|
|
|
317
358
|
}
|
|
318
359
|
/**
|
|
319
360
|
* Extract content from URLs with optional AI processing
|
|
320
|
-
* @param urls - Array of URLs to process (max 10)
|
|
361
|
+
* @param urls - Array of URLs to process (max 10 sync, max 50 with async: true)
|
|
321
362
|
* @param options - Content extraction configuration options
|
|
322
363
|
* @param options.summary - AI summary configuration: false (raw), true (auto), string (custom), or JSON schema
|
|
323
364
|
* @param options.extractEffort - Extraction thoroughness: "normal", "high", or "auto"
|
|
324
365
|
* @param options.responseLength - Content length per URL
|
|
325
366
|
* @param options.maxPriceDollars - Maximum cost limit in USD
|
|
326
367
|
* @param options.screenshot - Request page screenshots (default: false)
|
|
327
|
-
* @
|
|
368
|
+
* @param options.async - Force async processing (required for >10 URLs)
|
|
369
|
+
* @param options.webhookUrl - HTTPS URL for completion notification (async only)
|
|
370
|
+
* @returns Promise resolving to sync results or async job (when async: true or >10 URLs)
|
|
328
371
|
*/
|
|
329
372
|
async contents(urls, options = {}) {
|
|
330
373
|
try {
|
|
@@ -352,10 +395,23 @@ var Valyu = class {
|
|
|
352
395
|
total_characters: 0
|
|
353
396
|
};
|
|
354
397
|
}
|
|
355
|
-
|
|
398
|
+
const isAsync = options.async === true || urls.length > 10;
|
|
399
|
+
if (urls.length > 10 && !options.async) {
|
|
400
|
+
return {
|
|
401
|
+
success: false,
|
|
402
|
+
error: "Requests with more than 10 URLs require async processing. Add async: true to the request.",
|
|
403
|
+
urls_requested: urls.length,
|
|
404
|
+
urls_processed: 0,
|
|
405
|
+
urls_failed: urls.length,
|
|
406
|
+
results: [],
|
|
407
|
+
total_cost_dollars: 0,
|
|
408
|
+
total_characters: 0
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
if (urls.length > 50) {
|
|
356
412
|
return {
|
|
357
413
|
success: false,
|
|
358
|
-
error: "Maximum
|
|
414
|
+
error: "Maximum 50 URLs allowed per request",
|
|
359
415
|
urls_requested: urls.length,
|
|
360
416
|
urls_processed: 0,
|
|
361
417
|
urls_failed: urls.length,
|
|
@@ -421,6 +477,12 @@ var Valyu = class {
|
|
|
421
477
|
if (options.screenshot !== void 0) {
|
|
422
478
|
payload.screenshot = options.screenshot;
|
|
423
479
|
}
|
|
480
|
+
if (isAsync) {
|
|
481
|
+
payload.async = true;
|
|
482
|
+
}
|
|
483
|
+
if (options.webhookUrl !== void 0) {
|
|
484
|
+
payload.webhook_url = options.webhookUrl;
|
|
485
|
+
}
|
|
424
486
|
const response = await axios.post(`${this.baseUrl}/contents`, payload, {
|
|
425
487
|
headers: this.headers
|
|
426
488
|
});
|
|
@@ -436,6 +498,9 @@ var Valyu = class {
|
|
|
436
498
|
total_characters: 0
|
|
437
499
|
};
|
|
438
500
|
}
|
|
501
|
+
if (response.status === 202) {
|
|
502
|
+
return normalizeContentsAsyncJobResponse(response.data);
|
|
503
|
+
}
|
|
439
504
|
return response.data;
|
|
440
505
|
} catch (e) {
|
|
441
506
|
return {
|
|
@@ -450,6 +515,61 @@ var Valyu = class {
|
|
|
450
515
|
};
|
|
451
516
|
}
|
|
452
517
|
}
|
|
518
|
+
/**
|
|
519
|
+
* Get async Contents job status and results
|
|
520
|
+
* @param jobId - Job ID from contents() async response
|
|
521
|
+
* @returns Promise resolving to job status
|
|
522
|
+
*/
|
|
523
|
+
async getContentsJob(jobId) {
|
|
524
|
+
try {
|
|
525
|
+
const response = await axios.get(
|
|
526
|
+
`${this.baseUrl}/contents/jobs/${jobId}`,
|
|
527
|
+
{ headers: this.headers }
|
|
528
|
+
);
|
|
529
|
+
return normalizeContentsJobResponse(response.data);
|
|
530
|
+
} catch (e) {
|
|
531
|
+
const errData = e.response?.data;
|
|
532
|
+
const status = e.response?.status;
|
|
533
|
+
return {
|
|
534
|
+
success: false,
|
|
535
|
+
jobId,
|
|
536
|
+
status: "failed",
|
|
537
|
+
urlsTotal: 0,
|
|
538
|
+
urlsProcessed: 0,
|
|
539
|
+
urlsFailed: 0,
|
|
540
|
+
createdAt: 0,
|
|
541
|
+
updatedAt: 0,
|
|
542
|
+
error: errData?.error || (status === 403 ? "Forbidden - you do not have access to this job" : status === 404 ? `Job ${jobId} not found` : e.message)
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Wait for async Contents job completion (polls until terminal state)
|
|
548
|
+
* @param jobId - Job ID from contents() async response
|
|
549
|
+
* @param options - Wait configuration (pollInterval, maxWaitTime, onProgress)
|
|
550
|
+
* @returns Promise resolving to final job status with results
|
|
551
|
+
*/
|
|
552
|
+
async waitForJob(jobId, options = {}) {
|
|
553
|
+
const pollInterval = options.pollInterval ?? 5e3;
|
|
554
|
+
const maxWaitTime = options.maxWaitTime ?? 72e5;
|
|
555
|
+
const startTime = Date.now();
|
|
556
|
+
while (true) {
|
|
557
|
+
const status = await this.getContentsJob(jobId);
|
|
558
|
+
if (!status.success && status.error) {
|
|
559
|
+
throw new Error(status.error);
|
|
560
|
+
}
|
|
561
|
+
if (options.onProgress) {
|
|
562
|
+
options.onProgress(status);
|
|
563
|
+
}
|
|
564
|
+
if (status.status === "completed" || status.status === "partial" || status.status === "failed") {
|
|
565
|
+
return status;
|
|
566
|
+
}
|
|
567
|
+
if (Date.now() - startTime > maxWaitTime) {
|
|
568
|
+
throw new Error("Maximum wait time exceeded");
|
|
569
|
+
}
|
|
570
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
571
|
+
}
|
|
572
|
+
}
|
|
453
573
|
/**
|
|
454
574
|
* DeepResearch: Create a new research task
|
|
455
575
|
* @param options.search - Search configuration options
|
|
@@ -478,6 +598,10 @@ var Valyu = class {
|
|
|
478
598
|
code_execution: options.codeExecution !== false
|
|
479
599
|
};
|
|
480
600
|
if (options.strategy) payload.strategy = options.strategy;
|
|
601
|
+
if (options.researchStrategy)
|
|
602
|
+
payload.research_strategy = options.researchStrategy;
|
|
603
|
+
if (options.reportFormat)
|
|
604
|
+
payload.report_format = options.reportFormat;
|
|
481
605
|
if (options.search) {
|
|
482
606
|
payload.search = {};
|
|
483
607
|
if (options.search.searchType) {
|
|
@@ -489,6 +613,9 @@ var Valyu = class {
|
|
|
489
613
|
if (options.search.excludedSources) {
|
|
490
614
|
payload.search.excluded_sources = options.search.excludedSources;
|
|
491
615
|
}
|
|
616
|
+
if (options.search.sourceBiases) {
|
|
617
|
+
payload.search.source_biases = options.search.sourceBiases;
|
|
618
|
+
}
|
|
492
619
|
if (options.search.startDate) {
|
|
493
620
|
payload.search.start_date = options.search.startDate;
|
|
494
621
|
}
|
|
@@ -785,6 +912,9 @@ var Valyu = class {
|
|
|
785
912
|
if (options.search.excludedSources) {
|
|
786
913
|
payload.search.excluded_sources = options.search.excludedSources;
|
|
787
914
|
}
|
|
915
|
+
if (options.search.sourceBiases) {
|
|
916
|
+
payload.search.source_biases = options.search.sourceBiases;
|
|
917
|
+
}
|
|
788
918
|
if (options.search.startDate) {
|
|
789
919
|
payload.search.start_date = options.search.startDate;
|
|
790
920
|
}
|
|
@@ -872,6 +1002,10 @@ var Valyu = class {
|
|
|
872
1002
|
}
|
|
873
1003
|
if (task.id) taskPayload.id = task.id;
|
|
874
1004
|
if (task.strategy) taskPayload.strategy = task.strategy;
|
|
1005
|
+
if (task.researchStrategy)
|
|
1006
|
+
taskPayload.research_strategy = task.researchStrategy;
|
|
1007
|
+
if (task.reportFormat)
|
|
1008
|
+
taskPayload.report_format = task.reportFormat;
|
|
875
1009
|
if (task.urls) taskPayload.urls = task.urls;
|
|
876
1010
|
if (task.metadata) taskPayload.metadata = task.metadata;
|
|
877
1011
|
return taskPayload;
|
|
@@ -1342,6 +1476,7 @@ var Valyu = class {
|
|
|
1342
1476
|
}
|
|
1343
1477
|
};
|
|
1344
1478
|
export {
|
|
1345
|
-
Valyu
|
|
1479
|
+
Valyu,
|
|
1480
|
+
verifyContentsWebhookSignature
|
|
1346
1481
|
};
|
|
1347
1482
|
//# sourceMappingURL=index.mjs.map
|