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.js
CHANGED
|
@@ -30,10 +30,49 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
Valyu: () => Valyu
|
|
33
|
+
Valyu: () => Valyu,
|
|
34
|
+
verifyContentsWebhookSignature: () => verifyContentsWebhookSignature
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
var import_crypto = require("crypto");
|
|
36
38
|
var import_axios = __toESM(require("axios"));
|
|
39
|
+
function normalizeContentsJobResponse(api) {
|
|
40
|
+
return {
|
|
41
|
+
success: api.success ?? true,
|
|
42
|
+
jobId: api.job_id ?? api.jobId,
|
|
43
|
+
status: api.status ?? "pending",
|
|
44
|
+
urlsTotal: api.urls_total ?? api.urlsTotal ?? 0,
|
|
45
|
+
urlsProcessed: api.urls_processed ?? api.urlsProcessed ?? 0,
|
|
46
|
+
urlsFailed: api.urls_failed ?? api.urlsFailed ?? 0,
|
|
47
|
+
createdAt: api.created_at ?? api.createdAt ?? 0,
|
|
48
|
+
updatedAt: api.updated_at ?? api.updatedAt ?? 0,
|
|
49
|
+
currentBatch: api.current_batch ?? api.currentBatch,
|
|
50
|
+
totalBatches: api.total_batches ?? api.totalBatches,
|
|
51
|
+
results: api.results,
|
|
52
|
+
actualCostDollars: api.actual_cost_dollars ?? api.actualCostDollars,
|
|
53
|
+
error: api.error,
|
|
54
|
+
webhookSecret: api.webhook_secret ?? api.webhookSecret
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function normalizeContentsAsyncJobResponse(api) {
|
|
58
|
+
return {
|
|
59
|
+
success: api.success ?? true,
|
|
60
|
+
jobId: api.job_id ?? api.jobId,
|
|
61
|
+
status: "pending",
|
|
62
|
+
urlsTotal: api.urls_total ?? api.urlsTotal ?? 0,
|
|
63
|
+
webhookSecret: api.webhook_secret ?? api.webhookSecret,
|
|
64
|
+
txId: api.tx_id ?? api.txId ?? ""
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function verifyContentsWebhookSignature(payload, signature, timestamp, secret) {
|
|
68
|
+
const expected = (0, import_crypto.createHmac)("sha256", secret).update(`${timestamp}.${payload}`).digest("hex");
|
|
69
|
+
const expectedSignature = `sha256=${expected}`;
|
|
70
|
+
if (signature.length !== expectedSignature.length) return false;
|
|
71
|
+
return (0, import_crypto.timingSafeEqual)(
|
|
72
|
+
Buffer.from(signature, "utf8"),
|
|
73
|
+
Buffer.from(expectedSignature, "utf8")
|
|
74
|
+
);
|
|
75
|
+
}
|
|
37
76
|
var Valyu = class {
|
|
38
77
|
constructor(apiKey, baseUrl = "https://api.valyu.ai/v1") {
|
|
39
78
|
if (!apiKey) {
|
|
@@ -299,6 +338,9 @@ var Valyu = class {
|
|
|
299
338
|
if (options.excludeSources !== void 0) {
|
|
300
339
|
payload.exclude_sources = options.excludeSources;
|
|
301
340
|
}
|
|
341
|
+
if (options.sourceBiases !== void 0) {
|
|
342
|
+
payload.source_biases = options.sourceBiases;
|
|
343
|
+
}
|
|
302
344
|
if (options.category !== void 0) {
|
|
303
345
|
payload.category = options.category;
|
|
304
346
|
}
|
|
@@ -351,14 +393,16 @@ var Valyu = class {
|
|
|
351
393
|
}
|
|
352
394
|
/**
|
|
353
395
|
* Extract content from URLs with optional AI processing
|
|
354
|
-
* @param urls - Array of URLs to process (max 10)
|
|
396
|
+
* @param urls - Array of URLs to process (max 10 sync, max 50 with async: true)
|
|
355
397
|
* @param options - Content extraction configuration options
|
|
356
398
|
* @param options.summary - AI summary configuration: false (raw), true (auto), string (custom), or JSON schema
|
|
357
399
|
* @param options.extractEffort - Extraction thoroughness: "normal", "high", or "auto"
|
|
358
400
|
* @param options.responseLength - Content length per URL
|
|
359
401
|
* @param options.maxPriceDollars - Maximum cost limit in USD
|
|
360
402
|
* @param options.screenshot - Request page screenshots (default: false)
|
|
361
|
-
* @
|
|
403
|
+
* @param options.async - Force async processing (required for >10 URLs)
|
|
404
|
+
* @param options.webhookUrl - HTTPS URL for completion notification (async only)
|
|
405
|
+
* @returns Promise resolving to sync results or async job (when async: true or >10 URLs)
|
|
362
406
|
*/
|
|
363
407
|
async contents(urls, options = {}) {
|
|
364
408
|
try {
|
|
@@ -386,10 +430,23 @@ var Valyu = class {
|
|
|
386
430
|
total_characters: 0
|
|
387
431
|
};
|
|
388
432
|
}
|
|
389
|
-
|
|
433
|
+
const isAsync = options.async === true || urls.length > 10;
|
|
434
|
+
if (urls.length > 10 && !options.async) {
|
|
435
|
+
return {
|
|
436
|
+
success: false,
|
|
437
|
+
error: "Requests with more than 10 URLs require async processing. Add async: true to the request.",
|
|
438
|
+
urls_requested: urls.length,
|
|
439
|
+
urls_processed: 0,
|
|
440
|
+
urls_failed: urls.length,
|
|
441
|
+
results: [],
|
|
442
|
+
total_cost_dollars: 0,
|
|
443
|
+
total_characters: 0
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
if (urls.length > 50) {
|
|
390
447
|
return {
|
|
391
448
|
success: false,
|
|
392
|
-
error: "Maximum
|
|
449
|
+
error: "Maximum 50 URLs allowed per request",
|
|
393
450
|
urls_requested: urls.length,
|
|
394
451
|
urls_processed: 0,
|
|
395
452
|
urls_failed: urls.length,
|
|
@@ -455,6 +512,12 @@ var Valyu = class {
|
|
|
455
512
|
if (options.screenshot !== void 0) {
|
|
456
513
|
payload.screenshot = options.screenshot;
|
|
457
514
|
}
|
|
515
|
+
if (isAsync) {
|
|
516
|
+
payload.async = true;
|
|
517
|
+
}
|
|
518
|
+
if (options.webhookUrl !== void 0) {
|
|
519
|
+
payload.webhook_url = options.webhookUrl;
|
|
520
|
+
}
|
|
458
521
|
const response = await import_axios.default.post(`${this.baseUrl}/contents`, payload, {
|
|
459
522
|
headers: this.headers
|
|
460
523
|
});
|
|
@@ -470,6 +533,9 @@ var Valyu = class {
|
|
|
470
533
|
total_characters: 0
|
|
471
534
|
};
|
|
472
535
|
}
|
|
536
|
+
if (response.status === 202) {
|
|
537
|
+
return normalizeContentsAsyncJobResponse(response.data);
|
|
538
|
+
}
|
|
473
539
|
return response.data;
|
|
474
540
|
} catch (e) {
|
|
475
541
|
return {
|
|
@@ -484,6 +550,61 @@ var Valyu = class {
|
|
|
484
550
|
};
|
|
485
551
|
}
|
|
486
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Get async Contents job status and results
|
|
555
|
+
* @param jobId - Job ID from contents() async response
|
|
556
|
+
* @returns Promise resolving to job status
|
|
557
|
+
*/
|
|
558
|
+
async getContentsJob(jobId) {
|
|
559
|
+
try {
|
|
560
|
+
const response = await import_axios.default.get(
|
|
561
|
+
`${this.baseUrl}/contents/jobs/${jobId}`,
|
|
562
|
+
{ headers: this.headers }
|
|
563
|
+
);
|
|
564
|
+
return normalizeContentsJobResponse(response.data);
|
|
565
|
+
} catch (e) {
|
|
566
|
+
const errData = e.response?.data;
|
|
567
|
+
const status = e.response?.status;
|
|
568
|
+
return {
|
|
569
|
+
success: false,
|
|
570
|
+
jobId,
|
|
571
|
+
status: "failed",
|
|
572
|
+
urlsTotal: 0,
|
|
573
|
+
urlsProcessed: 0,
|
|
574
|
+
urlsFailed: 0,
|
|
575
|
+
createdAt: 0,
|
|
576
|
+
updatedAt: 0,
|
|
577
|
+
error: errData?.error || (status === 403 ? "Forbidden - you do not have access to this job" : status === 404 ? `Job ${jobId} not found` : e.message)
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Wait for async Contents job completion (polls until terminal state)
|
|
583
|
+
* @param jobId - Job ID from contents() async response
|
|
584
|
+
* @param options - Wait configuration (pollInterval, maxWaitTime, onProgress)
|
|
585
|
+
* @returns Promise resolving to final job status with results
|
|
586
|
+
*/
|
|
587
|
+
async waitForJob(jobId, options = {}) {
|
|
588
|
+
const pollInterval = options.pollInterval ?? 5e3;
|
|
589
|
+
const maxWaitTime = options.maxWaitTime ?? 72e5;
|
|
590
|
+
const startTime = Date.now();
|
|
591
|
+
while (true) {
|
|
592
|
+
const status = await this.getContentsJob(jobId);
|
|
593
|
+
if (!status.success && status.error) {
|
|
594
|
+
throw new Error(status.error);
|
|
595
|
+
}
|
|
596
|
+
if (options.onProgress) {
|
|
597
|
+
options.onProgress(status);
|
|
598
|
+
}
|
|
599
|
+
if (status.status === "completed" || status.status === "partial" || status.status === "failed") {
|
|
600
|
+
return status;
|
|
601
|
+
}
|
|
602
|
+
if (Date.now() - startTime > maxWaitTime) {
|
|
603
|
+
throw new Error("Maximum wait time exceeded");
|
|
604
|
+
}
|
|
605
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
606
|
+
}
|
|
607
|
+
}
|
|
487
608
|
/**
|
|
488
609
|
* DeepResearch: Create a new research task
|
|
489
610
|
* @param options.search - Search configuration options
|
|
@@ -512,6 +633,10 @@ var Valyu = class {
|
|
|
512
633
|
code_execution: options.codeExecution !== false
|
|
513
634
|
};
|
|
514
635
|
if (options.strategy) payload.strategy = options.strategy;
|
|
636
|
+
if (options.researchStrategy)
|
|
637
|
+
payload.research_strategy = options.researchStrategy;
|
|
638
|
+
if (options.reportFormat)
|
|
639
|
+
payload.report_format = options.reportFormat;
|
|
515
640
|
if (options.search) {
|
|
516
641
|
payload.search = {};
|
|
517
642
|
if (options.search.searchType) {
|
|
@@ -523,6 +648,9 @@ var Valyu = class {
|
|
|
523
648
|
if (options.search.excludedSources) {
|
|
524
649
|
payload.search.excluded_sources = options.search.excludedSources;
|
|
525
650
|
}
|
|
651
|
+
if (options.search.sourceBiases) {
|
|
652
|
+
payload.search.source_biases = options.search.sourceBiases;
|
|
653
|
+
}
|
|
526
654
|
if (options.search.startDate) {
|
|
527
655
|
payload.search.start_date = options.search.startDate;
|
|
528
656
|
}
|
|
@@ -819,6 +947,9 @@ var Valyu = class {
|
|
|
819
947
|
if (options.search.excludedSources) {
|
|
820
948
|
payload.search.excluded_sources = options.search.excludedSources;
|
|
821
949
|
}
|
|
950
|
+
if (options.search.sourceBiases) {
|
|
951
|
+
payload.search.source_biases = options.search.sourceBiases;
|
|
952
|
+
}
|
|
822
953
|
if (options.search.startDate) {
|
|
823
954
|
payload.search.start_date = options.search.startDate;
|
|
824
955
|
}
|
|
@@ -906,6 +1037,10 @@ var Valyu = class {
|
|
|
906
1037
|
}
|
|
907
1038
|
if (task.id) taskPayload.id = task.id;
|
|
908
1039
|
if (task.strategy) taskPayload.strategy = task.strategy;
|
|
1040
|
+
if (task.researchStrategy)
|
|
1041
|
+
taskPayload.research_strategy = task.researchStrategy;
|
|
1042
|
+
if (task.reportFormat)
|
|
1043
|
+
taskPayload.report_format = task.reportFormat;
|
|
909
1044
|
if (task.urls) taskPayload.urls = task.urls;
|
|
910
1045
|
if (task.metadata) taskPayload.metadata = task.metadata;
|
|
911
1046
|
return taskPayload;
|
|
@@ -1377,6 +1512,7 @@ var Valyu = class {
|
|
|
1377
1512
|
};
|
|
1378
1513
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1379
1514
|
0 && (module.exports = {
|
|
1380
|
-
Valyu
|
|
1515
|
+
Valyu,
|
|
1516
|
+
verifyContentsWebhookSignature
|
|
1381
1517
|
});
|
|
1382
1518
|
//# sourceMappingURL=index.js.map
|