From 5ae4ba95e69c9423bcc6045572001d4fb4e2d064 Mon Sep 17 00:00:00 2001 From: yorkeccak Date: Mon, 19 Jan 2026 20:43:47 +0000 Subject: [PATCH] Reorganize tools for better categorization and add new tools - Add universal `search` tool as catchall across all sources - Rename `bioSearch` -> `lifeSciencesSearch` with expanded NCBI genomics sources - Rename `paperSearch` -> `academicSearch` for clarity - Add `contents` tool for URL content extraction - Remove economics sources from financeSearch (use economicsSearch instead) - Add backwards-compatible aliases for bioSearch and paperSearch - Bump version to 1.1.0 --- package.json | 2 +- pnpm-lock.yaml | 151 ++++++++++++++++++ src/{paper-search.ts => academic-search.ts} | 22 ++- src/contents.ts | 74 +++++++++ src/finance-search.ts | 5 +- src/index.ts | 19 ++- ...{bio-search.ts => life-sciences-search.ts} | 36 +++-- src/search.ts | 98 ++++++++++++ src/types.ts | 61 +++++-- 9 files changed, 414 insertions(+), 54 deletions(-) create mode 100644 pnpm-lock.yaml rename src/{paper-search.ts => academic-search.ts} (73%) create mode 100644 src/contents.ts rename src/{bio-search.ts => life-sciences-search.ts} (65%) create mode 100644 src/search.ts diff --git a/package.json b/package.json index 93a3ada..a6e1b8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@valyu/ai-sdk", - "version": "1.0.7", + "version": "1.1.0", "description": "Valyu search tools for Vercel AI SDK", "files": [ "dist" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..b2912de --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,151 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + zod: + specifier: ^3.22.0 + version: 3.25.76 + devDependencies: + '@ai-sdk/openai': + specifier: ^2.0.65 + version: 2.0.89(zod@3.25.76) + '@types/node': + specifier: ^20.0.0 + version: 20.19.30 + ai: + specifier: ^5.0.83 + version: 5.0.121(zod@3.25.76) + typescript: + specifier: ^5.0.0 + version: 5.9.3 + +packages: + + '@ai-sdk/gateway@2.0.27': + resolution: {integrity: sha512-8hbezMsGa0crSt7/DKjkYL1UbbJJW/UFxTfhmf5qcIeYeeWG4dTNmm+DWbUdIsTaWvp59KC4eeC9gYXBbTHd7w==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/openai@2.0.89': + resolution: {integrity: sha512-4+qWkBCbL9HPKbgrUO/F2uXZ8GqrYxHa8SWEYIzxEJ9zvWw3ISr3t1/27O1i8MGSym+PzEyHBT48EV4LAwWaEw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@3.0.20': + resolution: {integrity: sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@2.0.1': + resolution: {integrity: sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng==} + engines: {node: '>=18'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@types/node@20.19.30': + resolution: {integrity: sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==} + + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + engines: {node: '>= 20'} + + ai@5.0.121: + resolution: {integrity: sha512-3iYPdARKGLryC/7OA9RgBUaym1gynvWS7UPy8NwoRNCKP52lshldtHB5xcEfVviw7liWH2zJlW9yEzsDglcIEQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + +snapshots: + + '@ai-sdk/gateway@2.0.27(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.1 + '@ai-sdk/provider-utils': 3.0.20(zod@3.25.76) + '@vercel/oidc': 3.1.0 + zod: 3.25.76 + + '@ai-sdk/openai@2.0.89(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.1 + '@ai-sdk/provider-utils': 3.0.20(zod@3.25.76) + zod: 3.25.76 + + '@ai-sdk/provider-utils@3.0.20(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.1 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.6 + zod: 3.25.76 + + '@ai-sdk/provider@2.0.1': + dependencies: + json-schema: 0.4.0 + + '@opentelemetry/api@1.9.0': {} + + '@standard-schema/spec@1.1.0': {} + + '@types/node@20.19.30': + dependencies: + undici-types: 6.21.0 + + '@vercel/oidc@3.1.0': {} + + ai@5.0.121(zod@3.25.76): + dependencies: + '@ai-sdk/gateway': 2.0.27(zod@3.25.76) + '@ai-sdk/provider': 2.0.1 + '@ai-sdk/provider-utils': 3.0.20(zod@3.25.76) + '@opentelemetry/api': 1.9.0 + zod: 3.25.76 + + dotenv@17.2.3: {} + + eventsource-parser@3.0.6: {} + + json-schema@0.4.0: {} + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + zod@3.25.76: {} diff --git a/src/paper-search.ts b/src/academic-search.ts similarity index 73% rename from src/paper-search.ts rename to src/academic-search.ts index 3b8fb5d..539188c 100644 --- a/src/paper-search.ts +++ b/src/academic-search.ts @@ -1,29 +1,29 @@ import { tool } from "ai"; import { z } from "zod"; -import type { ValyuPaperSearchConfig } from "./types.js"; +import type { ValyuAcademicSearchConfig } from "./types.js"; /** - * Creates a research paper search tool powered by Valyu for use with Vercel AI SDK + * Creates an academic paper search tool powered by Valyu for use with Vercel AI SDK * - * @param config - Configuration options for the Valyu paper search + * @param config - Configuration options for the Valyu academic search * @returns A tool that can be used with AI SDK's generateText, streamText, etc. * * @example * ```ts * import { generateText } from "ai"; - * import { paperSearch } from "@valyu/ai-sdk"; + * import { academicSearch } from "@valyu/ai-sdk"; * import { openai } from "@ai-sdk/openai"; * * const { text } = await generateText({ * model: openai('gpt-5'), * prompt: 'Find recent research papers on transformer architectures', * tools: { - * paperSearch: paperSearch({ maxNumResults: 5 }), + * academicSearch: academicSearch({ maxNumResults: 5 }), * }, * }); * ``` */ -export function paperSearch(config: ValyuPaperSearchConfig = {}) { +export function academicSearch(config: ValyuAcademicSearchConfig = {}) { const { apiKey = process.env.VALYU_API_KEY, searchType = "proprietary", @@ -38,16 +38,15 @@ export function paperSearch(config: ValyuPaperSearchConfig = {}) { } = config; return tool({ - description: "Search academic papers from arXiv, PubMed, bioRxiv, and medRxiv. The API handles semantic search - use simple natural language, not keyword stuffing.", + description: "Search academic papers and preprints from arXiv, PubMed, bioRxiv, and medRxiv. Use for research papers across all scientific disciplines.", inputSchema: z.object({ - query: z.string().min(1).max(500).describe("Natural language query (e.g., 'psilocybin effects on lifespan in mice', 'CRISPR cancer therapy trials')"), + query: z.string().min(1).max(500).describe("Natural language query (e.g., 'transformer architectures for protein folding', 'CRISPR gene editing mechanisms')"), }), execute: async ({ query }) => { if (!apiKey) { throw new Error("VALYU_API_KEY is required. Set it in environment variables or pass it in config."); } - // Build the request body for Valyu API const requestBody: any = { query, search_type: searchType, @@ -55,7 +54,6 @@ export function paperSearch(config: ValyuPaperSearchConfig = {}) { included_sources: includedSources, }; - // Add optional parameters if (otherOptions.maxPrice !== undefined) { requestBody.max_price = otherOptions.maxPrice; } @@ -69,7 +67,6 @@ export function paperSearch(config: ValyuPaperSearchConfig = {}) { requestBody.response_length = otherOptions.responseLength; } - // Call Valyu API try { const response = await fetch("https://api.valyu.ai/v1/deepsearch", { method: "POST", @@ -85,12 +82,11 @@ export function paperSearch(config: ValyuPaperSearchConfig = {}) { throw new Error(`Valyu API error: ${response.status} - ${errorText}`); } - // Return the full API response const data = await response.json(); return data; } catch (error) { if (error instanceof Error) { - throw new Error(`Failed to search research papers with Valyu: ${error.message}`); + throw new Error(`Failed to search academic papers with Valyu: ${error.message}`); } throw error; } diff --git a/src/contents.ts b/src/contents.ts new file mode 100644 index 0000000..92fda2c --- /dev/null +++ b/src/contents.ts @@ -0,0 +1,74 @@ +import { tool } from "ai"; +import { z } from "zod"; +import type { ValyuContentsConfig } from "./types.js"; + +/** + * Creates a content extraction tool powered by Valyu for use with Vercel AI SDK + * + * @param config - Configuration options for the Valyu contents extraction + * @returns A tool that can be used with AI SDK's generateText, streamText, etc. + * + * @example + * ```ts + * import { generateText } from "ai"; + * import { contents } from "@valyu/ai-sdk"; + * import { openai } from "@ai-sdk/openai"; + * + * const { text } = await generateText({ + * model: openai('gpt-5'), + * prompt: 'Extract and summarize this article: https://example.com/article', + * tools: { + * contents: contents(), + * }, + * }); + * ``` + */ +export function contents(config: ValyuContentsConfig = {}) { + const { + apiKey = process.env.VALYU_API_KEY, + responseLength = "max", + extractEffort = "auto", + } = config; + + return tool({ + description: "Extract clean, structured content from URLs. Use this to read and process web pages, articles, and documents.", + inputSchema: z.object({ + urls: z.array(z.string().url()).min(1).max(10).describe("Array of URLs to extract content from (1-10 URLs)"), + }), + execute: async ({ urls }) => { + if (!apiKey) { + throw new Error("VALYU_API_KEY is required. Set it in environment variables or pass it in config."); + } + + const requestBody: any = { + urls, + response_length: responseLength, + extract_effort: extractEffort, + }; + + try { + const response = await fetch("https://api.valyu.ai/v1/contents", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-api-key": apiKey, + }, + body: JSON.stringify(requestBody), + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Valyu API error: ${response.status} - ${errorText}`); + } + + const data = await response.json(); + return data; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to extract content with Valyu: ${error.message}`); + } + throw error; + } + }, + }); +} diff --git a/src/finance-search.ts b/src/finance-search.ts index 529702f..8edf5e4 100644 --- a/src/finance-search.ts +++ b/src/finance-search.ts @@ -40,15 +40,12 @@ export function financeSearch(config: ValyuFinanceSearchConfig = {}) { "valyu/valyu-market-movers-US", "valyu/valyu-crypto", "valyu/valyu-forex", - "valyu/valyu-bls", - "valyu/valyu-fred", - "valyu/valyu-world-bank", ], ...otherOptions } = config; return tool({ - description: "Search financial data: stock prices, earnings, balance sheets, income statements, cash flows, SEC filings, dividends, insider transactions, crypto, forex, and economic indicators. The API handles natural language - ask your full question in one query per topic.", + description: "Search financial data: stock prices, earnings, balance sheets, income statements, cash flows, SEC filings, dividends, insider transactions, crypto, and forex. Use economicsSearch for BLS, FRED, and World Bank data.", inputSchema: z.object({ query: z.string().min(1).max(500).describe("Natural language query (e.g., 'Apple stock price Q1-Q3 2020', 'Tesla revenue last 4 quarters')"), }), diff --git a/src/index.ts b/src/index.ts index af5c0e9..57a4eed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,18 @@ // Export all search tools +export { search } from "./search.js"; export { webSearch } from "./web-search.js"; export { financeSearch } from "./finance-search.js"; -export { paperSearch } from "./paper-search.js"; -export { bioSearch } from "./bio-search.js"; +export { academicSearch } from "./academic-search.js"; +export { lifeSciencesSearch } from "./life-sciences-search.js"; export { patentSearch } from "./patent-search.js"; export { secSearch } from "./sec-search.js"; export { economicsSearch } from "./economics-search.js"; export { companyResearch } from "./company-research.js"; +export { contents } from "./contents.js"; + +// Backwards-compatible aliases (deprecated) +export { lifeSciencesSearch as bioSearch } from "./life-sciences-search.js"; +export { academicSearch as paperSearch } from "./academic-search.js"; // Export datasources discovery tools export { datasources, datasourcesCategories } from "./datasources.js"; @@ -14,14 +20,16 @@ export { datasources, datasourcesCategories } from "./datasources.js"; // Export all types export type { ValyuBaseConfig, + ValyuSearchConfig, ValyuWebSearchConfig, ValyuFinanceSearchConfig, - ValyuPaperSearchConfig, - ValyuBioSearchConfig, + ValyuAcademicSearchConfig, + ValyuLifeSciencesSearchConfig, ValyuPatentSearchConfig, ValyuSecSearchConfig, ValyuEconomicsSearchConfig, ValyuCompanyResearchConfig, + ValyuContentsConfig, ValyuSearchResult, ValyuApiResponse, ValyuResultsBySource, @@ -29,5 +37,8 @@ export type { ValyuDataType, ValyuResponseLength, ValyuResponseLengthPreset, + // Backwards-compatible type aliases (deprecated) + ValyuLifeSciencesSearchConfig as ValyuBioSearchConfig, + ValyuAcademicSearchConfig as ValyuPaperSearchConfig, } from "./types.js"; export type { ValyuDatasourcesConfig } from "./datasources.js"; diff --git a/src/bio-search.ts b/src/life-sciences-search.ts similarity index 65% rename from src/bio-search.ts rename to src/life-sciences-search.ts index 7c8d1c6..cef058d 100644 --- a/src/bio-search.ts +++ b/src/life-sciences-search.ts @@ -1,60 +1,65 @@ import { tool } from "ai"; import { z } from "zod"; -import type { ValyuBioSearchConfig } from "./types.js"; +import type { ValyuLifeSciencesSearchConfig } from "./types.js"; /** - * Creates a biomedical search tool powered by Valyu for use with Vercel AI SDK + * Creates a life sciences search tool powered by Valyu for use with Vercel AI SDK * - * @param config - Configuration options for the Valyu biomedical search + * @param config - Configuration options for the Valyu life sciences search * @returns A tool that can be used with AI SDK's generateText, streamText, etc. * * @example * ```ts * import { generateText } from "ai"; - * import { bioSearch } from "@valyu/ai-sdk"; + * import { lifeSciencesSearch } from "@valyu/ai-sdk"; * import { openai } from "@ai-sdk/openai"; * * const { text } = await generateText({ * model: openai('gpt-5'), - * prompt: 'Find clinical trials for cancer immunotherapy', + * prompt: 'Find clinical trials for GLP-1 agonists in obesity', * tools: { - * bioSearch: bioSearch({ maxNumResults: 5 }), + * lifeSciencesSearch: lifeSciencesSearch({ maxNumResults: 5 }), * }, * }); * ``` */ -export function bioSearch(config: ValyuBioSearchConfig = {}) { +export function lifeSciencesSearch(config: ValyuLifeSciencesSearchConfig = {}) { const { apiKey = process.env.VALYU_API_KEY, searchType = "proprietary", maxNumResults = 5, includedSources = [ - "valyu/valyu-pubmed", - "valyu/valyu-biorxiv", - "valyu/valyu-medrxiv", + // Clinical and regulatory "valyu/valyu-clinical-trials", "valyu/valyu-drug-labels", + // Pharmaceutical databases "valyu/valyu-chembl", "valyu/valyu-pubchem", "valyu/valyu-drugbank", "valyu/valyu-open-targets", + // Healthcare "valyu/valyu-npi-registry", "valyu/valyu-who-icd", + // Genomics (NCBI) + "valyu/valyu-ncbi-gene", + "valyu/valyu-ncbi-snp", + "valyu/valyu-ncbi-clinvar", + "valyu/valyu-ncbi-geo", + "valyu/valyu-ncbi-sra", ], ...otherOptions } = config; return tool({ - description: "Search biomedical and healthcare data including PubMed, clinical trials, FDA drug labels, ChEMBL compounds, PubChem, DrugBank, Open Targets, NPI registry, and WHO ICD codes. The API handles natural language - use simple queries.", + description: "Search life sciences databases including clinical trials, drug data (ChEMBL, DrugBank, PubChem), FDA labels, genomics (NCBI Gene, SNP, ClinVar, GEO, SRA), and healthcare data (NPI registry, WHO ICD codes). Use for biomedical research, drug discovery, and genomics queries.", inputSchema: z.object({ - query: z.string().min(1).max(500).describe("Natural language query (e.g., 'GLP-1 agonists for weight loss', 'Phase 3 melanoma immunotherapy trials')"), + query: z.string().min(1).max(500).describe("Natural language query (e.g., 'BRCA1 mutations in breast cancer', 'Phase 3 melanoma immunotherapy trials', 'GLP-1 agonist mechanisms')"), }), execute: async ({ query }) => { if (!apiKey) { throw new Error("VALYU_API_KEY is required. Set it in environment variables or pass it in config."); } - // Build request body for Valyu API const requestBody: any = { query, search_type: searchType, @@ -62,7 +67,6 @@ export function bioSearch(config: ValyuBioSearchConfig = {}) { included_sources: includedSources, }; - // Add optional parameters if (otherOptions.maxPrice !== undefined) { requestBody.max_price = otherOptions.maxPrice; } @@ -76,7 +80,6 @@ export function bioSearch(config: ValyuBioSearchConfig = {}) { requestBody.response_length = otherOptions.responseLength; } - // Call Valyu API try { const response = await fetch("https://api.valyu.ai/v1/deepsearch", { method: "POST", @@ -92,12 +95,11 @@ export function bioSearch(config: ValyuBioSearchConfig = {}) { throw new Error(`Valyu API error: ${response.status} - ${errorText}`); } - // Return the full API response const data = await response.json(); return data; } catch (error) { if (error instanceof Error) { - throw new Error(`Failed to search biomedical data with Valyu: ${error.message}`); + throw new Error(`Failed to search life sciences data with Valyu: ${error.message}`); } throw error; } diff --git a/src/search.ts b/src/search.ts new file mode 100644 index 0000000..5fe7d5a --- /dev/null +++ b/src/search.ts @@ -0,0 +1,98 @@ +import { tool } from "ai"; +import { z } from "zod"; +import type { ValyuSearchConfig } from "./types.js"; + +/** + * Creates a universal search tool powered by Valyu for use with Vercel AI SDK + * + * @param config - Configuration options for Valyu search + * @returns A tool that can be used with AI SDK's generateText, streamText, etc. + * + * @example + * ```ts + * import { generateText } from "ai"; + * import { search } from "@valyu/ai-sdk"; + * import { openai } from "@ai-sdk/openai"; + * + * const { text } = await generateText({ + * model: openai('gpt-5'), + * prompt: 'What happened in San Francisco last week?', + * tools: { + * search: search({ maxNumResults: 5 }), + * }, + * }); + * ``` + */ +export function search(config: ValyuSearchConfig = {}) { + const { + apiKey = process.env.VALYU_API_KEY, + searchType = "all", + maxNumResults = 5, + ...otherOptions + } = config; + + return tool({ + description: "Search across all Valyu sources including web, academic papers, financial data, and proprietary datasets. Use this as a general-purpose search when you need broad coverage.", + inputSchema: z.object({ + query: z.string().min(1).max(500).describe("Natural language query"), + includedSources: z.array(z.string()).optional().describe("Restrict search to specific domains or sources (e.g., ['nature.com', 'arxiv.org']). Cannot be used with excludedSources."), + excludedSources: z.array(z.string()).optional().describe("Exclude specific domains or sources from results (e.g., ['reddit.com', 'quora.com']). Cannot be used with includedSources."), + }), + execute: async ({ query, includedSources, excludedSources }) => { + if (!apiKey) { + throw new Error("VALYU_API_KEY is required. Set it in environment variables or pass it in config."); + } + + const requestBody: any = { + query, + search_type: searchType, + max_num_results: maxNumResults, + }; + + if (otherOptions.maxPrice !== undefined) { + requestBody.max_price = otherOptions.maxPrice; + } + if (otherOptions.relevanceThreshold !== undefined) { + requestBody.relevance_threshold = otherOptions.relevanceThreshold; + } + if (otherOptions.category) { + requestBody.category = otherOptions.category; + } + if (otherOptions.responseLength !== undefined) { + requestBody.response_length = otherOptions.responseLength; + } + if (includedSources && includedSources.length > 0) { + requestBody.included_sources = includedSources; + } else if (otherOptions.includedSources && otherOptions.includedSources.length > 0) { + requestBody.included_sources = otherOptions.includedSources; + } + if (excludedSources && excludedSources.length > 0) { + requestBody.excluded_sources = excludedSources; + } + + try { + const response = await fetch("https://api.valyu.ai/v1/deepsearch", { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-api-key": apiKey, + }, + body: JSON.stringify(requestBody), + }); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Valyu API error: ${response.status} - ${errorText}`); + } + + const data = await response.json(); + return data; + } catch (error) { + if (error instanceof Error) { + throw new Error(`Failed to search with Valyu: ${error.message}`); + } + throw error; + } + }, + }); +} diff --git a/src/types.ts b/src/types.ts index 4343b53..40c13e9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,8 +26,9 @@ export interface ValyuBaseConfig { * Search type (default: "proprietary") * - proprietary: Access premium sources including academic papers, financial data, etc. * - web: Standard web search + * - all: Search across all sources */ - searchType?: "proprietary" | "web"; + searchType?: "proprietary" | "web" | "all"; /** * Maximum number of results to return (default: 10) @@ -61,12 +62,27 @@ export interface ValyuBaseConfig { responseLength?: ValyuResponseLength; } +/** + * Configuration for universal search tool + */ +export interface ValyuSearchConfig extends ValyuBaseConfig { + /** + * List of specific sources to include + */ + includedSources?: string[]; + + /** + * Category to focus the search on + */ + category?: string; +} + /** * Configuration for web search tool */ export interface ValyuWebSearchConfig extends ValyuBaseConfig { /** - * List of specific sources to include (e.g., ["valyu/web-general"]) + * List of specific sources to include */ includedSources?: string[]; @@ -82,7 +98,6 @@ export interface ValyuWebSearchConfig extends ValyuBaseConfig { export interface ValyuFinanceSearchConfig extends ValyuBaseConfig { /** * List of financial sources to include - * Examples: ["valyu/financial-reports", "valyu/market-data"] */ includedSources?: string[]; @@ -93,12 +108,11 @@ export interface ValyuFinanceSearchConfig extends ValyuBaseConfig { } /** - * Configuration for research paper search tool + * Configuration for academic paper search tool */ -export interface ValyuPaperSearchConfig extends ValyuBaseConfig { +export interface ValyuAcademicSearchConfig extends ValyuBaseConfig { /** * List of academic sources to include - * Examples: ["valyu/valyu-arxiv", "valyu/academic-journals"] */ includedSources?: string[]; @@ -109,17 +123,16 @@ export interface ValyuPaperSearchConfig extends ValyuBaseConfig { } /** - * Configuration for biomedical search tool + * Configuration for life sciences search tool */ -export interface ValyuBioSearchConfig extends ValyuBaseConfig { +export interface ValyuLifeSciencesSearchConfig extends ValyuBaseConfig { /** - * List of biomedical sources to include - * Examples: ["valyu/valyu-pubmed", "valyu/clinical-trials", "valyu/fda-labels"] + * List of life sciences sources to include */ includedSources?: string[]; /** - * Category to focus on (e.g., "clinical-trials", "drug-labels", "medical-research") + * Category to focus on (e.g., "clinical-trials", "genomics", "drug-discovery") */ category?: string; } @@ -130,7 +143,6 @@ export interface ValyuBioSearchConfig extends ValyuBaseConfig { export interface ValyuPatentSearchConfig extends ValyuBaseConfig { /** * List of patent sources to include - * Examples: ["valyu/patents-us", "valyu/patents-international"] */ includedSources?: string[]; @@ -141,12 +153,11 @@ export interface ValyuPatentSearchConfig extends ValyuBaseConfig { } /** - * Configuration for SEC filings search tool + * Configuration for SEC search tool */ export interface ValyuSecSearchConfig extends ValyuBaseConfig { /** * List of SEC filing sources to include - * Examples: ["valyu/valyu-sec-filings"] */ includedSources?: string[]; @@ -162,7 +173,6 @@ export interface ValyuSecSearchConfig extends ValyuBaseConfig { export interface ValyuEconomicsSearchConfig extends ValyuBaseConfig { /** * List of economics sources to include - * Examples: ["valyu/valyu-bls", "valyu/valyu-fred", "valyu/valyu-world-bank"] */ includedSources?: string[]; @@ -189,6 +199,27 @@ export interface ValyuCompanyResearchConfig { dataMaxPrice?: number; } +/** + * Configuration for contents extraction tool + */ +export interface ValyuContentsConfig { + /** + * Your Valyu API key. Get one at https://platform.valyu.ai + * Defaults to process.env.VALYU_API_KEY + */ + apiKey?: string; + + /** + * Response length preset (default: "max") + */ + responseLength?: ValyuResponseLengthPreset; + + /** + * Extraction effort level (default: "auto") + */ + extractEffort?: "auto" | "low" | "medium" | "high"; +} + /** * Source type for search results */