exa-js 1.4.5 → 1.4.6
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 +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ const response = await exa.answer('What is the population of New York City?', {
|
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### Streaming Responses
|
|
131
|
-
The answer endpoint supports streaming responses, where the answer is returned in chunks as it's being generated. This is useful
|
|
131
|
+
The answer endpoint supports streaming responses, where the answer is returned in chunks as it's being generated. This is useful if you'd like to provide users with tokens as they are generated.
|
|
132
132
|
|
|
133
133
|
```javascript
|
|
134
134
|
await exa.answer(
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,8 @@ __export(src_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(src_exports);
|
|
36
36
|
var import_cross_fetch = __toESM(require("cross-fetch"));
|
|
37
|
+
var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : import_cross_fetch.default;
|
|
38
|
+
var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : import_cross_fetch.Headers;
|
|
37
39
|
var Exa = class {
|
|
38
40
|
extractContentsOptions(options) {
|
|
39
41
|
const {
|
|
@@ -86,7 +88,7 @@ var Exa = class {
|
|
|
86
88
|
);
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
|
-
this.headers = new
|
|
91
|
+
this.headers = new HeadersImpl({
|
|
90
92
|
"x-api-key": apiKey,
|
|
91
93
|
"Content-Type": "application/json",
|
|
92
94
|
"User-Agent": "exa-node 1.4.0"
|
|
@@ -102,7 +104,7 @@ var Exa = class {
|
|
|
102
104
|
* @returns {Promise<any>} The response from the API.
|
|
103
105
|
*/
|
|
104
106
|
async request(endpoint, method, body, stream, onChunk) {
|
|
105
|
-
const response = await (
|
|
107
|
+
const response = await fetchImpl(this.baseURL + endpoint, {
|
|
106
108
|
method,
|
|
107
109
|
headers: this.headers,
|
|
108
110
|
body: body ? JSON.stringify(body) : void 0
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fetch, { Headers } from \"cross-fetch\";\n\nconst isBeta = false;\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} SearchOptions\n * @property {number} [numResults] - Number of search results to return. Default 10. Max 10 for basic plans.\n * @property {string[]} [includeDomains] - List of domains to include in the search.\n * @property {string[]} [excludeDomains] - List of domains to exclude in the search.\n * @property {string} [startCrawlDate] - Start date for results based on crawl date.\n * @property {string} [endCrawlDate] - End date for results based on crawl date.\n * @property {string} [startPublishedDate] - Start date for results based on published date.\n * @property {string} [endPublishedDate] - End date for results based on published date.\n * @property {string} [category] - A data category to focus on, with higher comprehensivity and data cleanliness. Currently, the only category is company.\n * @property {string[]} [includeText] - List of strings that must be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [excludeText] - List of strings that must not be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [flags] - Experimental flags\n */\nexport type BaseSearchOptions = {\n numResults?: number;\n includeDomains?: string[];\n excludeDomains?: string[];\n startCrawlDate?: string;\n endCrawlDate?: string;\n startPublishedDate?: string;\n endPublishedDate?: string;\n category?: \"company\" | \"research paper\" | \"news\" | \"pdf\" | \"github\" | \"tweet\" | \"personal site\" | \"linkedin profile\" | \"financial report\";\n includeText?: string[];\n excludeText?: string[];\n flags?: string[];\n};\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} RegularSearchOptions\n */\nexport type RegularSearchOptions = BaseSearchOptions & {\n useAutoprompt?: boolean;\n type?: \"keyword\" | \"neural\" | \"auto\";\n};\n\n/**\n * Options for finding similar links.\n * @typedef {Object} FindSimilarOptions\n * @property {boolean} [excludeSourceDomain] - If true, excludes links from the base domain of the input.\n */\nexport type FindSimilarOptions = BaseSearchOptions & {\n excludeSourceDomain?: boolean;\n};\n\nexport type ExtrasOptions = { links?: number; imageLinks?: number };\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} ContentsOptions\n * @property {TextContentsOptions | boolean} [text] - Options for retrieving text contents.\n * @property {HighlightsContentsOptions | boolean} [highlights] - Options for retrieving highlights.\n * @property {SummaryContentsOptions | boolean} [summary] - Options for retrieving summary.\n * @property {LivecrawlOptions} [livecrawl] - Options for livecrawling contents. Default is \"never\" for neural/auto search, \"fallback\" for keyword search.\n * @property {number} [livecrawlTimeout] - The timeout for livecrawling. Max and default is 10000ms.\n * @property {boolean} [filterEmptyResults] - If true, filters out results with no contents. Default is true.\n * @property {number} [subpages] - The number of subpages to return for each result, where each subpage is derived from an internal link for the result.\n * @property {string | string[]} [subpageTarget] - Text used to match/rank subpages in the returned subpage list. You could use \"about\" to get *about* page for websites. Note that this is a fuzzy matcher.\n * @property {ExtrasOptions} [extras] - Miscelleneous data for derived from results\n */\nexport type ContentsOptions = {\n text?: TextContentsOptions | true;\n highlights?: HighlightsContentsOptions | true;\n summary?: SummaryContentsOptions | true;\n livecrawl?: LivecrawlOptions;\n livecrawlTimeout?: number;\n filterEmptyResults?: boolean;\n subpages?: number;\n subpageTarget?: string | string[];\n extras?: ExtrasOptions;\n} & (typeof isBeta extends true ? {} : {});\n\n/**\n * Options for livecrawling contents\n * @typedef {string} LivecrawlOptions\n */\nexport type LivecrawlOptions = \"never\" | \"fallback\" | \"always\" | \"auto\";\n\n/**\n * Options for retrieving text from page.\n * @typedef {Object} TextContentsOptions\n * @property {number} [maxCharacters] - The maximum number of characters to return.\n * @property {boolean} [includeHtmlTags] - If true, includes HTML tags in the returned text. Default: false\n */\nexport type TextContentsOptions = {\n maxCharacters?: number;\n includeHtmlTags?: boolean;\n};\n\n/**\n * Options for retrieving highlights from page.\n * @typedef {Object} HighlightsContentsOptions\n * @property {string} [query] - The query string to use for highlights search.\n * @property {number} [numSentences] - The number of sentences to return for each highlight.\n * @property {number} [highlightsPerUrl] - The number of highlights to return for each URL.\n */\nexport type HighlightsContentsOptions = {\n query?: string;\n numSentences?: number;\n highlightsPerUrl?: number;\n};\n\n/**\n * Options for retrieving summary from page.\n * @typedef {Object} SummaryContentsOptions\n * @property {string} [query] - The query string to use for summary generation.\n */\nexport type SummaryContentsOptions = {\n query?: string;\n};\n\n/**\n * @typedef {Object} TextResponse\n * @property {string} text - Text from page\n */\nexport type TextResponse = { text: string };\n\n/**\n * @typedef {Object} HighlightsResponse\n * @property {string[]} highlights - The highlights as an array of strings.\n * @property {number[]} highlightScores - The corresponding scores as an array of floats, 0 to 1\n */\nexport type HighlightsResponse = {\n highlights: string[];\n highlightScores: number[];\n};\n\n/**\n * @typedef {Object} SummaryResponse\n * @property {string} summary - The generated summary of the page content.\n */\nexport type SummaryResponse = { summary: string };\n\n/**\n * @typedef {Object} ExtrasResponse\n * @property {string[]} links - The links on the page of a result\n * @property {string[]} imageLinks - The image links on the page of a result\n */\nexport type ExtrasResponse = { extras: { links?: string[]; imageLinks?: string[] } };\n\n/**\n * @typedef {Object} SubpagesResponse\n * @property {ContentsResultComponent<T extends ContentsOptions>} subpages - The links on the page of a result\n */\nexport type SubpagesResponse<T extends ContentsOptions> = {\n subpages: ContentsResultComponent<T>[];\n};\n\nexport type Default<T extends {}, U> = [keyof T] extends [never] ? U : T;\n\n/**\n * @typedef {Object} ContentsResultComponent\n * Depending on 'ContentsOptions', this yields a combination of 'TextResponse', 'HighlightsResponse', 'SummaryResponse', or an empty object.\n *\n * @template T - A type extending from 'ContentsOptions'.\n */\nexport type ContentsResultComponent<T extends ContentsOptions> = Default<\n (T[\"text\"] extends object | true ? TextResponse : {}) &\n (T[\"highlights\"] extends object | true ? HighlightsResponse : {}) &\n (T[\"summary\"] extends object | true ? SummaryResponse : {}) &\n (T[\"subpages\"] extends number ? SubpagesResponse<T> : {}) &\n (T[\"extras\"] extends object ? ExtrasResponse : {}),\n TextResponse\n>;\n\n/**\n * Represents a search result object.\n * @typedef {Object} SearchResult\n * @property {string} title - The title of the search result.\n * @property {string} url - The URL of the search result.\n * @property {string} [publishedDate] - The estimated creation date of the content.\n * @property {string} [author] - The author of the content, if available.\n * @property {number} [score] - Similarity score between the query/url and the result.\n * @property {string} id - The temporary ID for the document.\n */\nexport type SearchResult<T extends ContentsOptions> = {\n title: string | null;\n url: string;\n publishedDate?: string;\n author?: string;\n score?: number;\n id: string;\n image?: string;\n favicon?: string;\n} & ContentsResultComponent<T>;\n\n/**\n * Represents a search response object.\n * @typedef {Object} SearchResponse\n * @property {Result[]} results - The list of search results.\n * @property {string} [autopromptString] - The autoprompt string, if applicable.\n * @property {string} [autoDate] - The autoprompt date, if applicable.\n * @property {string} requestId - The request ID for the search.\n */\nexport type SearchResponse<T extends ContentsOptions> = {\n results: SearchResult<T>[];\n autopromptString?: string;\n autoDate?: string;\n requestId: string;\n};\n\n/**\n * Options for the answer endpoint\n * @typedef {Object} AnswerOptions\n * @property {number} [expandedQueriesLimit] - Maximum number of query variations (0-4). Default 1.\n * @property {boolean} [stream] - Whether to stream the response. Default false.\n * @property {boolean} [includeText] - Whether to include text in the source results. Default false.\n */\nexport type AnswerOptions = {\n expandedQueriesLimit?: number;\n stream?: boolean;\n includeText?: boolean;\n};\n\n/**\n * Represents an answer response object from the /answer endpoint.\n * @typedef {Object} AnswerResponse\n * @property {string} answer - The generated answer text.\n * @property {SearchResult<{}>[]]} sources - The sources used to generate the answer.\n * @property {string} [requestId] - Optional request ID for the answer.\n */\nexport type AnswerResponse = {\n answer: string;\n sources: SearchResult<{}>[];\n requestId?: string;\n};\n\n/**\n * Represents a streaming answer response chunk from the /answer endpoint.\n * @typedef {Object} AnswerStreamResponse\n * @property {string} [answer] - A chunk of the generated answer text.\n * @property {SearchResult<{}>[]]} [sources] - The sources used to generate the answer.\n * @property {string} [error] - Error message if something went wrong.\n */\nexport type AnswerStreamResponse = {\n answer?: string;\n sources?: SearchResult<{}>[];\n error?: string;\n};\n\n/**\n * The Exa class encapsulates the API's endpoints.\n */\nclass Exa {\n private baseURL: string;\n private headers: Headers;\n\n private extractContentsOptions<T extends ContentsOptions>(options: T): {\n contentsOptions: ContentsOptions;\n restOptions: Omit<T, keyof ContentsOptions>;\n } {\n const {\n text,\n highlights,\n summary,\n subpages,\n subpageTarget,\n extras,\n livecrawl,\n livecrawlTimeout,\n ...rest\n } = options;\n\n const contentsOptions: ContentsOptions = {};\n // don't send text if it's explicitly false\n if (\n text === undefined &&\n summary === undefined &&\n highlights === undefined &&\n extras === undefined\n )\n contentsOptions.text = true;\n if (text !== undefined) contentsOptions.text = text;\n\n if (summary !== undefined) contentsOptions.summary = summary;\n if (highlights !== undefined) contentsOptions.highlights = highlights;\n\n if (subpages !== undefined) contentsOptions.subpages = subpages;\n if (subpageTarget !== undefined)\n contentsOptions.subpageTarget = subpageTarget;\n\n if (extras !== undefined) contentsOptions.extras = extras;\n if (livecrawl !== undefined) contentsOptions.livecrawl = livecrawl;\n if (livecrawlTimeout !== undefined)\n contentsOptions.livecrawlTimeout = livecrawlTimeout;\n\n return {\n contentsOptions: contentsOptions,\n restOptions: rest as Omit<T, keyof ContentsOptions>,\n };\n }\n\n /**\n * Constructs the Exa API client.\n * @param {string} apiKey - The API key for authentication.\n * @param {string} [baseURL] - The base URL of the Exa API.\n */\n constructor(apiKey?: string, baseURL: string = \"https://api.exa.ai\") {\n this.baseURL = baseURL;\n if (!apiKey) {\n apiKey = process.env.EXASEARCH_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)\",\n );\n }\n }\n this.headers = new Headers({\n \"x-api-key\": apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"exa-node 1.4.0\",\n });\n }\n\n /**\n * Makes a request to the Exa API.\n * @param {string} endpoint - The API endpoint to call.\n * @param {string} method - The HTTP method to use.\n * @param {any} [body] - The request body for POST requests.\n * @param {boolean} [stream] - Whether to stream the response.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<any>} The response from the API.\n */\n private async request(\n endpoint: string,\n method: string,\n body?: any,\n stream?: boolean,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<any> {\n const response = await fetch(this.baseURL + endpoint, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const message = (await response.json()).error;\n throw new Error(\n `Request failed with status ${response.status}. ${message}`,\n );\n }\n\n /**\n * Handle streaming responses from the API. This processes Server-Sent Events (SSE)\n * where data is sent in chunks with the format \"data: {...}\". Each chunk is decoded,\n * parsed as JSON, and passed to the provided callback function.\n */\n if (stream && response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const data = JSON.parse(buffer.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n } catch (error: any) {\n throw new Error(`Streaming error: ${error?.message || 'Unknown error'}`);\n } finally {\n reader.releaseLock();\n }\n\n return null;\n }\n return await response.json();\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions} [options] - Additional search options.\n * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.\n */\n async search(\n query: string,\n options?: RegularSearchOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/search\", \"POST\", { query, ...options });\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions & T} [options] - Additional search + contents options.\n * @returns {Promise<SearchResponse<T>>} A list of relevant search results.\n */\n async searchAndContents<T extends ContentsOptions>(\n query: string,\n options?: RegularSearchOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/search\", \"POST\", {\n query,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Finds similar links to the provided URL.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions} [options] - Additional options for finding similar links.\n * @returns {Promise<SearchResponse<{}>>} A list of similar search results.\n */\n async findSimilar(\n url: string,\n options?: FindSimilarOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/findSimilar\", \"POST\", { url, ...options });\n }\n\n /**\n * Finds similar links to the provided URL and returns the contents of the documents.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions & T} [options] - Additional options for finding similar links + contents.\n * @returns {Promise<SearchResponse<T>>} A list of similar search results.\n */\n async findSimilarAndContents<T extends ContentsOptions>(\n url: string,\n options?: FindSimilarOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/findSimilar\", \"POST\", {\n url,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Retrieves contents of documents based on URLs\n * @param {string | string[] | SearchResult[]} urls - An array of URLs.\n * @param {ContentsOptions} [options] - Additional options for retrieving document contents.\n * @returns {Promise<SearchResponse<T>>} A list of document contents.\n */\n async getContents<T extends ContentsOptions>(\n urls: string | string[] | SearchResult<T>[],\n options?: T,\n ): Promise<SearchResponse<T>> {\n if (urls.length === 0) {\n throw new Error(\"Must provide at least one URL\");\n }\n let requestUrls: string[];\n if (typeof urls === \"string\") {\n requestUrls = [urls];\n } else if (typeof urls[0] === \"string\") {\n requestUrls = urls as string[];\n } else {\n requestUrls = (urls as SearchResult<T>[]).map((result) => result.url);\n }\n const payload = {\n urls: requestUrls,\n ...options,\n };\n\n return await this.request(`/contents`, \"POST\", payload);\n }\n\n /**\n * Generates an answer to a query using search results as context.\n * @param {string} query - The question or query to answer.\n * @param {AnswerOptions} [options] - Additional options for answer generation.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<AnswerResponse | null>} The generated answer and source references, or null if streaming.\n */\n async answer(\n query: string,\n options?: AnswerOptions,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<AnswerResponse | null> {\n const requestBody = {\n query,\n expandedQueriesLimit: options?.expandedQueriesLimit ?? 1,\n stream: options?.stream ?? false,\n includeText: options?.includeText ?? false\n };\n return await this.request(\"/answer\", \"POST\", requestBody, options?.stream, onChunk);\n }\n}\n\nexport default Exa;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA+B;AAyP/B,IAAM,MAAN,MAAU;AAAA,EAIA,uBAAkD,SAGxD;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AAEJ,UAAM,kBAAmC,CAAC;AAE1C,QACE,SAAS,UACT,YAAY,UACZ,eAAe,UACf,WAAW;AAEX,sBAAgB,OAAO;AACzB,QAAI,SAAS;AAAW,sBAAgB,OAAO;AAE/C,QAAI,YAAY;AAAW,sBAAgB,UAAU;AACrD,QAAI,eAAe;AAAW,sBAAgB,aAAa;AAE3D,QAAI,aAAa;AAAW,sBAAgB,WAAW;AACvD,QAAI,kBAAkB;AACpB,sBAAgB,gBAAgB;AAElC,QAAI,WAAW;AAAW,sBAAgB,SAAS;AACnD,QAAI,cAAc;AAAW,sBAAgB,YAAY;AACzD,QAAI,qBAAqB;AACvB,sBAAgB,mBAAmB;AAErC,WAAO;AAAA,MACL;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,QAAiB,UAAkB,sBAAsB;AACnE,SAAK,UAAU;AACf,QAAI,CAAC,QAAQ;AACX,eAAS,QAAQ,IAAI;AACrB,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,SAAK,UAAU,IAAI,2BAAQ;AAAA,MACzB,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,QACZ,UACA,QACA,MACA,QACA,SACc;AACd,UAAM,WAAW,UAAM,mBAAAA,SAAM,KAAK,UAAU,UAAU;AAAA,MACpD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,WAAW,MAAM,SAAS,KAAK,GAAG;AACxC,YAAM,IAAI;AAAA,QACR,8BAA8B,SAAS,WAAW;AAAA,MACpD;AAAA,IACF;AAOA,QAAI,UAAU,SAAS,MAAM;AAC3B,YAAM,SAAS,SAAS,KAAK,UAAU;AACvC,YAAM,UAAU,IAAI,YAAY;AAChC,UAAI,SAAS;AAEb,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAI;AAAM;AAEV,oBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,gBAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,mBAAS,MAAM,IAAI,KAAK;AAExB,qBAAW,QAAQ,OAAO;AACxB,gBAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,kBAAI;AACF,sBAAM,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AACrC,0BAAU,IAAI;AAAA,cAChB,SAAS,GAAP;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,YAAI,UAAU,OAAO,WAAW,QAAQ,GAAG;AACzC,cAAI;AACF,kBAAM,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC;AACvC,sBAAU,IAAI;AAAA,UAChB,SAAS,GAAP;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAP;AACA,cAAM,IAAI,MAAM,oBAAoB,OAAO,WAAW,iBAAiB;AAAA,MACzE,UAAE;AACA,eAAO,YAAY;AAAA,MACrB;AAEA,aAAO;AAAA,IACT;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,OACA,SAC6B;AAC7B,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,OACA,SAC4B;AAC5B,UAAM,EAAE,iBAAiB,YAAY,IACnC,YAAY,SACR,EAAE,iBAAiB,EAAE,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,IACnD,KAAK,uBAAuB,OAAO;AAEzC,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ;AAAA,MAC3C;AAAA,MACA,UAAU;AAAA,MACV,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACJ,KACA,SAC6B;AAC7B,WAAO,MAAM,KAAK,QAAQ,gBAAgB,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,uBACJ,KACA,SAC4B;AAC5B,UAAM,EAAE,iBAAiB,YAAY,IACnC,YAAY,SACR,EAAE,iBAAiB,EAAE,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,IACnD,KAAK,uBAAuB,OAAO;AAEzC,WAAO,MAAM,KAAK,QAAQ,gBAAgB,QAAQ;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACJ,MACA,SAC4B;AAC5B,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,QAAI;AACJ,QAAI,OAAO,SAAS,UAAU;AAC5B,oBAAc,CAAC,IAAI;AAAA,IACrB,WAAW,OAAO,KAAK,CAAC,MAAM,UAAU;AACtC,oBAAc;AAAA,IAChB,OAAO;AACL,oBAAe,KAA2B,IAAI,CAAC,WAAW,OAAO,GAAG;AAAA,IACtE;AACA,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,GAAG;AAAA,IACL;AAEA,WAAO,MAAM,KAAK,QAAQ,aAAa,QAAQ,OAAO;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,OACA,SACA,SACgC;AAChC,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,sBAAsB,SAAS,wBAAwB;AAAA,MACvD,QAAQ,SAAS,UAAU;AAAA,MAC3B,aAAa,SAAS,eAAe;AAAA,IACvC;AACA,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ,aAAa,SAAS,QAAQ,OAAO;AAAA,EACpF;AACF;AAEA,IAAO,cAAQ;","names":["fetch"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fetch, { Headers } from \"cross-fetch\";\n\n// Use native fetch in Node.js environments\nconst fetchImpl = typeof global !== \"undefined\" && global.fetch ? global.fetch : fetch;\nconst HeadersImpl = typeof global !== \"undefined\" && global.Headers ? global.Headers : Headers;\n\nconst isBeta = false;\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} SearchOptions\n * @property {number} [numResults] - Number of search results to return. Default 10. Max 10 for basic plans.\n * @property {string[]} [includeDomains] - List of domains to include in the search.\n * @property {string[]} [excludeDomains] - List of domains to exclude in the search.\n * @property {string} [startCrawlDate] - Start date for results based on crawl date.\n * @property {string} [endCrawlDate] - End date for results based on crawl date.\n * @property {string} [startPublishedDate] - Start date for results based on published date.\n * @property {string} [endPublishedDate] - End date for results based on published date.\n * @property {string} [category] - A data category to focus on, with higher comprehensivity and data cleanliness. Currently, the only category is company.\n * @property {string[]} [includeText] - List of strings that must be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [excludeText] - List of strings that must not be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [flags] - Experimental flags\n */\nexport type BaseSearchOptions = {\n numResults?: number;\n includeDomains?: string[];\n excludeDomains?: string[];\n startCrawlDate?: string;\n endCrawlDate?: string;\n startPublishedDate?: string;\n endPublishedDate?: string;\n category?: \"company\" | \"research paper\" | \"news\" | \"pdf\" | \"github\" | \"tweet\" | \"personal site\" | \"linkedin profile\" | \"financial report\";\n includeText?: string[];\n excludeText?: string[];\n flags?: string[];\n};\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} RegularSearchOptions\n */\nexport type RegularSearchOptions = BaseSearchOptions & {\n useAutoprompt?: boolean;\n type?: \"keyword\" | \"neural\" | \"auto\";\n};\n\n/**\n * Options for finding similar links.\n * @typedef {Object} FindSimilarOptions\n * @property {boolean} [excludeSourceDomain] - If true, excludes links from the base domain of the input.\n */\nexport type FindSimilarOptions = BaseSearchOptions & {\n excludeSourceDomain?: boolean;\n};\n\nexport type ExtrasOptions = { links?: number; imageLinks?: number };\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} ContentsOptions\n * @property {TextContentsOptions | boolean} [text] - Options for retrieving text contents.\n * @property {HighlightsContentsOptions | boolean} [highlights] - Options for retrieving highlights.\n * @property {SummaryContentsOptions | boolean} [summary] - Options for retrieving summary.\n * @property {LivecrawlOptions} [livecrawl] - Options for livecrawling contents. Default is \"never\" for neural/auto search, \"fallback\" for keyword search.\n * @property {number} [livecrawlTimeout] - The timeout for livecrawling. Max and default is 10000ms.\n * @property {boolean} [filterEmptyResults] - If true, filters out results with no contents. Default is true.\n * @property {number} [subpages] - The number of subpages to return for each result, where each subpage is derived from an internal link for the result.\n * @property {string | string[]} [subpageTarget] - Text used to match/rank subpages in the returned subpage list. You could use \"about\" to get *about* page for websites. Note that this is a fuzzy matcher.\n * @property {ExtrasOptions} [extras] - Miscelleneous data for derived from results\n */\nexport type ContentsOptions = {\n text?: TextContentsOptions | true;\n highlights?: HighlightsContentsOptions | true;\n summary?: SummaryContentsOptions | true;\n livecrawl?: LivecrawlOptions;\n livecrawlTimeout?: number;\n filterEmptyResults?: boolean;\n subpages?: number;\n subpageTarget?: string | string[];\n extras?: ExtrasOptions;\n} & (typeof isBeta extends true ? {} : {});\n\n/**\n * Options for livecrawling contents\n * @typedef {string} LivecrawlOptions\n */\nexport type LivecrawlOptions = \"never\" | \"fallback\" | \"always\" | \"auto\";\n\n/**\n * Options for retrieving text from page.\n * @typedef {Object} TextContentsOptions\n * @property {number} [maxCharacters] - The maximum number of characters to return.\n * @property {boolean} [includeHtmlTags] - If true, includes HTML tags in the returned text. Default: false\n */\nexport type TextContentsOptions = {\n maxCharacters?: number;\n includeHtmlTags?: boolean;\n};\n\n/**\n * Options for retrieving highlights from page.\n * @typedef {Object} HighlightsContentsOptions\n * @property {string} [query] - The query string to use for highlights search.\n * @property {number} [numSentences] - The number of sentences to return for each highlight.\n * @property {number} [highlightsPerUrl] - The number of highlights to return for each URL.\n */\nexport type HighlightsContentsOptions = {\n query?: string;\n numSentences?: number;\n highlightsPerUrl?: number;\n};\n\n/**\n * Options for retrieving summary from page.\n * @typedef {Object} SummaryContentsOptions\n * @property {string} [query] - The query string to use for summary generation.\n */\nexport type SummaryContentsOptions = {\n query?: string;\n};\n\n/**\n * @typedef {Object} TextResponse\n * @property {string} text - Text from page\n */\nexport type TextResponse = { text: string };\n\n/**\n * @typedef {Object} HighlightsResponse\n * @property {string[]} highlights - The highlights as an array of strings.\n * @property {number[]} highlightScores - The corresponding scores as an array of floats, 0 to 1\n */\nexport type HighlightsResponse = {\n highlights: string[];\n highlightScores: number[];\n};\n\n/**\n * @typedef {Object} SummaryResponse\n * @property {string} summary - The generated summary of the page content.\n */\nexport type SummaryResponse = { summary: string };\n\n/**\n * @typedef {Object} ExtrasResponse\n * @property {string[]} links - The links on the page of a result\n * @property {string[]} imageLinks - The image links on the page of a result\n */\nexport type ExtrasResponse = { extras: { links?: string[]; imageLinks?: string[] } };\n\n/**\n * @typedef {Object} SubpagesResponse\n * @property {ContentsResultComponent<T extends ContentsOptions>} subpages - The links on the page of a result\n */\nexport type SubpagesResponse<T extends ContentsOptions> = {\n subpages: ContentsResultComponent<T>[];\n};\n\nexport type Default<T extends {}, U> = [keyof T] extends [never] ? U : T;\n\n/**\n * @typedef {Object} ContentsResultComponent\n * Depending on 'ContentsOptions', this yields a combination of 'TextResponse', 'HighlightsResponse', 'SummaryResponse', or an empty object.\n *\n * @template T - A type extending from 'ContentsOptions'.\n */\nexport type ContentsResultComponent<T extends ContentsOptions> = Default<\n (T[\"text\"] extends object | true ? TextResponse : {}) &\n (T[\"highlights\"] extends object | true ? HighlightsResponse : {}) &\n (T[\"summary\"] extends object | true ? SummaryResponse : {}) &\n (T[\"subpages\"] extends number ? SubpagesResponse<T> : {}) &\n (T[\"extras\"] extends object ? ExtrasResponse : {}),\n TextResponse\n>;\n\n/**\n * Represents a search result object.\n * @typedef {Object} SearchResult\n * @property {string} title - The title of the search result.\n * @property {string} url - The URL of the search result.\n * @property {string} [publishedDate] - The estimated creation date of the content.\n * @property {string} [author] - The author of the content, if available.\n * @property {number} [score] - Similarity score between the query/url and the result.\n * @property {string} id - The temporary ID for the document.\n */\nexport type SearchResult<T extends ContentsOptions> = {\n title: string | null;\n url: string;\n publishedDate?: string;\n author?: string;\n score?: number;\n id: string;\n image?: string;\n favicon?: string;\n} & ContentsResultComponent<T>;\n\n/**\n * Represents a search response object.\n * @typedef {Object} SearchResponse\n * @property {Result[]} results - The list of search results.\n * @property {string} [autopromptString] - The autoprompt string, if applicable.\n * @property {string} [autoDate] - The autoprompt date, if applicable.\n * @property {string} requestId - The request ID for the search.\n */\nexport type SearchResponse<T extends ContentsOptions> = {\n results: SearchResult<T>[];\n autopromptString?: string;\n autoDate?: string;\n requestId: string;\n};\n\n/**\n * Options for the answer endpoint\n * @typedef {Object} AnswerOptions\n * @property {number} [expandedQueriesLimit] - Maximum number of query variations (0-4). Default 1.\n * @property {boolean} [stream] - Whether to stream the response. Default false.\n * @property {boolean} [includeText] - Whether to include text in the source results. Default false.\n */\nexport type AnswerOptions = {\n expandedQueriesLimit?: number;\n stream?: boolean;\n includeText?: boolean;\n};\n\n/**\n * Represents an answer response object from the /answer endpoint.\n * @typedef {Object} AnswerResponse\n * @property {string} answer - The generated answer text.\n * @property {SearchResult<{}>[]]} sources - The sources used to generate the answer.\n * @property {string} [requestId] - Optional request ID for the answer.\n */\nexport type AnswerResponse = {\n answer: string;\n sources: SearchResult<{}>[];\n requestId?: string;\n};\n\n/**\n * Represents a streaming answer response chunk from the /answer endpoint.\n * @typedef {Object} AnswerStreamResponse\n * @property {string} [answer] - A chunk of the generated answer text.\n * @property {SearchResult<{}>[]]} [sources] - The sources used to generate the answer.\n * @property {string} [error] - Error message if something went wrong.\n */\nexport type AnswerStreamResponse = {\n answer?: string;\n sources?: SearchResult<{}>[];\n error?: string;\n};\n\n/**\n * The Exa class encapsulates the API's endpoints.\n */\nclass Exa {\n private baseURL: string;\n private headers: Headers;\n\n private extractContentsOptions<T extends ContentsOptions>(options: T): {\n contentsOptions: ContentsOptions;\n restOptions: Omit<T, keyof ContentsOptions>;\n } {\n const {\n text,\n highlights,\n summary,\n subpages,\n subpageTarget,\n extras,\n livecrawl,\n livecrawlTimeout,\n ...rest\n } = options;\n\n const contentsOptions: ContentsOptions = {};\n // don't send text if it's explicitly false\n if (\n text === undefined &&\n summary === undefined &&\n highlights === undefined &&\n extras === undefined\n )\n contentsOptions.text = true;\n if (text !== undefined) contentsOptions.text = text;\n\n if (summary !== undefined) contentsOptions.summary = summary;\n if (highlights !== undefined) contentsOptions.highlights = highlights;\n\n if (subpages !== undefined) contentsOptions.subpages = subpages;\n if (subpageTarget !== undefined)\n contentsOptions.subpageTarget = subpageTarget;\n\n if (extras !== undefined) contentsOptions.extras = extras;\n if (livecrawl !== undefined) contentsOptions.livecrawl = livecrawl;\n if (livecrawlTimeout !== undefined)\n contentsOptions.livecrawlTimeout = livecrawlTimeout;\n\n return {\n contentsOptions: contentsOptions,\n restOptions: rest as Omit<T, keyof ContentsOptions>,\n };\n }\n\n /**\n * Constructs the Exa API client.\n * @param {string} apiKey - The API key for authentication.\n * @param {string} [baseURL] - The base URL of the Exa API.\n */\n constructor(apiKey?: string, baseURL: string = \"https://api.exa.ai\") {\n this.baseURL = baseURL;\n if (!apiKey) {\n apiKey = process.env.EXASEARCH_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)\",\n );\n }\n }\n this.headers = new HeadersImpl({\n \"x-api-key\": apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"exa-node 1.4.0\",\n });\n }\n\n /**\n * Makes a request to the Exa API.\n * @param {string} endpoint - The API endpoint to call.\n * @param {string} method - The HTTP method to use.\n * @param {any} [body] - The request body for POST requests.\n * @param {boolean} [stream] - Whether to stream the response.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<any>} The response from the API.\n */\n private async request(\n endpoint: string,\n method: string,\n body?: any,\n stream?: boolean,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<any> {\n const response = await fetchImpl(this.baseURL + endpoint, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const message = (await response.json()).error;\n throw new Error(\n `Request failed with status ${response.status}. ${message}`,\n );\n }\n\n /**\n * Handle streaming responses from the API. This processes Server-Sent Events (SSE)\n * where data is sent in chunks with the format \"data: {...}\". Each chunk is decoded,\n * parsed as JSON, and passed to the provided callback function.\n */\n if (stream && response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const data = JSON.parse(buffer.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n } catch (error: any) {\n throw new Error(`Streaming error: ${error?.message || 'Unknown error'}`);\n } finally {\n reader.releaseLock();\n }\n\n return null;\n }\n return await response.json();\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions} [options] - Additional search options.\n * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.\n */\n async search(\n query: string,\n options?: RegularSearchOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/search\", \"POST\", { query, ...options });\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions & T} [options] - Additional search + contents options.\n * @returns {Promise<SearchResponse<T>>} A list of relevant search results.\n */\n async searchAndContents<T extends ContentsOptions>(\n query: string,\n options?: RegularSearchOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/search\", \"POST\", {\n query,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Finds similar links to the provided URL.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions} [options] - Additional options for finding similar links.\n * @returns {Promise<SearchResponse<{}>>} A list of similar search results.\n */\n async findSimilar(\n url: string,\n options?: FindSimilarOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/findSimilar\", \"POST\", { url, ...options });\n }\n\n /**\n * Finds similar links to the provided URL and returns the contents of the documents.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions & T} [options] - Additional options for finding similar links + contents.\n * @returns {Promise<SearchResponse<T>>} A list of similar search results.\n */\n async findSimilarAndContents<T extends ContentsOptions>(\n url: string,\n options?: FindSimilarOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/findSimilar\", \"POST\", {\n url,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Retrieves contents of documents based on URLs\n * @param {string | string[] | SearchResult[]} urls - An array of URLs.\n * @param {ContentsOptions} [options] - Additional options for retrieving document contents.\n * @returns {Promise<SearchResponse<T>>} A list of document contents.\n */\n async getContents<T extends ContentsOptions>(\n urls: string | string[] | SearchResult<T>[],\n options?: T,\n ): Promise<SearchResponse<T>> {\n if (urls.length === 0) {\n throw new Error(\"Must provide at least one URL\");\n }\n let requestUrls: string[];\n if (typeof urls === \"string\") {\n requestUrls = [urls];\n } else if (typeof urls[0] === \"string\") {\n requestUrls = urls as string[];\n } else {\n requestUrls = (urls as SearchResult<T>[]).map((result) => result.url);\n }\n const payload = {\n urls: requestUrls,\n ...options,\n };\n\n return await this.request(`/contents`, \"POST\", payload);\n }\n\n /**\n * Generates an answer to a query using search results as context.\n * @param {string} query - The question or query to answer.\n * @param {AnswerOptions} [options] - Additional options for answer generation.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<AnswerResponse | null>} The generated answer and source references, or null if streaming.\n */\n async answer(\n query: string,\n options?: AnswerOptions,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<AnswerResponse | null> {\n const requestBody = {\n query,\n expandedQueriesLimit: options?.expandedQueriesLimit ?? 1,\n stream: options?.stream ?? false,\n includeText: options?.includeText ?? false\n };\n return await this.request(\"/answer\", \"POST\", requestBody, options?.stream, onChunk);\n }\n}\n\nexport default Exa;\n"],"mappings":"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","names":["fetch"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import fetch, { Headers } from "cross-fetch";
|
|
3
|
+
var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : fetch;
|
|
4
|
+
var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : Headers;
|
|
3
5
|
var Exa = class {
|
|
4
6
|
extractContentsOptions(options) {
|
|
5
7
|
const {
|
|
@@ -52,7 +54,7 @@ var Exa = class {
|
|
|
52
54
|
);
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
this.headers = new
|
|
57
|
+
this.headers = new HeadersImpl({
|
|
56
58
|
"x-api-key": apiKey,
|
|
57
59
|
"Content-Type": "application/json",
|
|
58
60
|
"User-Agent": "exa-node 1.4.0"
|
|
@@ -68,7 +70,7 @@ var Exa = class {
|
|
|
68
70
|
* @returns {Promise<any>} The response from the API.
|
|
69
71
|
*/
|
|
70
72
|
async request(endpoint, method, body, stream, onChunk) {
|
|
71
|
-
const response = await
|
|
73
|
+
const response = await fetchImpl(this.baseURL + endpoint, {
|
|
72
74
|
method,
|
|
73
75
|
headers: this.headers,
|
|
74
76
|
body: body ? JSON.stringify(body) : void 0
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fetch, { Headers } from \"cross-fetch\";\n\nconst isBeta = false;\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} SearchOptions\n * @property {number} [numResults] - Number of search results to return. Default 10. Max 10 for basic plans.\n * @property {string[]} [includeDomains] - List of domains to include in the search.\n * @property {string[]} [excludeDomains] - List of domains to exclude in the search.\n * @property {string} [startCrawlDate] - Start date for results based on crawl date.\n * @property {string} [endCrawlDate] - End date for results based on crawl date.\n * @property {string} [startPublishedDate] - Start date for results based on published date.\n * @property {string} [endPublishedDate] - End date for results based on published date.\n * @property {string} [category] - A data category to focus on, with higher comprehensivity and data cleanliness. Currently, the only category is company.\n * @property {string[]} [includeText] - List of strings that must be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [excludeText] - List of strings that must not be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [flags] - Experimental flags\n */\nexport type BaseSearchOptions = {\n numResults?: number;\n includeDomains?: string[];\n excludeDomains?: string[];\n startCrawlDate?: string;\n endCrawlDate?: string;\n startPublishedDate?: string;\n endPublishedDate?: string;\n category?: \"company\" | \"research paper\" | \"news\" | \"pdf\" | \"github\" | \"tweet\" | \"personal site\" | \"linkedin profile\" | \"financial report\";\n includeText?: string[];\n excludeText?: string[];\n flags?: string[];\n};\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} RegularSearchOptions\n */\nexport type RegularSearchOptions = BaseSearchOptions & {\n useAutoprompt?: boolean;\n type?: \"keyword\" | \"neural\" | \"auto\";\n};\n\n/**\n * Options for finding similar links.\n * @typedef {Object} FindSimilarOptions\n * @property {boolean} [excludeSourceDomain] - If true, excludes links from the base domain of the input.\n */\nexport type FindSimilarOptions = BaseSearchOptions & {\n excludeSourceDomain?: boolean;\n};\n\nexport type ExtrasOptions = { links?: number; imageLinks?: number };\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} ContentsOptions\n * @property {TextContentsOptions | boolean} [text] - Options for retrieving text contents.\n * @property {HighlightsContentsOptions | boolean} [highlights] - Options for retrieving highlights.\n * @property {SummaryContentsOptions | boolean} [summary] - Options for retrieving summary.\n * @property {LivecrawlOptions} [livecrawl] - Options for livecrawling contents. Default is \"never\" for neural/auto search, \"fallback\" for keyword search.\n * @property {number} [livecrawlTimeout] - The timeout for livecrawling. Max and default is 10000ms.\n * @property {boolean} [filterEmptyResults] - If true, filters out results with no contents. Default is true.\n * @property {number} [subpages] - The number of subpages to return for each result, where each subpage is derived from an internal link for the result.\n * @property {string | string[]} [subpageTarget] - Text used to match/rank subpages in the returned subpage list. You could use \"about\" to get *about* page for websites. Note that this is a fuzzy matcher.\n * @property {ExtrasOptions} [extras] - Miscelleneous data for derived from results\n */\nexport type ContentsOptions = {\n text?: TextContentsOptions | true;\n highlights?: HighlightsContentsOptions | true;\n summary?: SummaryContentsOptions | true;\n livecrawl?: LivecrawlOptions;\n livecrawlTimeout?: number;\n filterEmptyResults?: boolean;\n subpages?: number;\n subpageTarget?: string | string[];\n extras?: ExtrasOptions;\n} & (typeof isBeta extends true ? {} : {});\n\n/**\n * Options for livecrawling contents\n * @typedef {string} LivecrawlOptions\n */\nexport type LivecrawlOptions = \"never\" | \"fallback\" | \"always\" | \"auto\";\n\n/**\n * Options for retrieving text from page.\n * @typedef {Object} TextContentsOptions\n * @property {number} [maxCharacters] - The maximum number of characters to return.\n * @property {boolean} [includeHtmlTags] - If true, includes HTML tags in the returned text. Default: false\n */\nexport type TextContentsOptions = {\n maxCharacters?: number;\n includeHtmlTags?: boolean;\n};\n\n/**\n * Options for retrieving highlights from page.\n * @typedef {Object} HighlightsContentsOptions\n * @property {string} [query] - The query string to use for highlights search.\n * @property {number} [numSentences] - The number of sentences to return for each highlight.\n * @property {number} [highlightsPerUrl] - The number of highlights to return for each URL.\n */\nexport type HighlightsContentsOptions = {\n query?: string;\n numSentences?: number;\n highlightsPerUrl?: number;\n};\n\n/**\n * Options for retrieving summary from page.\n * @typedef {Object} SummaryContentsOptions\n * @property {string} [query] - The query string to use for summary generation.\n */\nexport type SummaryContentsOptions = {\n query?: string;\n};\n\n/**\n * @typedef {Object} TextResponse\n * @property {string} text - Text from page\n */\nexport type TextResponse = { text: string };\n\n/**\n * @typedef {Object} HighlightsResponse\n * @property {string[]} highlights - The highlights as an array of strings.\n * @property {number[]} highlightScores - The corresponding scores as an array of floats, 0 to 1\n */\nexport type HighlightsResponse = {\n highlights: string[];\n highlightScores: number[];\n};\n\n/**\n * @typedef {Object} SummaryResponse\n * @property {string} summary - The generated summary of the page content.\n */\nexport type SummaryResponse = { summary: string };\n\n/**\n * @typedef {Object} ExtrasResponse\n * @property {string[]} links - The links on the page of a result\n * @property {string[]} imageLinks - The image links on the page of a result\n */\nexport type ExtrasResponse = { extras: { links?: string[]; imageLinks?: string[] } };\n\n/**\n * @typedef {Object} SubpagesResponse\n * @property {ContentsResultComponent<T extends ContentsOptions>} subpages - The links on the page of a result\n */\nexport type SubpagesResponse<T extends ContentsOptions> = {\n subpages: ContentsResultComponent<T>[];\n};\n\nexport type Default<T extends {}, U> = [keyof T] extends [never] ? U : T;\n\n/**\n * @typedef {Object} ContentsResultComponent\n * Depending on 'ContentsOptions', this yields a combination of 'TextResponse', 'HighlightsResponse', 'SummaryResponse', or an empty object.\n *\n * @template T - A type extending from 'ContentsOptions'.\n */\nexport type ContentsResultComponent<T extends ContentsOptions> = Default<\n (T[\"text\"] extends object | true ? TextResponse : {}) &\n (T[\"highlights\"] extends object | true ? HighlightsResponse : {}) &\n (T[\"summary\"] extends object | true ? SummaryResponse : {}) &\n (T[\"subpages\"] extends number ? SubpagesResponse<T> : {}) &\n (T[\"extras\"] extends object ? ExtrasResponse : {}),\n TextResponse\n>;\n\n/**\n * Represents a search result object.\n * @typedef {Object} SearchResult\n * @property {string} title - The title of the search result.\n * @property {string} url - The URL of the search result.\n * @property {string} [publishedDate] - The estimated creation date of the content.\n * @property {string} [author] - The author of the content, if available.\n * @property {number} [score] - Similarity score between the query/url and the result.\n * @property {string} id - The temporary ID for the document.\n */\nexport type SearchResult<T extends ContentsOptions> = {\n title: string | null;\n url: string;\n publishedDate?: string;\n author?: string;\n score?: number;\n id: string;\n image?: string;\n favicon?: string;\n} & ContentsResultComponent<T>;\n\n/**\n * Represents a search response object.\n * @typedef {Object} SearchResponse\n * @property {Result[]} results - The list of search results.\n * @property {string} [autopromptString] - The autoprompt string, if applicable.\n * @property {string} [autoDate] - The autoprompt date, if applicable.\n * @property {string} requestId - The request ID for the search.\n */\nexport type SearchResponse<T extends ContentsOptions> = {\n results: SearchResult<T>[];\n autopromptString?: string;\n autoDate?: string;\n requestId: string;\n};\n\n/**\n * Options for the answer endpoint\n * @typedef {Object} AnswerOptions\n * @property {number} [expandedQueriesLimit] - Maximum number of query variations (0-4). Default 1.\n * @property {boolean} [stream] - Whether to stream the response. Default false.\n * @property {boolean} [includeText] - Whether to include text in the source results. Default false.\n */\nexport type AnswerOptions = {\n expandedQueriesLimit?: number;\n stream?: boolean;\n includeText?: boolean;\n};\n\n/**\n * Represents an answer response object from the /answer endpoint.\n * @typedef {Object} AnswerResponse\n * @property {string} answer - The generated answer text.\n * @property {SearchResult<{}>[]]} sources - The sources used to generate the answer.\n * @property {string} [requestId] - Optional request ID for the answer.\n */\nexport type AnswerResponse = {\n answer: string;\n sources: SearchResult<{}>[];\n requestId?: string;\n};\n\n/**\n * Represents a streaming answer response chunk from the /answer endpoint.\n * @typedef {Object} AnswerStreamResponse\n * @property {string} [answer] - A chunk of the generated answer text.\n * @property {SearchResult<{}>[]]} [sources] - The sources used to generate the answer.\n * @property {string} [error] - Error message if something went wrong.\n */\nexport type AnswerStreamResponse = {\n answer?: string;\n sources?: SearchResult<{}>[];\n error?: string;\n};\n\n/**\n * The Exa class encapsulates the API's endpoints.\n */\nclass Exa {\n private baseURL: string;\n private headers: Headers;\n\n private extractContentsOptions<T extends ContentsOptions>(options: T): {\n contentsOptions: ContentsOptions;\n restOptions: Omit<T, keyof ContentsOptions>;\n } {\n const {\n text,\n highlights,\n summary,\n subpages,\n subpageTarget,\n extras,\n livecrawl,\n livecrawlTimeout,\n ...rest\n } = options;\n\n const contentsOptions: ContentsOptions = {};\n // don't send text if it's explicitly false\n if (\n text === undefined &&\n summary === undefined &&\n highlights === undefined &&\n extras === undefined\n )\n contentsOptions.text = true;\n if (text !== undefined) contentsOptions.text = text;\n\n if (summary !== undefined) contentsOptions.summary = summary;\n if (highlights !== undefined) contentsOptions.highlights = highlights;\n\n if (subpages !== undefined) contentsOptions.subpages = subpages;\n if (subpageTarget !== undefined)\n contentsOptions.subpageTarget = subpageTarget;\n\n if (extras !== undefined) contentsOptions.extras = extras;\n if (livecrawl !== undefined) contentsOptions.livecrawl = livecrawl;\n if (livecrawlTimeout !== undefined)\n contentsOptions.livecrawlTimeout = livecrawlTimeout;\n\n return {\n contentsOptions: contentsOptions,\n restOptions: rest as Omit<T, keyof ContentsOptions>,\n };\n }\n\n /**\n * Constructs the Exa API client.\n * @param {string} apiKey - The API key for authentication.\n * @param {string} [baseURL] - The base URL of the Exa API.\n */\n constructor(apiKey?: string, baseURL: string = \"https://api.exa.ai\") {\n this.baseURL = baseURL;\n if (!apiKey) {\n apiKey = process.env.EXASEARCH_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)\",\n );\n }\n }\n this.headers = new Headers({\n \"x-api-key\": apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"exa-node 1.4.0\",\n });\n }\n\n /**\n * Makes a request to the Exa API.\n * @param {string} endpoint - The API endpoint to call.\n * @param {string} method - The HTTP method to use.\n * @param {any} [body] - The request body for POST requests.\n * @param {boolean} [stream] - Whether to stream the response.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<any>} The response from the API.\n */\n private async request(\n endpoint: string,\n method: string,\n body?: any,\n stream?: boolean,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<any> {\n const response = await fetch(this.baseURL + endpoint, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const message = (await response.json()).error;\n throw new Error(\n `Request failed with status ${response.status}. ${message}`,\n );\n }\n\n /**\n * Handle streaming responses from the API. This processes Server-Sent Events (SSE)\n * where data is sent in chunks with the format \"data: {...}\". Each chunk is decoded,\n * parsed as JSON, and passed to the provided callback function.\n */\n if (stream && response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const data = JSON.parse(buffer.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n } catch (error: any) {\n throw new Error(`Streaming error: ${error?.message || 'Unknown error'}`);\n } finally {\n reader.releaseLock();\n }\n\n return null;\n }\n return await response.json();\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions} [options] - Additional search options.\n * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.\n */\n async search(\n query: string,\n options?: RegularSearchOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/search\", \"POST\", { query, ...options });\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions & T} [options] - Additional search + contents options.\n * @returns {Promise<SearchResponse<T>>} A list of relevant search results.\n */\n async searchAndContents<T extends ContentsOptions>(\n query: string,\n options?: RegularSearchOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/search\", \"POST\", {\n query,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Finds similar links to the provided URL.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions} [options] - Additional options for finding similar links.\n * @returns {Promise<SearchResponse<{}>>} A list of similar search results.\n */\n async findSimilar(\n url: string,\n options?: FindSimilarOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/findSimilar\", \"POST\", { url, ...options });\n }\n\n /**\n * Finds similar links to the provided URL and returns the contents of the documents.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions & T} [options] - Additional options for finding similar links + contents.\n * @returns {Promise<SearchResponse<T>>} A list of similar search results.\n */\n async findSimilarAndContents<T extends ContentsOptions>(\n url: string,\n options?: FindSimilarOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/findSimilar\", \"POST\", {\n url,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Retrieves contents of documents based on URLs\n * @param {string | string[] | SearchResult[]} urls - An array of URLs.\n * @param {ContentsOptions} [options] - Additional options for retrieving document contents.\n * @returns {Promise<SearchResponse<T>>} A list of document contents.\n */\n async getContents<T extends ContentsOptions>(\n urls: string | string[] | SearchResult<T>[],\n options?: T,\n ): Promise<SearchResponse<T>> {\n if (urls.length === 0) {\n throw new Error(\"Must provide at least one URL\");\n }\n let requestUrls: string[];\n if (typeof urls === \"string\") {\n requestUrls = [urls];\n } else if (typeof urls[0] === \"string\") {\n requestUrls = urls as string[];\n } else {\n requestUrls = (urls as SearchResult<T>[]).map((result) => result.url);\n }\n const payload = {\n urls: requestUrls,\n ...options,\n };\n\n return await this.request(`/contents`, \"POST\", payload);\n }\n\n /**\n * Generates an answer to a query using search results as context.\n * @param {string} query - The question or query to answer.\n * @param {AnswerOptions} [options] - Additional options for answer generation.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<AnswerResponse | null>} The generated answer and source references, or null if streaming.\n */\n async answer(\n query: string,\n options?: AnswerOptions,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<AnswerResponse | null> {\n const requestBody = {\n query,\n expandedQueriesLimit: options?.expandedQueriesLimit ?? 1,\n stream: options?.stream ?? false,\n includeText: options?.includeText ?? false\n };\n return await this.request(\"/answer\", \"POST\", requestBody, options?.stream, onChunk);\n }\n}\n\nexport default Exa;\n"],"mappings":";AAAA,OAAO,SAAS,eAAe;AAyP/B,IAAM,MAAN,MAAU;AAAA,EAIA,uBAAkD,SAGxD;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AAEJ,UAAM,kBAAmC,CAAC;AAE1C,QACE,SAAS,UACT,YAAY,UACZ,eAAe,UACf,WAAW;AAEX,sBAAgB,OAAO;AACzB,QAAI,SAAS;AAAW,sBAAgB,OAAO;AAE/C,QAAI,YAAY;AAAW,sBAAgB,UAAU;AACrD,QAAI,eAAe;AAAW,sBAAgB,aAAa;AAE3D,QAAI,aAAa;AAAW,sBAAgB,WAAW;AACvD,QAAI,kBAAkB;AACpB,sBAAgB,gBAAgB;AAElC,QAAI,WAAW;AAAW,sBAAgB,SAAS;AACnD,QAAI,cAAc;AAAW,sBAAgB,YAAY;AACzD,QAAI,qBAAqB;AACvB,sBAAgB,mBAAmB;AAErC,WAAO;AAAA,MACL;AAAA,MACA,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,QAAiB,UAAkB,sBAAsB;AACnE,SAAK,UAAU;AACf,QAAI,CAAC,QAAQ;AACX,eAAS,QAAQ,IAAI;AACrB,UAAI,CAAC,QAAQ;AACX,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,SAAK,UAAU,IAAI,QAAQ;AAAA,MACzB,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,QACZ,UACA,QACA,MACA,QACA,SACc;AACd,UAAM,WAAW,MAAM,MAAM,KAAK,UAAU,UAAU;AAAA,MACpD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,WAAW,MAAM,SAAS,KAAK,GAAG;AACxC,YAAM,IAAI;AAAA,QACR,8BAA8B,SAAS,WAAW;AAAA,MACpD;AAAA,IACF;AAOA,QAAI,UAAU,SAAS,MAAM;AAC3B,YAAM,SAAS,SAAS,KAAK,UAAU;AACvC,YAAM,UAAU,IAAI,YAAY;AAChC,UAAI,SAAS;AAEb,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAI;AAAM;AAEV,oBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,gBAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,mBAAS,MAAM,IAAI,KAAK;AAExB,qBAAW,QAAQ,OAAO;AACxB,gBAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,kBAAI;AACF,sBAAM,OAAO,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AACrC,0BAAU,IAAI;AAAA,cAChB,SAAS,GAAP;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,YAAI,UAAU,OAAO,WAAW,QAAQ,GAAG;AACzC,cAAI;AACF,kBAAM,OAAO,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC;AACvC,sBAAU,IAAI;AAAA,UAChB,SAAS,GAAP;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAP;AACA,cAAM,IAAI,MAAM,oBAAoB,OAAO,WAAW,iBAAiB;AAAA,MACzE,UAAE;AACA,eAAO,YAAY;AAAA,MACrB;AAEA,aAAO;AAAA,IACT;AACA,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OACJ,OACA,SAC6B;AAC7B,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,OACA,SAC4B;AAC5B,UAAM,EAAE,iBAAiB,YAAY,IACnC,YAAY,SACR,EAAE,iBAAiB,EAAE,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,IACnD,KAAK,uBAAuB,OAAO;AAEzC,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ;AAAA,MAC3C;AAAA,MACA,UAAU;AAAA,MACV,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACJ,KACA,SAC6B;AAC7B,WAAO,MAAM,KAAK,QAAQ,gBAAgB,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;AAAA,EACvE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,uBACJ,KACA,SAC4B;AAC5B,UAAM,EAAE,iBAAiB,YAAY,IACnC,YAAY,SACR,EAAE,iBAAiB,EAAE,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,IACnD,KAAK,uBAAuB,OAAO;AAEzC,WAAO,MAAM,KAAK,QAAQ,gBAAgB,QAAQ;AAAA,MAChD;AAAA,MACA,UAAU;AAAA,MACV,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YACJ,MACA,SAC4B;AAC5B,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,QAAI;AACJ,QAAI,OAAO,SAAS,UAAU;AAC5B,oBAAc,CAAC,IAAI;AAAA,IACrB,WAAW,OAAO,KAAK,CAAC,MAAM,UAAU;AACtC,oBAAc;AAAA,IAChB,OAAO;AACL,oBAAe,KAA2B,IAAI,CAAC,WAAW,OAAO,GAAG;AAAA,IACtE;AACA,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,GAAG;AAAA,IACL;AAEA,WAAO,MAAM,KAAK,QAAQ,aAAa,QAAQ,OAAO;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OACJ,OACA,SACA,SACgC;AAChC,UAAM,cAAc;AAAA,MAClB;AAAA,MACA,sBAAsB,SAAS,wBAAwB;AAAA,MACvD,QAAQ,SAAS,UAAU;AAAA,MAC3B,aAAa,SAAS,eAAe;AAAA,IACvC;AACA,WAAO,MAAM,KAAK,QAAQ,WAAW,QAAQ,aAAa,SAAS,QAAQ,OAAO;AAAA,EACpF;AACF;AAEA,IAAO,cAAQ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fetch, { Headers } from \"cross-fetch\";\n\n// Use native fetch in Node.js environments\nconst fetchImpl = typeof global !== \"undefined\" && global.fetch ? global.fetch : fetch;\nconst HeadersImpl = typeof global !== \"undefined\" && global.Headers ? global.Headers : Headers;\n\nconst isBeta = false;\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} SearchOptions\n * @property {number} [numResults] - Number of search results to return. Default 10. Max 10 for basic plans.\n * @property {string[]} [includeDomains] - List of domains to include in the search.\n * @property {string[]} [excludeDomains] - List of domains to exclude in the search.\n * @property {string} [startCrawlDate] - Start date for results based on crawl date.\n * @property {string} [endCrawlDate] - End date for results based on crawl date.\n * @property {string} [startPublishedDate] - Start date for results based on published date.\n * @property {string} [endPublishedDate] - End date for results based on published date.\n * @property {string} [category] - A data category to focus on, with higher comprehensivity and data cleanliness. Currently, the only category is company.\n * @property {string[]} [includeText] - List of strings that must be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [excludeText] - List of strings that must not be present in webpage text of results. Currently only supports 1 string of up to 5 words.\n * @property {string[]} [flags] - Experimental flags\n */\nexport type BaseSearchOptions = {\n numResults?: number;\n includeDomains?: string[];\n excludeDomains?: string[];\n startCrawlDate?: string;\n endCrawlDate?: string;\n startPublishedDate?: string;\n endPublishedDate?: string;\n category?: \"company\" | \"research paper\" | \"news\" | \"pdf\" | \"github\" | \"tweet\" | \"personal site\" | \"linkedin profile\" | \"financial report\";\n includeText?: string[];\n excludeText?: string[];\n flags?: string[];\n};\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} RegularSearchOptions\n */\nexport type RegularSearchOptions = BaseSearchOptions & {\n useAutoprompt?: boolean;\n type?: \"keyword\" | \"neural\" | \"auto\";\n};\n\n/**\n * Options for finding similar links.\n * @typedef {Object} FindSimilarOptions\n * @property {boolean} [excludeSourceDomain] - If true, excludes links from the base domain of the input.\n */\nexport type FindSimilarOptions = BaseSearchOptions & {\n excludeSourceDomain?: boolean;\n};\n\nexport type ExtrasOptions = { links?: number; imageLinks?: number };\n\n/**\n * Search options for performing a search query.\n * @typedef {Object} ContentsOptions\n * @property {TextContentsOptions | boolean} [text] - Options for retrieving text contents.\n * @property {HighlightsContentsOptions | boolean} [highlights] - Options for retrieving highlights.\n * @property {SummaryContentsOptions | boolean} [summary] - Options for retrieving summary.\n * @property {LivecrawlOptions} [livecrawl] - Options for livecrawling contents. Default is \"never\" for neural/auto search, \"fallback\" for keyword search.\n * @property {number} [livecrawlTimeout] - The timeout for livecrawling. Max and default is 10000ms.\n * @property {boolean} [filterEmptyResults] - If true, filters out results with no contents. Default is true.\n * @property {number} [subpages] - The number of subpages to return for each result, where each subpage is derived from an internal link for the result.\n * @property {string | string[]} [subpageTarget] - Text used to match/rank subpages in the returned subpage list. You could use \"about\" to get *about* page for websites. Note that this is a fuzzy matcher.\n * @property {ExtrasOptions} [extras] - Miscelleneous data for derived from results\n */\nexport type ContentsOptions = {\n text?: TextContentsOptions | true;\n highlights?: HighlightsContentsOptions | true;\n summary?: SummaryContentsOptions | true;\n livecrawl?: LivecrawlOptions;\n livecrawlTimeout?: number;\n filterEmptyResults?: boolean;\n subpages?: number;\n subpageTarget?: string | string[];\n extras?: ExtrasOptions;\n} & (typeof isBeta extends true ? {} : {});\n\n/**\n * Options for livecrawling contents\n * @typedef {string} LivecrawlOptions\n */\nexport type LivecrawlOptions = \"never\" | \"fallback\" | \"always\" | \"auto\";\n\n/**\n * Options for retrieving text from page.\n * @typedef {Object} TextContentsOptions\n * @property {number} [maxCharacters] - The maximum number of characters to return.\n * @property {boolean} [includeHtmlTags] - If true, includes HTML tags in the returned text. Default: false\n */\nexport type TextContentsOptions = {\n maxCharacters?: number;\n includeHtmlTags?: boolean;\n};\n\n/**\n * Options for retrieving highlights from page.\n * @typedef {Object} HighlightsContentsOptions\n * @property {string} [query] - The query string to use for highlights search.\n * @property {number} [numSentences] - The number of sentences to return for each highlight.\n * @property {number} [highlightsPerUrl] - The number of highlights to return for each URL.\n */\nexport type HighlightsContentsOptions = {\n query?: string;\n numSentences?: number;\n highlightsPerUrl?: number;\n};\n\n/**\n * Options for retrieving summary from page.\n * @typedef {Object} SummaryContentsOptions\n * @property {string} [query] - The query string to use for summary generation.\n */\nexport type SummaryContentsOptions = {\n query?: string;\n};\n\n/**\n * @typedef {Object} TextResponse\n * @property {string} text - Text from page\n */\nexport type TextResponse = { text: string };\n\n/**\n * @typedef {Object} HighlightsResponse\n * @property {string[]} highlights - The highlights as an array of strings.\n * @property {number[]} highlightScores - The corresponding scores as an array of floats, 0 to 1\n */\nexport type HighlightsResponse = {\n highlights: string[];\n highlightScores: number[];\n};\n\n/**\n * @typedef {Object} SummaryResponse\n * @property {string} summary - The generated summary of the page content.\n */\nexport type SummaryResponse = { summary: string };\n\n/**\n * @typedef {Object} ExtrasResponse\n * @property {string[]} links - The links on the page of a result\n * @property {string[]} imageLinks - The image links on the page of a result\n */\nexport type ExtrasResponse = { extras: { links?: string[]; imageLinks?: string[] } };\n\n/**\n * @typedef {Object} SubpagesResponse\n * @property {ContentsResultComponent<T extends ContentsOptions>} subpages - The links on the page of a result\n */\nexport type SubpagesResponse<T extends ContentsOptions> = {\n subpages: ContentsResultComponent<T>[];\n};\n\nexport type Default<T extends {}, U> = [keyof T] extends [never] ? U : T;\n\n/**\n * @typedef {Object} ContentsResultComponent\n * Depending on 'ContentsOptions', this yields a combination of 'TextResponse', 'HighlightsResponse', 'SummaryResponse', or an empty object.\n *\n * @template T - A type extending from 'ContentsOptions'.\n */\nexport type ContentsResultComponent<T extends ContentsOptions> = Default<\n (T[\"text\"] extends object | true ? TextResponse : {}) &\n (T[\"highlights\"] extends object | true ? HighlightsResponse : {}) &\n (T[\"summary\"] extends object | true ? SummaryResponse : {}) &\n (T[\"subpages\"] extends number ? SubpagesResponse<T> : {}) &\n (T[\"extras\"] extends object ? ExtrasResponse : {}),\n TextResponse\n>;\n\n/**\n * Represents a search result object.\n * @typedef {Object} SearchResult\n * @property {string} title - The title of the search result.\n * @property {string} url - The URL of the search result.\n * @property {string} [publishedDate] - The estimated creation date of the content.\n * @property {string} [author] - The author of the content, if available.\n * @property {number} [score] - Similarity score between the query/url and the result.\n * @property {string} id - The temporary ID for the document.\n */\nexport type SearchResult<T extends ContentsOptions> = {\n title: string | null;\n url: string;\n publishedDate?: string;\n author?: string;\n score?: number;\n id: string;\n image?: string;\n favicon?: string;\n} & ContentsResultComponent<T>;\n\n/**\n * Represents a search response object.\n * @typedef {Object} SearchResponse\n * @property {Result[]} results - The list of search results.\n * @property {string} [autopromptString] - The autoprompt string, if applicable.\n * @property {string} [autoDate] - The autoprompt date, if applicable.\n * @property {string} requestId - The request ID for the search.\n */\nexport type SearchResponse<T extends ContentsOptions> = {\n results: SearchResult<T>[];\n autopromptString?: string;\n autoDate?: string;\n requestId: string;\n};\n\n/**\n * Options for the answer endpoint\n * @typedef {Object} AnswerOptions\n * @property {number} [expandedQueriesLimit] - Maximum number of query variations (0-4). Default 1.\n * @property {boolean} [stream] - Whether to stream the response. Default false.\n * @property {boolean} [includeText] - Whether to include text in the source results. Default false.\n */\nexport type AnswerOptions = {\n expandedQueriesLimit?: number;\n stream?: boolean;\n includeText?: boolean;\n};\n\n/**\n * Represents an answer response object from the /answer endpoint.\n * @typedef {Object} AnswerResponse\n * @property {string} answer - The generated answer text.\n * @property {SearchResult<{}>[]]} sources - The sources used to generate the answer.\n * @property {string} [requestId] - Optional request ID for the answer.\n */\nexport type AnswerResponse = {\n answer: string;\n sources: SearchResult<{}>[];\n requestId?: string;\n};\n\n/**\n * Represents a streaming answer response chunk from the /answer endpoint.\n * @typedef {Object} AnswerStreamResponse\n * @property {string} [answer] - A chunk of the generated answer text.\n * @property {SearchResult<{}>[]]} [sources] - The sources used to generate the answer.\n * @property {string} [error] - Error message if something went wrong.\n */\nexport type AnswerStreamResponse = {\n answer?: string;\n sources?: SearchResult<{}>[];\n error?: string;\n};\n\n/**\n * The Exa class encapsulates the API's endpoints.\n */\nclass Exa {\n private baseURL: string;\n private headers: Headers;\n\n private extractContentsOptions<T extends ContentsOptions>(options: T): {\n contentsOptions: ContentsOptions;\n restOptions: Omit<T, keyof ContentsOptions>;\n } {\n const {\n text,\n highlights,\n summary,\n subpages,\n subpageTarget,\n extras,\n livecrawl,\n livecrawlTimeout,\n ...rest\n } = options;\n\n const contentsOptions: ContentsOptions = {};\n // don't send text if it's explicitly false\n if (\n text === undefined &&\n summary === undefined &&\n highlights === undefined &&\n extras === undefined\n )\n contentsOptions.text = true;\n if (text !== undefined) contentsOptions.text = text;\n\n if (summary !== undefined) contentsOptions.summary = summary;\n if (highlights !== undefined) contentsOptions.highlights = highlights;\n\n if (subpages !== undefined) contentsOptions.subpages = subpages;\n if (subpageTarget !== undefined)\n contentsOptions.subpageTarget = subpageTarget;\n\n if (extras !== undefined) contentsOptions.extras = extras;\n if (livecrawl !== undefined) contentsOptions.livecrawl = livecrawl;\n if (livecrawlTimeout !== undefined)\n contentsOptions.livecrawlTimeout = livecrawlTimeout;\n\n return {\n contentsOptions: contentsOptions,\n restOptions: rest as Omit<T, keyof ContentsOptions>,\n };\n }\n\n /**\n * Constructs the Exa API client.\n * @param {string} apiKey - The API key for authentication.\n * @param {string} [baseURL] - The base URL of the Exa API.\n */\n constructor(apiKey?: string, baseURL: string = \"https://api.exa.ai\") {\n this.baseURL = baseURL;\n if (!apiKey) {\n apiKey = process.env.EXASEARCH_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"API key must be provided as an argument or as an environment variable (EXASEARCH_API_KEY)\",\n );\n }\n }\n this.headers = new HeadersImpl({\n \"x-api-key\": apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"exa-node 1.4.0\",\n });\n }\n\n /**\n * Makes a request to the Exa API.\n * @param {string} endpoint - The API endpoint to call.\n * @param {string} method - The HTTP method to use.\n * @param {any} [body] - The request body for POST requests.\n * @param {boolean} [stream] - Whether to stream the response.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<any>} The response from the API.\n */\n private async request(\n endpoint: string,\n method: string,\n body?: any,\n stream?: boolean,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<any> {\n const response = await fetchImpl(this.baseURL + endpoint, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const message = (await response.json()).error;\n throw new Error(\n `Request failed with status ${response.status}. ${message}`,\n );\n }\n\n /**\n * Handle streaming responses from the API. This processes Server-Sent Events (SSE)\n * where data is sent in chunks with the format \"data: {...}\". Each chunk is decoded,\n * parsed as JSON, and passed to the provided callback function.\n */\n if (stream && response.body) {\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n try {\n const data = JSON.parse(line.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n }\n }\n\n if (buffer && buffer.startsWith('data: ')) {\n try {\n const data = JSON.parse(buffer.slice(6));\n onChunk?.(data);\n } catch (e) {\n }\n }\n } catch (error: any) {\n throw new Error(`Streaming error: ${error?.message || 'Unknown error'}`);\n } finally {\n reader.releaseLock();\n }\n\n return null;\n }\n return await response.json();\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions} [options] - Additional search options.\n * @returns {Promise<SearchResponse<{}>>} A list of relevant search results.\n */\n async search(\n query: string,\n options?: RegularSearchOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/search\", \"POST\", { query, ...options });\n }\n\n /**\n * Performs a search with an Exa prompt-engineered query and returns the contents of the documents.\n * @param {string} query - The query string.\n * @param {RegularSearchOptions & T} [options] - Additional search + contents options.\n * @returns {Promise<SearchResponse<T>>} A list of relevant search results.\n */\n async searchAndContents<T extends ContentsOptions>(\n query: string,\n options?: RegularSearchOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/search\", \"POST\", {\n query,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Finds similar links to the provided URL.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions} [options] - Additional options for finding similar links.\n * @returns {Promise<SearchResponse<{}>>} A list of similar search results.\n */\n async findSimilar(\n url: string,\n options?: FindSimilarOptions,\n ): Promise<SearchResponse<{}>> {\n return await this.request(\"/findSimilar\", \"POST\", { url, ...options });\n }\n\n /**\n * Finds similar links to the provided URL and returns the contents of the documents.\n * @param {string} url - The URL for which to find similar links.\n * @param {FindSimilarOptions & T} [options] - Additional options for finding similar links + contents.\n * @returns {Promise<SearchResponse<T>>} A list of similar search results.\n */\n async findSimilarAndContents<T extends ContentsOptions>(\n url: string,\n options?: FindSimilarOptions & T,\n ): Promise<SearchResponse<T>> {\n const { contentsOptions, restOptions } =\n options === undefined\n ? { contentsOptions: { text: true }, restOptions: {} }\n : this.extractContentsOptions(options);\n\n return await this.request(\"/findSimilar\", \"POST\", {\n url,\n contents: contentsOptions,\n ...restOptions,\n });\n }\n\n /**\n * Retrieves contents of documents based on URLs\n * @param {string | string[] | SearchResult[]} urls - An array of URLs.\n * @param {ContentsOptions} [options] - Additional options for retrieving document contents.\n * @returns {Promise<SearchResponse<T>>} A list of document contents.\n */\n async getContents<T extends ContentsOptions>(\n urls: string | string[] | SearchResult<T>[],\n options?: T,\n ): Promise<SearchResponse<T>> {\n if (urls.length === 0) {\n throw new Error(\"Must provide at least one URL\");\n }\n let requestUrls: string[];\n if (typeof urls === \"string\") {\n requestUrls = [urls];\n } else if (typeof urls[0] === \"string\") {\n requestUrls = urls as string[];\n } else {\n requestUrls = (urls as SearchResult<T>[]).map((result) => result.url);\n }\n const payload = {\n urls: requestUrls,\n ...options,\n };\n\n return await this.request(`/contents`, \"POST\", payload);\n }\n\n /**\n * Generates an answer to a query using search results as context.\n * @param {string} query - The question or query to answer.\n * @param {AnswerOptions} [options] - Additional options for answer generation.\n * @param {(chunk: AnswerStreamResponse) => void} [onChunk] - Callback for handling stream chunks.\n * @returns {Promise<AnswerResponse | null>} The generated answer and source references, or null if streaming.\n */\n async answer(\n query: string,\n options?: AnswerOptions,\n onChunk?: (chunk: AnswerStreamResponse) => void,\n ): Promise<AnswerResponse | null> {\n const requestBody = {\n query,\n expandedQueriesLimit: options?.expandedQueriesLimit ?? 1,\n stream: options?.stream ?? false,\n includeText: options?.includeText ?? false\n };\n return await this.request(\"/answer\", \"POST\", requestBody, options?.stream, onChunk);\n }\n}\n\nexport default Exa;\n"],"mappings":"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","names":[]}
|