valyu-js 2.5.8 → 2.5.9

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 CHANGED
@@ -334,63 +334,94 @@ Each `SearchResult` contains:
334
334
 
335
335
  The `contents()` method extracts clean, structured content from web pages with optional AI-powered data extraction and summarization. It accepts an array of URLs as the first parameter, followed by optional configuration parameters.
336
336
 
337
+ - **Sync mode** (≤10 URLs): Returns results immediately
338
+ - **Async mode** (>10 URLs or `async: true`): Returns a job object; use `getContentsJob()` or `waitForJob()` to get results
339
+
337
340
  ```javascript
338
- valyu.contents(
339
- urls, // Array of URLs to process (max 10)
340
- {
341
- summary: false, // AI processing: false, true, string, or JSON schema
342
- extractEffort: "normal", // Extraction effort: "normal" or "high"
343
- responseLength: "short", // Content length control
344
- maxPriceDollars: null, // Maximum cost limit in USD
345
- }
346
- );
341
+ // Sync (≤10 URLs)
342
+ const response = await valyu.contents(urls, { summary: true });
343
+
344
+ // Async (11-50 URLs) - returns job, then poll or wait
345
+ const job = await valyu.contents(urls, { async: true });
346
+ const final = await valyu.waitForJob(job.jobId, { pollInterval: 5000 });
347
347
  ```
348
348
 
349
349
  ### Parameters
350
350
 
351
351
  | Parameter | Type | Default | Description |
352
352
  | ----------------- | ----------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
353
- | `urls` | `string[]` | _required_ | Array of URLs to process (maximum 10 URLs per request) |
353
+ | `urls` | `string[]` | _required_ | Array of URLs to process (max 10 sync, max 50 with `async: true`) |
354
354
  | `summary` | `boolean \| string \| object` | `false` | AI summary configuration: `false` (raw content), `true` (auto summary), string (custom instructions), or JSON schema (structured extraction) |
355
- | `extractEffort` | `string` | `"normal"` | Extraction thoroughness: `"normal"` (fast) or `"high"` (more thorough but slower) |
355
+ | `extractEffort` | `string` | `"normal"` | Extraction thoroughness: `"normal"`, `"high"`, or `"auto"` |
356
356
  | `responseLength` | `string \| number` | `"short"` | Content length per URL: `"short"` (25k chars), `"medium"` (50k), `"large"` (100k), `"max"` (no limit), or custom number |
357
357
  | `maxPriceDollars` | `number` | `null` | Maximum cost limit in USD |
358
+ | `screenshot` | `boolean` | `false` | Capture page screenshots |
359
+ | `async` | `boolean` | `false` | Force async processing (required for >10 URLs) |
360
+ | `webhookUrl` | `string` | - | HTTPS URL for completion notification (async only). Save `webhookSecret` for signature verification. |
358
361
 
359
- ### Contents Response Format
362
+ ### Contents Response Format (Sync)
360
363
 
361
- The contents method returns a `ContentsResponse` object with the following structure:
364
+ When sync, returns `ContentsResponse`:
362
365
 
363
366
  ```javascript
364
367
  {
365
- success: boolean, // Request success status
366
- error: string | null, // Error message if any
367
- tx_id: string, // Transaction ID for tracking
368
- urls_requested: number, // Total URLs requested
369
- urls_processed: number, // Successfully processed URLs
370
- urls_failed: number, // Failed URL count
371
- results: ContentResult[], // Array of processed results
372
- total_cost_dollars: number, // Actual cost charged
373
- total_characters: number // Total characters extracted
368
+ success: boolean,
369
+ tx_id: string,
370
+ urls_requested: number,
371
+ urls_processed: number,
372
+ urls_failed: number,
373
+ results: ContentResult[],
374
+ total_cost_dollars: number,
375
+ total_characters: number
374
376
  }
375
377
  ```
376
378
 
