valyu-js 2.8.0 → 2.9.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/dist/index.mjs CHANGED
@@ -3,7 +3,8 @@ import { createHmac, timingSafeEqual } from "crypto";
3
3
  import http from "http";
4
4
  import https from "https";
5
5
  import axios from "axios";
6
- var SDK_VERSION = "2.8.0";
6
+ var SDK_VERSION = "2.9.0";
7
+ var TRANSIENT_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
7
8
  function normalizeContentsJobResponse(api) {
8
9
  return {
9
10
  success: api.success ?? true,
@@ -788,19 +789,49 @@ var Valyu = class {
788
789
  /**
789
790
  * DeepResearch: Get task status
790
791
  */
791
- async _deepresearchStatus(taskId) {
792
- try {
793
- const response = await this.client.get(
794
- `${this.baseUrl}/deepresearch/tasks/${taskId}/status`,
795
- { headers: this.headers }
796
- );
797
- return { success: true, ...response.data };
798
- } catch (e) {
799
- return {
800
- success: false,
801
- error: e.response?.data?.error || e.message
802
- };
792
+ async _deepresearchStatus(taskId, maxAttempts = 5) {
793
+ const url = `${this.baseUrl}/deepresearch/tasks/${taskId}/status`;
794
+ let lastError = "status endpoint unreachable";
795
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
796
+ try {
797
+ const response = await this.client.get(url, {
798
+ headers: this.headers,
799
+ // Classify status codes ourselves rather than letting axios throw.
800
+ validateStatus: () => true
801
+ });
802
+ if (TRANSIENT_STATUS_CODES.has(response.status)) {
803
+ lastError = `HTTP ${response.status}`;
804
+ } else {
805
+ const contentType = String(
806
+ response.headers?.["content-type"] || ""
807
+ );
808
+ const body = response.data;
809
+ const isJsonObject = contentType.toLowerCase().includes("application/json") && typeof body === "object" && body !== null && !Array.isArray(body);
810
+ if (!isJsonObject) {
811
+ lastError = `non-JSON/empty status response (HTTP ${response.status}, content-type: ${contentType || "none"})`;
812
+ } else if (response.status >= 400) {
813
+ return {
814
+ success: false,
815
+ error: body.error || `HTTP Error: ${response.status}`
816
+ };
817
+ } else {
818
+ const { success: _ignored, ...rest } = body;
819
+ return { success: true, ...rest };
820
+ }
821
+ }
822
+ } catch (e) {
823
+ lastError = e?.message || String(e);
824
+ }
825
+ if (attempt < maxAttempts - 1) {
826
+ const delayMs = Math.min(2 ** attempt, 30) * 1e3 + Math.random() * 1e3;
827
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
828
+ }
803
829
  }
830
+ return {
831
+ success: false,
832
+ unreachable: true,
833
+ error: `Status endpoint unreachable after ${maxAttempts} attempts: ${lastError}`
834
+ };
804
835
  }
805
836
  /**
806
837
  * DeepResearch: Wait for task completion with polling
@@ -812,6 +843,15 @@ var Valyu = class {
812
843
  while (true) {
813
844
  const status = await this._deepresearchStatus(taskId);
814
845
  if (!status.success) {
846
+ if (status.unreachable) {
847
+ if (Date.now() - startTime > maxWaitTime) {
848
+ throw new Error(
849
+ `Status endpoint unreachable for ${maxWaitTime}ms: ${status.error}`
850
+ );
851
+ }
852
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
853
+ continue;
854
+ }
815
855
  throw new Error(status.error);
816
856
  }
817
857
  if (options.onProgress) {