valyu-js 2.7.18 → 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.js CHANGED
@@ -38,7 +38,8 @@ var import_crypto = require("crypto");
38
38
  var import_http = __toESM(require("http"));
39
39
  var import_https = __toESM(require("https"));
40
40
  var import_axios = __toESM(require("axios"));
41
- var SDK_VERSION = "2.7.17";
41
+ var SDK_VERSION = "2.9.0";
42
+ var TRANSIENT_STATUS_CODES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
42
43
  function normalizeContentsJobResponse(api) {
43
44
  return {
44
45
  success: api.success ?? true,
@@ -129,6 +130,15 @@ var Valyu = class {
129
130
  list: this._datasourcesList.bind(this),
130
131
  categories: this._datasourcesCategories.bind(this)
131
132
  };
133
+ this.workflows = {
134
+ list: this._workflowsList.bind(this),
135
+ get: this._workflowsGet.bind(this),
136
+ versions: this._workflowsVersions.bind(this),
137
+ preview: this._workflowsPreview.bind(this),
138
+ create: this._workflowsCreate.bind(this),
139
+ update: this._workflowsUpdate.bind(this),
140
+ delete: this._workflowsDelete.bind(this)
141
+ };
132
142
  }
133
143
  /**
134
144
  * Validates date format (YYYY-MM-DD)
@@ -656,6 +666,41 @@ var Valyu = class {
656
666
  async _deepresearchCreate(options) {
657
667
  try {
658
668
  const queryValue = options.query ?? options.input;
669
+ if (options.workflowId) {
670
+ if (queryValue || options.strategy || options.researchStrategy || options.reportFormat) {
671
+ return {
672
+ success: false,
673
+ error: "workflowId is mutually exclusive with query/input/researchStrategy/reportFormat - the workflow template supplies those fields"
674
+ };
675
+ }
676
+ const payload2 = {
677
+ workflow_id: options.workflowId
678
+ };
679
+ if (options.workflowParams !== void 0) {
680
+ payload2.workflow_params = options.workflowParams;
681
+ }
682
+ if (options.workflowVersion !== void 0) {
683
+ payload2.workflow_version = options.workflowVersion;
684
+ }
685
+ const explicitMode = options.mode ?? options.model;
686
+ if (explicitMode) payload2.mode = explicitMode;
687
+ if (options.outputFormats) payload2.output_formats = options.outputFormats;
688
+ if (options.tools) payload2.tools = options.tools;
689
+ if (options.webhookUrl) payload2.webhook_url = options.webhookUrl;
690
+ if (options.alertEmail) {
691
+ payload2.alert_email = typeof options.alertEmail === "string" ? options.alertEmail : {
692
+ email: options.alertEmail.email,
693
+ custom_url: options.alertEmail.custom_url
694
+ };
695
+ }
696
+ if (options.metadata) payload2.metadata = options.metadata;
697
+ const response2 = await this.client.post(
698
+ `${this.baseUrl}/deepresearch/tasks`,
699
+ payload2,
700
+ { headers: this.headers }
701
+ );
702
+ return { success: true, ...response2.data };
703
+ }
659
704
  if (!queryValue?.trim()) {
660
705
  return {
661
706
  success: false,
@@ -779,19 +824,49 @@ var Valyu = class {
779
824
  /**
780
825
  * DeepResearch: Get task status
781
826
  */
782
- async _deepresearchStatus(taskId) {
783
- try {
784
- const response = await this.client.get(
785
- `${this.baseUrl}/deepresearch/tasks/${taskId}/status`,
786
- { headers: this.headers }
787
- );
788
- return { success: true, ...response.data };
789
- } catch (e) {
790
- return {
791
- success: false,
792
- error: e.response?.data?.error || e.message
793
- };
827
+ async _deepresearchStatus(taskId, maxAttempts = 5) {
828
+ const url = `${this.baseUrl}/deepresearch/tasks/${taskId}/status`;
829
+ let lastError = "status endpoint unreachable";
830
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
831
+ try {
832
+ const response = await this.client.get(url, {
833
+ headers: this.headers,
834
+ // Classify status codes ourselves rather than letting axios throw.
835
+ validateStatus: () => true
836
+ });
837
+ if (TRANSIENT_STATUS_CODES.has(response.status)) {
838
+ lastError = `HTTP ${response.status}`;
839
+ } else {
840
+ const contentType = String(
841
+ response.headers?.["content-type"] || ""
842
+ );
843
+ const body = response.data;
844
+ const isJsonObject = contentType.toLowerCase().includes("application/json") && typeof body === "object" && body !== null && !Array.isArray(body);
845
+ if (!isJsonObject) {
846
+ lastError = `non-JSON/empty status response (HTTP ${response.status}, content-type: ${contentType || "none"})`;
847
+ } else if (response.status >= 400) {
848
+ return {
849
+ success: false,
850
+ error: body.error || `HTTP Error: ${response.status}`
851
+ };
852
+ } else {
853
+ const { success: _ignored, ...rest } = body;
854
+ return { success: true, ...rest };
855
+ }
856
+ }
857
+ } catch (e) {
858
+ lastError = e?.message || String(e);
859
+ }
860
+ if (attempt < maxAttempts - 1) {
861
+ const delayMs = Math.min(2 ** attempt, 30) * 1e3 + Math.random() * 1e3;
862
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
863
+ }
794
864
  }
865
+ return {
866
+ success: false,
867
+ unreachable: true,
868
+ error: `Status endpoint unreachable after ${maxAttempts} attempts: ${lastError}`
869
+ };
795
870
  }
796
871
  /**
797
872
  * DeepResearch: Wait for task completion with polling
@@ -803,6 +878,15 @@ var Valyu = class {
803
878
  while (true) {
804
879
  const status = await this._deepresearchStatus(taskId);
805
880
  if (!status.success) {
881
+ if (status.unreachable) {
882
+ if (Date.now() - startTime > maxWaitTime) {
883
+ throw new Error(
884
+ `Status endpoint unreachable for ${maxWaitTime}ms: ${status.error}`
885
+ );
886
+ }
887
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
888
+ continue;
889
+ }
806
890
  throw new Error(status.error);
807
891
  }
808
892
  if (options.onProgress) {
@@ -1674,6 +1758,160 @@ var Valyu = class {
1674
1758
  };
1675
1759
  }
1676
1760
  }
1761
+ /** Extract the most descriptive error message from a Workflows API error. */
1762
+ workflowError(e) {
1763
+ return e.response?.data?.message || e.response?.data?.error || e.message;
1764
+ }
1765
+ /**
1766
+ * Workflows: List workflows available to your org
1767
+ * @param options - Filters: vertical, scope ("valyu" | "org" | "all"), q, tags, limit, expand
1768
+ */
1769
+ async _workflowsList(options = {}) {
1770
+ try {
1771
+ const params = new URLSearchParams();
1772
+ if (options.vertical) params.append("vertical", options.vertical);
1773
+ if (options.scope) params.append("scope", options.scope);
1774
+ if (options.q) params.append("q", options.q);
1775
+ if (options.tags?.length) params.append("tags", options.tags.join(","));
1776
+ if (options.limit !== void 0) {
1777
+ params.append("limit", String(options.limit));
1778
+ }
1779
+ if (options.expand) params.append("expand", "true");
1780
+ const url = `${this.baseUrl}/workflows${params.toString() ? `?${params.toString()}` : ""}`;
1781
+ const response = await this.client.get(url, { headers: this.headers });
1782
+ return { success: true, ...response.data };
1783
+ } catch (e) {
1784
+ return { success: false, error: this.workflowError(e) };
1785
+ }
1786
+ }
1787
+ /**
1788
+ * Workflows: Get a workflow's full detail, including its template
1789
+ * @param slug - Workflow slug
1790
+ * @param version - Specific version to fetch (defaults to the current version)
1791
+ */
1792
+ async _workflowsGet(slug, version) {
1793
+ try {
1794
+ const url = `${this.baseUrl}/workflows/${encodeURIComponent(slug)}${version !== void 0 ? `?version=${version}` : ""}`;
1795
+ const response = await this.client.get(url, { headers: this.headers });
1796
+ return { success: true, workflow: response.data };
1797
+ } catch (e) {
1798
+ return { success: false, error: this.workflowError(e) };
1799
+ }
1800
+ }
1801
+ /**
1802
+ * Workflows: List a workflow's version history
1803
+ * @param slug - Workflow slug
1804
+ */
1805
+ async _workflowsVersions(slug) {
1806
+ try {
1807
+ const response = await this.client.get(
1808
+ `${this.baseUrl}/workflows/${encodeURIComponent(slug)}/versions`,
1809
+ { headers: this.headers }
1810
+ );
1811
+ return { success: true, ...response.data };
1812
+ } catch (e) {
1813
+ return { success: false, error: this.workflowError(e) };
1814
+ }
1815
+ }
1816
+ /**
1817
+ * Workflows: Resolve a workflow's template with params without creating a task
1818
+ * @param slug - Workflow slug
1819
+ * @param options - workflowParams (variable values) and optional workflowVersion
1820
+ */
1821
+ async _workflowsPreview(slug, options = {}) {
1822
+ try {
1823
+ const payload = {};
1824
+ if (options.workflowParams !== void 0) {
1825
+ payload.workflow_params = options.workflowParams;
1826
+ }
1827
+ if (options.workflowVersion !== void 0) {
1828
+ payload.workflow_version = options.workflowVersion;
1829
+ }
1830
+ const response = await this.client.post(
1831
+ `${this.baseUrl}/workflows/${encodeURIComponent(slug)}/preview`,
1832
+ payload,
1833
+ { headers: this.headers }
1834
+ );
1835
+ return { success: true, ...response.data };
1836
+ } catch (e) {
1837
+ return { success: false, error: this.workflowError(e) };
1838
+ }
1839
+ }
1840
+ /**
1841
+ * Workflows: Create a new workflow for your org
1842
+ * @param options - slug, title, version (template body), and optional metadata
1843
+ */
1844
+ async _workflowsCreate(options) {
1845
+ try {
1846
+ const payload = {
1847
+ slug: options.slug,
1848
+ title: options.title,
1849
+ version: options.version
1850
+ };
1851
+ if (options.subtitle !== void 0) payload.subtitle = options.subtitle;
1852
+ if (options.description !== void 0) {
1853
+ payload.description = options.description;
1854
+ }
1855
+ if (options.vertical !== void 0) payload.vertical = options.vertical;
1856
+ if (options.tags !== void 0) payload.tags = options.tags;
1857
+ if (options.icon !== void 0) payload.icon = options.icon;
1858
+ const response = await this.client.post(
1859
+ `${this.baseUrl}/workflows`,
1860
+ payload,
1861
+ { headers: this.headers }
1862
+ );
1863
+ return { success: true, workflow: response.data };
1864
+ } catch (e) {
1865
+ return { success: false, error: this.workflowError(e) };
1866
+ }
1867
+ }
1868
+ /**
1869
+ * Workflows: Update a workflow's metadata and/or publish a new template version.
1870
+ * Only workflows owned by your org can be updated; versions are append-only
1871
+ * (a version body requires a changelog).
1872
+ * @param slug - Workflow slug
1873
+ * @param options - Metadata fields and/or a new version body
1874
+ */
1875
+ async _workflowsUpdate(slug, options) {
1876
+ try {
1877
+ const payload = {};
1878
+ if (options.title !== void 0) payload.title = options.title;
1879
+ if (options.subtitle !== void 0) payload.subtitle = options.subtitle;
1880
+ if (options.description !== void 0) {
1881
+ payload.description = options.description;
1882
+ }
1883
+ if (options.vertical !== void 0) payload.vertical = options.vertical;
1884
+ if (options.tags !== void 0) payload.tags = options.tags;
1885
+ if (options.icon !== void 0) payload.icon = options.icon;
1886
+ if (options.version !== void 0) payload.version = options.version;
1887
+ if (options.setCurrent !== void 0) {
1888
+ payload.set_current = options.setCurrent;
1889
+ }
1890
+ const response = await this.client.patch(
1891
+ `${this.baseUrl}/workflows/${encodeURIComponent(slug)}`,
1892
+ payload,
1893
+ { headers: this.headers }
1894
+ );
1895
+ return { success: true, workflow: response.data };
1896
+ } catch (e) {
1897
+ return { success: false, error: this.workflowError(e) };
1898
+ }
1899
+ }
1900
+ /**
1901
+ * Workflows: Delete a workflow owned by your org (soft delete)
1902
+ * @param slug - Workflow slug
1903
+ */
1904
+ async _workflowsDelete(slug) {
1905
+ try {
1906
+ const response = await this.client.delete(
1907
+ `${this.baseUrl}/workflows/${encodeURIComponent(slug)}`,
1908
+ { headers: this.headers }
1909
+ );
1910
+ return { success: true, ...response.data };
1911
+ } catch (e) {
1912
+ return { success: false, error: this.workflowError(e) };
1913
+ }
1914
+ }
1677
1915
  };
1678
1916
  // Annotate the CommonJS export names for ESM import in node:
1679
1917
  0 && (module.exports = {