377
- Each `ContentResult` contains:
379
+ ### Contents Async Response
380
+
381
+ When async, returns `ContentsAsyncJobResponse` with `jobId`. Use `getContentsJob(jobId)` or `waitForJob(jobId)` to get results.
378
382
 
379
383
  ```javascript
380
- {
381
- url: string, // Source URL
382
- title: string, // Page/document title
383
- content: string | number, // Extracted content
384
- length: number, // Content length in characters
385
- source: string, // Data source identifier
386
- summary?: string | object, // AI-generated summary (if enabled)
387
- summary_success?: boolean, // Whether summary generation succeeded
388
- data_type?: string, // Type of data extracted
389
- image_url?: Record<string, string>, // Extracted images
390
- citation?: string // APA-style citation
384
+ // Poll for status
385
+ const status = await valyu.getContentsJob(jobId);
386
+
387
+ // Or wait until complete (like DeepResearch wait)
388
+ const final = await valyu.waitForJob(jobId, {
389
+ pollInterval: 5000,
390
+ maxWaitTime: 7200000,
391
+ onProgress: (s) => console.log(`${s.urlsProcessed}/${s.urlsTotal}`)
392
+ });
393
+ ```
394
+
395
+ ### ContentResult (with status)
396
+
397
+ Each result has a `status` field. Check before accessing success-only fields:
398
+
399
+ ```javascript
400
+ for (const r of response.results) {
401
+ if (r.status === 'success') {
402
+ console.log(r.title, r.content);
403
+ } else {
404
+ console.log(`Failed: ${r.url} - ${r.error}`);
405
+ }
391
406
  }
392
407
  ```
393
408
 
409
+ ### Webhook Signature Verification
410
+
411
+ When using `webhookUrl`, verify the `X-Webhook-Signature` header with the `webhookSecret` from job creation:
412
+
413
+ ```javascript
414
+ const { verifyContentsWebhookSignature } = require('valyu-js');
415
+
416
+ // In your webhook handler - use raw request body
417
+ const isValid = verifyContentsWebhookSignature(
418
+ rawBody, // Raw request body string
419
+ signatureHeader, // X-Webhook-Signature
420
+ timestampHeader, // X-Webhook-Timestamp
421
+ webhookSecret
422
+ );
423
+ ```
424
+
394
425
  ## Examples
395
426
 
396
427
  ### Basic Search
package/dist/index.d.mts CHANGED
@@ -59,22 +59,65 @@ interface ContentsOptions {
59
59
  responseLength?: ContentResponseLength;
60
60
  maxPriceDollars?: number;
61
61
  screenshot?: boolean;
62
+ async?: boolean;
63
+ webhookUrl?: string;
62
64
  }
63
- interface ContentResult {
65
+ interface ContentResultBase {
64
66
  url: string;
67
+ status: "success" | "failed";
68
+ }
69
+ interface ContentResultSuccess extends ContentResultBase {
70
+ status: "success";
65
71
  title: string;
66
72
  content: string | number;
67
73
  length: number;
68
74
  source: string;
69
- price: number;
75
+ price?: number;
70
76
  description?: string;
71
77
  summary?: string | object;
72
78
  summary_success?: boolean;
73
79
  data_type?: string;
74
80
  image_url?: Record<string, string>;
75
81
  screenshot_url?: string | null;
82
+ source_type?: string;
83
+ publication_date?: string;
76
84
  citation?: string;
77
85
  }
86
+ interface ContentResultFailed extends ContentResultBase {
87
+ status: "failed";
88
+ error: string;
89
+ }
90
+ type ContentResult = ContentResultSuccess | ContentResultFailed;
91
+ type ContentsJobStatus = "pending" | "processing" | "completed" | "partial" | "failed";
92
+ interface ContentsJobWaitOptions {
93
+ pollInterval?: number;
94
+ maxWaitTime?: number;
95
+ onProgress?: (status: ContentsJobResponse) => void;
96
+ }
97
+ interface ContentsJobResponse {
98
+ success: boolean;
99
+ jobId: string;
100
+ status: ContentsJobStatus;
101
+ urlsTotal: number;
102
+ urlsProcessed: number;
103
+ urlsFailed: number;
104
+ createdAt: number;
105
+ updatedAt: number;
106
+ currentBatch?: number;
107
+ totalBatches?: number;
108
+ results?: ContentResult[];
109
+ actualCostDollars?: number;
110
+ error?: string;
111
+ webhookSecret?: string;
112
+ }
113
+ interface ContentsAsyncJobResponse {
114
+ success: boolean;
115
+ jobId: string;
116
+ status: "pending";
117
+ urlsTotal: number;
118
+ webhookSecret?: string;
119
+ txId: string;
120
+ }
78
121
  interface ContentsResponse {
79
122
  success: boolean;
80
123
  error?: string | null;
@@ -576,6 +619,15 @@ interface DatasourcesCategoriesResponse {
576
619
  error?: string;
577
620
  }
578
621
 
622
+ /**
623
+ * Verify webhook signature for Contents API async completion notifications.
624
+ * Use the raw request body (not parsed JSON) as payload.
625
+ * @param payload - Raw request body string
626
+ * @param signature - X-Webhook-Signature header value
627
+ * @param timestamp - X-Webhook-Timestamp header value
628
+ * @param secret - webhookSecret from job creation
629
+ */
630
+ declare function verifyContentsWebhookSignature(payload: string, signature: string, timestamp: string, secret: string): boolean;
579
631
  declare class Valyu {
580
632
  private baseUrl;
581
633
  private headers;
@@ -652,16 +704,31 @@ declare class Valyu {
652
704
  search(query: string, options?: SearchOptions): Promise<SearchResponse>;
653
705
  /**
654
706
  * Extract content from URLs with optional AI processing
655
- * @param urls - Array of URLs to process (max 10)
707
+ * @param urls - Array of URLs to process (max 10 sync, max 50 with async: true)
656
708
  * @param options - Content extraction configuration options
657
709
  * @param options.summary - AI summary configuration: false (raw), true (auto), string (custom), or JSON schema
658
710
  * @param options.extractEffort - Extraction thoroughness: "normal", "high", or "auto"
659
711
  * @param options.responseLength - Content length per URL
660
712
  * @param options.maxPriceDollars - Maximum cost limit in USD
661
713
  * @param options.screenshot - Request page screenshots (default: false)
662
- * @returns Promise resolving to content extraction results
714
+ * @param options.async - Force async processing (required for >10 URLs)
715
+ * @param options.webhookUrl - HTTPS URL for completion notification (async only)
716
+ * @returns Promise resolving to sync results or async job (when async: true or >10 URLs)
717
+ */
718
+ contents(urls: string[], options?: ContentsOptions): Promise<ContentsResponse | ContentsAsyncJobResponse>;
719
+ /**
720
+ * Get async Contents job status and results
721
+ * @param jobId - Job ID from contents() async response
722
+ * @returns Promise resolving to job status
723
+ */
724
+ getContentsJob(jobId: string): Promise<ContentsJobResponse>;
725
+ /**
726
+ * Wait for async Contents job completion (polls until terminal state)
727
+ * @param jobId - Job ID from contents() async response
728
+ * @param options - Wait configuration (pollInterval, maxWaitTime, onProgress)
729
+ * @returns Promise resolving to final job status with results
663
730
  */
664
- contents(urls: string[], options?: ContentsOptions): Promise<ContentsResponse>;
731
+ waitForJob(jobId: string, options?: ContentsJobWaitOptions): Promise<ContentsJobResponse>;
665
732
  /**
666
733
  * DeepResearch: Create a new research task
667
734
  * @param options.search - Search configuration options
@@ -826,4 +893,4 @@ declare class Valyu {
826
893
  private _datasourcesCategories;
827
894
  }
828
895
 
829
- export { type AIUsage, type AddBatchTasksOptions, type AddBatchTasksResponse, type AlertEmailConfig, type AnswerErrorResponse, type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamChunkType, type AnswerSuccessResponse, type BatchCounts, type BatchPagination, type BatchStatus, type BatchStatusResponse, type BatchTaskCreated, type BatchTaskInput, type BatchTaskListItem, type BatchWaitOptions, type CancelBatchResponse, type ChartDataPoint, type ChartDataSeries, type ChartType, type ContentResponseLength, type ContentResult, type ContentsOptions, type ContentsResponse, type Cost, type CountryCode, type CreateBatchOptions, type CreateBatchResponse, type Datasource, type DatasourceCategory, type DatasourceCategoryId, type DatasourceCoverage, type DatasourceModality, type DatasourcePricing, type DatasourcesCategoriesResponse, type DatasourcesListOptions, type DatasourcesListResponse, type DeepResearchBatch, type DeepResearchCancelResponse, type DeepResearchCreateOptions, type DeepResearchCreateResponse, type DeepResearchDeleteResponse, type DeepResearchGetAssetsOptions, type DeepResearchGetAssetsResponse, type DeepResearchListResponse, type DeepResearchMode, type DeepResearchOutputFormat, type DeepResearchSearchConfig, type DeepResearchSource, type DeepResearchStatus, type DeepResearchStatusResponse, type DeepResearchTaskListItem, type DeepResearchTogglePublicResponse, type DeepResearchUpdateResponse, type DeepResearchUsage, type ExtractEffort, type ExtractionMetadata, type FeedbackResponse, type FeedbackSentiment, type FileAttachment, type ImageMetadata, type ImageType, type ListBatchTasksOptions, type ListBatchTasksResponse, type ListBatchesOptions, type ListBatchesResponse, type ListOptions, type MCPServerConfig, type Progress, type ResponseLength, type SearchMetadata, type SearchOptions, type SearchResponse, type SearchResult, type SearchType, type StreamCallback, Valyu, type WaitOptions };
896
+ export { type AIUsage, type AddBatchTasksOptions, type AddBatchTasksResponse, type AlertEmailConfig, type AnswerErrorResponse, type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamChunkType, type AnswerSuccessResponse, type BatchCounts, type BatchPagination, type BatchStatus, type BatchStatusResponse, type BatchTaskCreated, type BatchTaskInput, type BatchTaskListItem, type BatchWaitOptions, type CancelBatchResponse, type ChartDataPoint, type ChartDataSeries, type ChartType, type ContentResponseLength, type ContentResult, type ContentResultFailed, type ContentResultSuccess, type ContentsAsyncJobResponse, type ContentsJobResponse, type ContentsJobStatus, type ContentsJobWaitOptions, type ContentsOptions, type ContentsResponse, type Cost, type CountryCode, type CreateBatchOptions, type CreateBatchResponse, type Datasource, type DatasourceCategory, type DatasourceCategoryId, type DatasourceCoverage, type DatasourceModality, type DatasourcePricing, type DatasourcesCategoriesResponse, type DatasourcesListOptions, type DatasourcesListResponse, type DeepResearchBatch, type DeepResearchCancelResponse, type DeepResearchCreateOptions, type DeepResearchCreateResponse, type DeepResearchDeleteResponse, type DeepResearchGetAssetsOptions, type DeepResearchGetAssetsResponse, type DeepResearchListResponse, type DeepResearchMode, type DeepResearchOutputFormat, type DeepResearchSearchConfig, type DeepResearchSource, type DeepResearchStatus, type DeepResearchStatusResponse, type DeepResearchTaskListItem, type DeepResearchTogglePublicResponse, type DeepResearchUpdateResponse, type DeepResearchUsage, type ExtractEffort, type ExtractionMetadata, type FeedbackResponse, type FeedbackSentiment, type FileAttachment, type ImageMetadata, type ImageType, type ListBatchTasksOptions, type ListBatchTasksResponse, type ListBatchesOptions, type ListBatchesResponse, type ListOptions, type MCPServerConfig, type Progress, type ResponseLength, type SearchMetadata, type SearchOptions, type SearchResponse, type SearchResult, type SearchType, type StreamCallback, Valyu, type WaitOptions, verifyContentsWebhookSignature };
package/dist/index.d.ts CHANGED
@@ -59,22 +59,65 @@ interface ContentsOptions {
59
59
  responseLength?: ContentResponseLength;
60
60
  maxPriceDollars?: number;
61
61
  screenshot?: boolean;
62
+ async?: boolean;
63
+ webhookUrl?: string;
62
64
  }
63
- interface ContentResult {
65
+ interface ContentResultBase {
64
66
  url: string;
67
+ status: "success" | "failed";
68
+ }
69
+ interface ContentResultSuccess extends ContentResultBase {
70
+ status: "success";
65
71
  title: string;
66
72
  content: string | number;
67
73
  length: number;
68
74
  source: string;
69
- price: number;
75
+ price?: number;
70
76
  description?: string;
71
77
  summary?: string | object;
72
78
  summary_success?: boolean;
73
79
  data_type?: string;
74
80
  image_url?: Record<string, string>;
75
81
  screenshot_url?: string | null;
82
+ source_type?: string;
83
+ publication_date?: string;
76
84
  citation?: string;
77
85
  }
86
+ interface ContentResultFailed extends ContentResultBase {
87
+ status: "failed";
88
+ error: string;
89
+ }
90
+ type ContentResult = ContentResultSuccess | ContentResultFailed;
91
+ type ContentsJobStatus = "pending" | "processing" | "completed" | "partial" | "failed";
92
+ interface ContentsJobWaitOptions {
93
+ pollInterval?: number;
94
+ maxWaitTime?: number;
95
+ onProgress?: (status: ContentsJobResponse) => void;
96
+ }
97
+ interface ContentsJobResponse {
98
+ success: boolean;
99
+ jobId: string;
100
+ status: ContentsJobStatus;
101
+ urlsTotal: number;
102
+ urlsProcessed: number;
103
+ urlsFailed: number;
104
+ createdAt: number;
105
+ updatedAt: number;
106
+ currentBatch?: number;
107
+ totalBatches?: number;
108
+ results?: ContentResult[];
109
+ actualCostDollars?: number;
110
+ error?: string;
111
+ webhookSecret?: string;
112
+ }
113
+ interface ContentsAsyncJobResponse {
114
+ success: boolean;
115
+ jobId: string;
116
+ status: "pending";
117
+ urlsTotal: number;
118
+ webhookSecret?: string;
119
+ txId: string;
120
+ }
78
121
  interface ContentsResponse {
79
122
  success: boolean;
80
123
  error?: string | null;
@@ -576,6 +619,15 @@ interface DatasourcesCategoriesResponse {
576
619
  error?: string;
577
620
  }
578
621
 
622
+ /**
623
+ * Verify webhook signature for Contents API async completion notifications.
624
+ * Use the raw request body (not parsed JSON) as payload.
625
+ * @param payload - Raw request body string
626
+ * @param signature - X-Webhook-Signature header value
627
+ * @param timestamp - X-Webhook-Timestamp header value
628
+ * @param secret - webhookSecret from job creation
629
+ */
630
+ declare function verifyContentsWebhookSignature(payload: string, signature: string, timestamp: string, secret: string): boolean;
579
631
  declare class Valyu {
580
632
  private baseUrl;
581
633
  private headers;
@@ -652,16 +704,31 @@ declare class Valyu {
652
704
  search(query: string, options?: SearchOptions): Promise<SearchResponse>;
653
705
  /**
654
706
  * Extract content from URLs with optional AI processing
655
- * @param urls - Array of URLs to process (max 10)
707
+ * @param urls - Array of URLs to process (max 10 sync, max 50 with async: true)
656
708
  * @param options - Content extraction configuration options
657
709
  * @param options.summary - AI summary configuration: false (raw), true (auto), string (custom), or JSON schema
658
710
  * @param options.extractEffort - Extraction thoroughness: "normal", "high", or "auto"
659
711
  * @param options.responseLength - Content length per URL
660
712
  * @param options.maxPriceDollars - Maximum cost limit in USD
661
713
  * @param options.screenshot - Request page screenshots (default: false)
662
- * @returns Promise resolving to content extraction results
714
+ * @param options.async - Force async processing (required for >10 URLs)
715
+ * @param options.webhookUrl - HTTPS URL for completion notification (async only)
716
+ * @returns Promise resolving to sync results or async job (when async: true or >10 URLs)
717
+ */
718
+ contents(urls: string[], options?: ContentsOptions): Promise<ContentsResponse | ContentsAsyncJobResponse>;
719
+ /**
720
+ * Get async Contents job status and results
721
+ * @param jobId - Job ID from contents() async response
722
+ * @returns Promise resolving to job status
723
+ */
724
+ getContentsJob(jobId: string): Promise<ContentsJobResponse>;
725
+ /**
726
+ * Wait for async Contents job completion (polls until terminal state)
727
+ * @param jobId - Job ID from contents() async response
728
+ * @param options - Wait configuration (pollInterval, maxWaitTime, onProgress)
729
+ * @returns Promise resolving to final job status with results
663
730
  */
664
- contents(urls: string[], options?: ContentsOptions): Promise<ContentsResponse>;
731
+ waitForJob(jobId: string, options?: ContentsJobWaitOptions): Promise<ContentsJobResponse>;
665
732
  /**
666
733
  * DeepResearch: Create a new research task
667
734
  * @param options.search - Search configuration options
@@ -826,4 +893,4 @@ declare class Valyu {
826
893
  private _datasourcesCategories;
827
894
  }
828
895
 
829
- export { type AIUsage, type AddBatchTasksOptions, type AddBatchTasksResponse, type AlertEmailConfig, type AnswerErrorResponse, type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamChunkType, type AnswerSuccessResponse, type BatchCounts, type BatchPagination, type BatchStatus, type BatchStatusResponse, type BatchTaskCreated, type BatchTaskInput, type BatchTaskListItem, type BatchWaitOptions, type CancelBatchResponse, type ChartDataPoint, type ChartDataSeries, type ChartType, type ContentResponseLength, type ContentResult, type ContentsOptions, type ContentsResponse, type Cost, type CountryCode, type CreateBatchOptions, type CreateBatchResponse, type Datasource, type DatasourceCategory, type DatasourceCategoryId, type DatasourceCoverage, type DatasourceModality, type DatasourcePricing, type DatasourcesCategoriesResponse, type DatasourcesListOptions, type DatasourcesListResponse, type DeepResearchBatch, type DeepResearchCancelResponse, type DeepResearchCreateOptions, type DeepResearchCreateResponse, type DeepResearchDeleteResponse, type DeepResearchGetAssetsOptions, type DeepResearchGetAssetsResponse, type DeepResearchListResponse, type DeepResearchMode, type DeepResearchOutputFormat, type DeepResearchSearchConfig, type DeepResearchSource, type DeepResearchStatus, type DeepResearchStatusResponse, type DeepResearchTaskListItem, type DeepResearchTogglePublicResponse, type DeepResearchUpdateResponse, type DeepResearchUsage, type ExtractEffort, type ExtractionMetadata, type FeedbackResponse, type FeedbackSentiment, type FileAttachment, type ImageMetadata, type ImageType, type ListBatchTasksOptions, type ListBatchTasksResponse, type ListBatchesOptions, type ListBatchesResponse, type ListOptions, type MCPServerConfig, type Progress, type ResponseLength, type SearchMetadata, type SearchOptions, type SearchResponse, type SearchResult, type SearchType, type StreamCallback, Valyu, type WaitOptions };
896
+ export { type AIUsage, type AddBatchTasksOptions, type AddBatchTasksResponse, type AlertEmailConfig, type AnswerErrorResponse, type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamChunkType, type AnswerSuccessResponse, type BatchCounts, type BatchPagination, type BatchStatus, type BatchStatusResponse, type BatchTaskCreated, type BatchTaskInput, type BatchTaskListItem, type BatchWaitOptions, type CancelBatchResponse, type ChartDataPoint, type ChartDataSeries, type ChartType, type ContentResponseLength, type ContentResult, type ContentResultFailed, type ContentResultSuccess, type ContentsAsyncJobResponse, type ContentsJobResponse, type ContentsJobStatus, type ContentsJobWaitOptions, type ContentsOptions, type ContentsResponse, type Cost, type CountryCode, type CreateBatchOptions, type CreateBatchResponse, type Datasource, type DatasourceCategory, type DatasourceCategoryId, type DatasourceCoverage, type DatasourceModality, type DatasourcePricing, type DatasourcesCategoriesResponse, type DatasourcesListOptions, type DatasourcesListResponse, type DeepResearchBatch, type DeepResearchCancelResponse, type DeepResearchCreateOptions, type DeepResearchCreateResponse, type DeepResearchDeleteResponse, type DeepResearchGetAssetsOptions, type DeepResearchGetAssetsResponse, type DeepResearchListResponse, type DeepResearchMode, type DeepResearchOutputFormat, type DeepResearchSearchConfig, type DeepResearchSource, type DeepResearchStatus, type DeepResearchStatusResponse, type DeepResearchTaskListItem, type DeepResearchTogglePublicResponse, type DeepResearchUpdateResponse, type DeepResearchUsage, type ExtractEffort, type ExtractionMetadata, type FeedbackResponse, type FeedbackSentiment, type FileAttachment, type ImageMetadata, type ImageType, type ListBatchTasksOptions, type ListBatchTasksResponse, type ListBatchesOptions, type ListBatchesResponse, type ListOptions, type MCPServerConfig, type Progress, type ResponseLength, type SearchMetadata, type SearchOptions, type SearchResponse, type SearchResult, type SearchType, type StreamCallback, Valyu, type WaitOptions, verifyContentsWebhookSignature };
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) {
@@ -351,14 +390,16 @@ var Valyu = class {
351
390
  }
352
391
  /**
353
392
  * Extract content from URLs with optional AI processing
354
- * @param urls - Array of URLs to process (max 10)
393
+ * @param urls - Array of URLs to process (max 10 sync, max 50 with async: true)
355
394
  * @param options - Content extraction configuration options
356
395
  * @param options.summary - AI summary configuration: false (raw), true (auto), string (custom), or JSON schema
357
396
  * @param options.extractEffort - Extraction thoroughness: "normal", "high", or "auto"
358
397
  * @param options.responseLength - Content length per URL
359
398
  * @param options.maxPriceDollars - Maximum cost limit in USD
360
399
  * @param options.screenshot - Request page screenshots (default: false)
361
- * @returns Promise resolving to content extraction results
400
+ * @param options.async - Force async processing (required for >10 URLs)
401
+ * @param options.webhookUrl - HTTPS URL for completion notification (async only)
402
+ * @returns Promise resolving to sync results or async job (when async: true or >10 URLs)
362
403
  */
363
404
  async contents(urls, options = {}) {
364
405
  try {
@@ -386,10 +427,23 @@ var Valyu = class {
386
427
  total_characters: 0
387
428
  };
388
429
  }
389
- if (urls.length > 10) {
430
+ const isAsync = options.async === true || urls.length > 10;
431
+ if (urls.length > 10 && !options.async) {
390
432
  return {
391
433
  success: false,
392
- error: "Maximum 10 URLs allowed per request",
434
+ error: "Requests with more than 10 URLs require async processing. Add async: true to the request.",
435
+ urls_requested: urls.length,
436
+ urls_processed: 0,
437
+ urls_failed: urls.length,
438
+ results: [],
439
+ total_cost_dollars: 0,
440
+ total_characters: 0
441
+ };
442
+ }
443
+ if (urls.length > 50) {
444
+ return {
445
+ success: false,
446
+ error: "Maximum 50 URLs allowed per request",
393
447
  urls_requested: urls.length,
394
448
  urls_processed: 0,
395
449
  urls_failed: urls.length,
@@ -455,6 +509,12 @@ var Valyu = class {
455
509
  if (options.screenshot !== void 0) {
456
510
  payload.screenshot = options.screenshot;
457
511
  }
512
+ if (isAsync) {
513
+ payload.async = true;
514
+ }
515
+ if (options.webhookUrl !== void 0) {
516
+ payload.webhook_url = options.webhookUrl;
517
+ }
458
518
  const response = await import_axios.default.post(`${this.baseUrl}/contents`, payload, {
459
519
  headers: this.headers
460
520
  });
@@ -470,6 +530,9 @@ var Valyu = class {
470
530
  total_characters: 0
471
531
  };
472
532
  }
533
+ if (response.status === 202) {
534
+ return normalizeContentsAsyncJobResponse(response.data);
535
+ }
473
536
  return response.data;
474
537
  } catch (e) {
475
538
  return {
@@ -484,6 +547,61 @@ var Valyu = class {
484
547
  };
485
548
  }
486
549
  }
550
+ /**
551
+ * Get async Contents job status and results
552
+ * @param jobId - Job ID from contents() async response
553
+ * @returns Promise resolving to job status
554
+ */
555
+ async getContentsJob(jobId) {
556
+ try {
557
+ const response = await import_axios.default.get(
558
+ `${this.baseUrl}/contents/jobs/${jobId}`,
559
+ { headers: this.headers }
560
+ );
561
+ return normalizeContentsJobResponse(response.data);
562
+ } catch (e) {
563
+ const errData = e.response?.data;
564
+ const status = e.response?.status;
565
+ return {
566
+ success: false,
567
+ jobId,
568
+ status: "failed",
569
+ urlsTotal: 0,
570
+ urlsProcessed: 0,
571
+ urlsFailed: 0,
572
+ createdAt: 0,
573
+ updatedAt: 0,
574
+ error: errData?.error || (status === 403 ? "Forbidden - you do not have access to this job" : status === 404 ? `Job ${jobId} not found` : e.message)
575
+ };
576
+ }
577
+ }
578
+ /**
579
+ * Wait for async Contents job completion (polls until terminal state)
580
+ * @param jobId - Job ID from contents() async response
581
+ * @param options - Wait configuration (pollInterval, maxWaitTime, onProgress)
582
+ * @returns Promise resolving to final job status with results
583
+ */
584
+ async waitForJob(jobId, options = {}) {
585
+ const pollInterval = options.pollInterval ?? 5e3;
586
+ const maxWaitTime = options.maxWaitTime ?? 72e5;
587
+ const startTime = Date.now();
588
+ while (true) {
589
+ const status = await this.getContentsJob(jobId);
590
+ if (!status.success && status.error) {
591
+ throw new Error(status.error);
592
+ }
593
+ if (options.onProgress) {
594
+ options.onProgress(status);
595
+ }
596
+ if (status.status === "completed" || status.status === "partial" || status.status === "failed") {
597
+ return status;
598
+ }
599
+ if (Date.now() - startTime > maxWaitTime) {
600
+ throw new Error("Maximum wait time exceeded");
601
+ }
602
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
603
+ }
604
+ }
487
605
  /**
488
606
  * DeepResearch: Create a new research task
489
607
  * @param options.search - Search configuration options
@@ -1377,6 +1495,7 @@ var Valyu = class {
1377
1495
  };
1378
1496
  // Annotate the CommonJS export names for ESM import in node:
1379
1497
  0 && (module.exports = {
1380
- Valyu
1498
+ Valyu,
1499
+ verifyContentsWebhookSignature
1381
1500
  });
1382
1501
  //# sourceMappingURL=index.js.map