exa-js 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,71 +8,91 @@ features associated with Metaphor's rename to Exa. New site is https://exa.ai
8
8
  https://www.npmjs.com/package/exa-js
9
9
 
10
10
  ## Installation
11
+
11
12
  ```
12
13
  npm install exa-js
13
14
  ```
14
15
 
15
- ## Initialization
16
+ ## Initialization
17
+
16
18
  ```js
17
- import Exa from "exa-js"
19
+ import Exa from "exa-js";
18
20
 
19
- const exa = new Exa(process.env.EXA_API_KEY)
21
+ const exa = new Exa(process.env.EXA_API_KEY);
20
22
  ```
21
23
 
22
24
  ### Common commands
23
25
 
24
26
  ```js
25
-
26
27
  // Basic search
27
28
  const basicResults = await exa.search("This is a Exa query:");
28
29
 
29
30
  // Search with date filters
30
31
  const dateFilteredResults = await exa.search("This is a Exa query:", {
31
32
  startPublishedDate: "2019-01-01",
32
- endPublishedDate: "2019-01-31"
33
+ endPublishedDate: "2019-01-31",
33
34
  });
34
35
 
35
36
  // Search with domain filters
36
37
  const domainFilteredResults = await exa.search("This is a Exa query:", {
37
- includeDomains: ["www.cnn.com", "www.nytimes.com"]
38
+ includeDomains: ["www.cnn.com", "www.nytimes.com"],
38
39
  });
39
40
 
40
41
  // Search and get text contents
41
- const searchAndTextResults = await exa.searchAndContents("This is a Exa query:", { text: true });
42
+ const searchAndTextResults = await exa.searchAndContents(
43
+ "This is a Exa query:",
44
+ { text: true }
45
+ );
42
46
 
43
47
  // Search and get contents with contents options
44
- const searchAndCustomContentsResults = await exa.searchAndContents("This is a Exa query:", {
45
- text: { maxCharacters: 3000 }
46
- });
48
+ const searchAndCustomContentsResults = await exa.searchAndContents(
49
+ "This is a Exa query:",
50
+ {
51
+ text: { maxCharacters: 3000 },
52
+ }
53
+ );
47
54
 
48
55
  // Find similar documents
49
56
  const similarResults = await exa.findSimilar("https://example.com");
50
57
 
51
58
  // Find similar excluding source domain
52
- const similarExcludingSourceResults = await exa.findSimilar("https://example.com", { excludeSourceDomain: true });
59
+ const similarExcludingSourceResults = await exa.findSimilar(
60
+ "https://example.com",
61
+ { excludeSourceDomain: true }
62
+ );
53
63
 
54
64
  // Find similar with contents
55
- const similarWithContentsResults = await exa.findSimilarAndContents("https://example.com", { text: true });
65
+ const similarWithContentsResults = await exa.findSimilarAndContents(
66
+ "https://example.com",
67
+ { text: true }
68
+ );
56
69
 
57
70
  // Get text contents
58
71
  const textContentsResults = await exa.getContents(["urls"], { text: true });
59
72
 
60
73
  // Get contents with contents options
61
74
  const customContentsResults = await exa.getContents(["urls"], {
62
- text: { includeHtmlTags: true, maxCharacters: 3000 }
75
+ text: { includeHtmlTags: true, maxCharacters: 3000 },
63
76
  });
64
77
 
65
78
  // Get an answer to a question
66
- const answerResult = await exa.answer("What is the population of New York City?");
67
-
68
- // Get answer with citation contents and use the exa-pro model, which passes 2 extra queries to exa to increase coverage of the search space.
69
- const answerWithTextResults = await exa.answer("What is the population of New York City?", {
70
- text: true,
71
- model: "exa-pro"
72
- });
79
+ const answerResult = await exa.answer(
80
+ "What is the population of New York City?"
81
+ );
82
+
83
+ // Get answer with citation contents and use the exa-pro model, which passes 2 extra queries to exa to increase coverage of the search space.
84
+ const answerWithTextResults = await exa.answer(
85
+ "What is the population of New York City?",
86
+ {
87
+ text: true,
88
+ model: "exa-pro",
89
+ }
90
+ );
73
91
 
74
92
  // Get an answer with streaming
75
- for await (const chunk of exa.streamAnswer("What is the population of New York City?")) {
93
+ for await (const chunk of exa.streamAnswer(
94
+ "What is the population of New York City?"
95
+ )) {
76
96
  if (chunk.content) {
77
97
  process.stdout.write(chunk.content);
78
98
  }
@@ -80,45 +100,72 @@ for await (const chunk of exa.streamAnswer("What is the population of New York C
80
100
  console.log("\nCitations:", chunk.citations);
81
101
  }
82
102
  }
103
+
104
+ // Get an answer with output schema
105
+ const answerResult = await exa.answer(
106
+ "What is the population of New York City?",
107
+ {
108
+ outputSchema: {
109
+ type: "object",
110
+ required: ["answer"],
111
+ additionalProperties: false,
112
+ properties: {
113
+ answer: {
114
+ type: "number",
115
+ },
116
+ },
117
+ },
118
+ }
119
+ );
83
120
  ```
84
121
 
85
122
  ### `exa.search(query: string, options?: SearchOptions): Promise<SearchResponse>`
123
+
86
124
  Performs a search on the Exa system with the given parameters.
87
125
 
88
126
  ```javascript
89
- const response = await exa.search('funny article about tech culture', {
127
+ const response = await exa.search("funny article about tech culture", {
90
128
  numResults: 5,
91
- includeDomains: ['nytimes.com', 'wsj.com'],
92
- startPublishedDate: '2023-06-12'
129
+ includeDomains: ["nytimes.com", "wsj.com"],
130
+ startPublishedDate: "2023-06-12",
93
131
  });
94
132
  ```
95
133
 
96
134
  ### `exa.findSimilar(url: string, options?: FindSimilarOptions): Promise<SearchResponse>`
135
+
97
136
  Finds content similar to the specified URL.
98
137
 
99
138
  ```javascript
100
- const response = await exa.findSimilar('https://waitbutwhy.com/2014/05/fermi-paradox.html', {
101
- numResults: 10
102
- });
139
+ const response = await exa.findSimilar(
140
+ "https://waitbutwhy.com/2014/05/fermi-paradox.html",
141
+ {
142
+ numResults: 10,
143
+ }
144
+ );
103
145
  ```
104
146
 
105
147
  ### `exa.getContents(urls: string[] | Result[]): Promise<GetContentsResponse>`
148
+
106
149
  Retrieves the contents of the specified documents.
107
150
 
108
151
  ```javascript
109
- const response = await exa.getContents(['https://blog.samaltman.com/how-to-be-successful']);
152
+ const response = await exa.getContents([
153
+ "https://blog.samaltman.com/how-to-be-successful",
154
+ ]);
110
155
  ```
111
156
 
112
157
  ### `exa.answer(query: string, options?: AnswerOptions): Promise<AnswerResponse>`
158
+
113
159
  Generates an answer to a query using search results as context.
114
160
 
115
161
  ```javascript
116
- const response = await exa.answer('What is the population of New York City?', {
117
- text: true
162
+ const response = await exa.answer("What is the population of New York City?", {
163
+ text: true,
118
164
  });
119
165
  ```
120
166
 
121
167
  ### `exa.streamAnswer(query: string, options?: { text?: boolean }): AsyncGenerator<AnswerStreamChunk>`
168
+
122
169
  Streams an answer as it's being generated, yielding chunks of text and citations. This is useful for providing real-time updates in chat interfaces or displaying partial results as they become available.
123
170
 
124
171
  ```javascript
@@ -132,13 +179,44 @@ for await (const chunk of exa.streamAnswer("What is quantum computing?")) {
132
179
  }
133
180
  }
134
181
 
135
- for await (const chunk of exa.streamAnswer("What is quantum computing?", { text: true })) {
182
+ for await (const chunk of exa.streamAnswer("What is quantum computing?", {
183
+ text: true,
184
+ })) {
136
185
  }
137
186
  ```
138
187
 
139
188
  Each chunk contains:
189
+
140
190
  - `content`: A string containing the next piece of generated text
141
191
  - `citations`: An array of citation objects containing source information
142
192
 
193
+ ### `exa.research.createTask(input: object, options?: { schema?: object }): Promise<ResearchTaskResponse>`
194
+
195
+ Exa's research agent can autonomously gather information and return a structured JSON object that conforms to a schema you provide.
196
+
197
+ ```javascript
198
+ import Exa from "exa-js";
199
+
200
+ const exa = new Exa(process.env.EXA_API_KEY);
201
+
202
+ const schema = {
203
+ type: "object",
204
+ required: ["answer"],
205
+ properties: {
206
+ answer: { type: "string" },
207
+ },
208
+ };
209
+
210
+ const response = await exa.research.createTask(
211
+ {
212
+ instructions: "In ≤3 sentences, explain quantum computing.",
213
+ },
214
+ { schema }
215
+ );
216
+ ```
217
+
218
+ Use the `status` field to poll long-running tasks if needed (a future `getTask` helper will be added when the async API is released).
219
+
143
220
  # Contributing
221
+
144
222
  Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
package/dist/index.d.mts CHANGED
@@ -5,11 +5,11 @@
5
5
  /**
6
6
  * Type for API query parameters
7
7
  */
8
- type QueryParams = Record<string, string | number | boolean | string[] | undefined>;
8
+ type QueryParams$1 = Record<string, string | number | boolean | string[] | undefined>;
9
9
  /**
10
10
  * Type for API request body
11
11
  */
12
- interface RequestBody {
12
+ interface RequestBody$1 {
13
13
  [key: string]: unknown;
14
14
  }
15
15
  /**
@@ -44,13 +44,13 @@ declare class WebsetsBaseClient {
44
44
  * @returns The response JSON
45
45
  * @throws ExaError with API error details if the request fails
46
46
  */
47
- protected request<T = unknown>(endpoint: string, method?: string, data?: RequestBody, params?: QueryParams): Promise<T>;
47
+ protected request<T = unknown>(endpoint: string, method?: string, data?: RequestBody$1, params?: QueryParams$1): Promise<T>;
48
48
  /**
49
49
  * Helper to build pagination parameters
50
50
  * @param pagination The pagination parameters
51
51
  * @returns QueryParams object with pagination parameters
52
52
  */
53
- protected buildPaginationParams(pagination?: PaginationParams): QueryParams;
53
+ protected buildPaginationParams(pagination?: PaginationParams): QueryParams$1;
54
54
  }
55
55
 
56
56
  interface components {
@@ -1340,6 +1340,93 @@ declare class WebsetsClient extends WebsetsBaseClient {
1340
1340
  } | number): Promise<Webset>;
1341
1341
  }
1342
1342
 
1343
+ /**
1344
+ * Enum representing the status of a research task.
1345
+ */
1346
+ declare enum ResearchStatus {
1347
+ /** The research request has finished successfully. */
1348
+ completed = "completed",
1349
+ /** The research request failed. */
1350
+ failed = "failed"
1351
+ }
1352
+ /**
1353
+ * Response object returned from the research API.
1354
+ */
1355
+ type ResearchTaskResponse = {
1356
+ /** Unique identifier for the task. */
1357
+ id: string;
1358
+ /** Current status (may include future enum values served by the API). */
1359
+ status: ResearchStatus | string;
1360
+ /** Structured output that follows the user-provided schema (null while running). */
1361
+ output: Record<string, any> | null;
1362
+ /**
1363
+ * Citations collected while deriving each top-level field in `output`.
1364
+ * The key is the field name, the value is the list of `SearchResult`s that
1365
+ * were used to compute that field.
1366
+ */
1367
+ citations: Record<string, SearchResult<{}>[]>;
1368
+ };
1369
+
1370
+ type QueryParams = Record<string, string | number | boolean | string[] | undefined>;
1371
+ interface RequestBody {
1372
+ [key: string]: unknown;
1373
+ }
1374
+ /**
1375
+ * Base client class for all Research-related API clients
1376
+ */
1377
+ declare class ResearchBaseClient {
1378
+ protected client: Exa;
1379
+ /**
1380
+ * Initialize a new Research base client
1381
+ * @param client The Exa client instance
1382
+ */
1383
+ constructor(client: Exa);
1384
+ /**
1385
+ * Make a request to the Research API (prefixes all paths with `/research`).
1386
+ * @param endpoint The endpoint path, beginning with a slash (e.g. "/tasks").
1387
+ * @param method The HTTP method. Defaults to "POST".
1388
+ * @param data Optional request body
1389
+ * @param params Optional query parameters
1390
+ * @returns The parsed JSON response
1391
+ */
1392
+ protected request<T = unknown>(endpoint: string, method?: string, data?: RequestBody, params?: QueryParams): Promise<T>;
1393
+ }
1394
+
1395
+ /**
1396
+ * Client for interacting with the Research Tasks API.
1397
+ */
1398
+ declare class ResearchClient extends ResearchBaseClient {
1399
+ constructor(client: Exa);
1400
+ /**
1401
+ * Create and run a research task (blocking call).
1402
+ *
1403
+ * Both parameters are required and have fixed shapes:
1404
+ * 1. `input`
1405
+ * `{ instructions: string }`
1406
+ * • `instructions` – High-level guidance that tells the research agent what to do.
1407
+ * 2. `output`
1408
+ * defines the exact structure you expect back, and guides the research conducted by the agent.
1409
+ * `{ schema: JSONSchema }`.
1410
+ * The agent's response will be validated against this schema.
1411
+ *
1412
+ * @param input Object containing high-level research instructions.
1413
+ * @param output Object containing the expected output schema.
1414
+ * @returns The ResearchTaskResponse returned by the API.
1415
+ */
1416
+ createTask(input: {
1417
+ instructions: string;
1418
+ }, output: {
1419
+ schema: JSONSchema;
1420
+ }): Promise<ResearchTaskResponse>;
1421
+ /**
1422
+ * Retrieve a research task by ID.
1423
+ *
1424
+ * Not yet implemented server-side. Calling this will throw until the API is
1425
+ * available.
1426
+ */
1427
+ getTask(): Promise<ResearchTaskResponse>;
1428
+ }
1429
+
1343
1430
  /**
1344
1431
  * HTTP status codes
1345
1432
  */
@@ -1644,23 +1731,25 @@ type SearchResponse<T extends ContentsOptions> = {
1644
1731
  * @property {boolean} [text] - Whether to include text in the source results. Default false.
1645
1732
  * @property {"exa" | "exa-pro"} [model] - The model to use for generating the answer. Default "exa".
1646
1733
  * @property {string} [systemPrompt] - A system prompt to guide the LLM's behavior when generating the answer.
1734
+ * @property {Object} [outputSchema] - A JSON Schema specification for the structure you expect the output to take
1647
1735
  */
1648
1736
  type AnswerOptions = {
1649
1737
  stream?: boolean;
1650
1738
  text?: boolean;
1651
1739
  model?: "exa" | "exa-pro";
1652
1740
  systemPrompt?: string;
1741
+ outputSchema?: Record<string, unknown>;
1653
1742
  };
1654
1743
  /**
1655
1744
  * Represents an answer response object from the /answer endpoint.
1656
1745
  * @typedef {Object} AnswerResponse
1657
- * @property {string} answer - The generated answer text.
1746
+ * @property {string | Object} answer - The generated answer text (or an object matching `outputSchema`, if provided)
1658
1747
  * @property {SearchResult<{}>[]} citations - The sources used to generate the answer.
1659
1748
  * @property {CostDollars} [costDollars] - The cost breakdown for this request.
1660
1749
  * @property {string} [requestId] - Optional request ID for the answer.
1661
1750
  */
1662
1751
  type AnswerResponse = {
1663
- answer: string;
1752
+ answer: string | Record<string, unknown>;
1664
1753
  citations: SearchResult<{}>[];
1665
1754
  requestId?: string;
1666
1755
  costDollars?: CostDollars;
@@ -1692,29 +1781,6 @@ type AnswerStreamResponse = {
1692
1781
  answer?: string;
1693
1782
  citations?: SearchResult<{}>[];
1694
1783
  };
1695
- /**
1696
- * Enum representing the status of a research task.
1697
- */
1698
- declare enum ResearchStatus {
1699
- /** The research request has finished successfully. */
1700
- completed = "completed",
1701
- /** The research request failed. */
1702
- failed = "failed"
1703
- }
1704
- /**
1705
- * @typedef {Object} ResearchTaskResponse
1706
- * @property {string} id - The unique identifier of the research request.
1707
- * @property {ResearchStatus | string} status - The current status of the research request.
1708
- * @property {Record<string, any> | null} output - The structured output, if the research has completed.
1709
- * @property {SearchResult<{}>[]} citations - References used for the research.
1710
- */
1711
- type ResearchTaskResponse = {
1712
- id: string;
1713
- status: ResearchStatus | string;
1714
- output: Record<string, any> | null;
1715
- citations: SearchResult<{}>[];
1716
- };
1717
-
1718
1784
  /**
1719
1785
  * The Exa class encapsulates the API's endpoints.
1720
1786
  */
@@ -1725,6 +1791,10 @@ declare class Exa {
1725
1791
  * Websets API client
1726
1792
  */
1727
1793
  websets: WebsetsClient;
1794
+ /**
1795
+ * Research API client
1796
+ */
1797
+ research: ResearchClient;
1728
1798
  /**
1729
1799
  * Helper method to separate out the contents-specific options from the rest.
1730
1800
  */
@@ -1828,44 +1898,10 @@ declare class Exa {
1828
1898
  text?: boolean;
1829
1899
  model?: "exa" | "exa-pro";
1830
1900
  systemPrompt?: string;
1901
+ outputSchema?: Record<string, unknown>;
1831
1902
  }): AsyncGenerator<AnswerStreamChunk>;
1832
1903
  private processChunk;
1833
- /**
1834
- * Creates and runs a research task in a blocking manner.
1835
- *
1836
- * Both parameters are required and have fixed shapes:
1837
- * 1. `input`
1838
- * `{ instructions: string }`
1839
- * • `instructions` – High-level guidance that tells the research agent what to do.
1840
- * 2. `output`
1841
- * defines the exact structure you expect back, and guides the research conducted by the agent.
1842
- * `{ schema: JSONSchema }`.
1843
- * The agent’s response will be validated against this schema.
1844
- *
1845
- * @param {{ instructions: string }} input The research prompt.
1846
- * @param {{ schema: JSONSchema }} output The desired output schema.
1847
- * @returns {Promise<ResearchTaskResponse>} The research response.
1848
- *
1849
- * @example
1850
- * const response = await exa.researchTask(
1851
- * { instructions: "I need a few key facts about honey pot ants." },
1852
- * {
1853
- * schema: {
1854
- * type: "object",
1855
- * required: ["scientificName", "primaryRegions"],
1856
- * properties: {
1857
- * scientificName: { type: "string" },
1858
- * primaryRegions: { type: "string" },
1859
- * },
1860
- * },
1861
- * },
1862
- * );
1863
- */
1864
- researchTask(input: {
1865
- instructions: string;
1866
- }, output: {
1867
- schema: JSONSchema;
1868
- }): Promise<ResearchTaskResponse>;
1904
+ private parseSSEStream;
1869
1905
  }
1870
1906
 
1871
- export { type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamResponse, type BaseSearchOptions, type ContentsOptions, type ContentsResultComponent, type CostDollars, type CostDollarsContents, type CostDollarsSeearch, type CreateEnrichmentParameters, CreateEnrichmentParametersFormat, type CreateWebhookParameters, type CreateWebsetParameters, type CreateWebsetSearchParameters, CreateWebsetSearchParametersBehaviour, type Default, type EnrichmentResult, type Event, EventType, Exa, ExaError, type ExtrasOptions, type ExtrasResponse, type FindSimilarOptions, type GetWebsetResponse, type HighlightsContentsOptions, type HighlightsResponse, HttpStatusCode, type JSONSchema, type ListEventsResponse, type ListWebhooksOptions, type ListWebhooksResponse, type ListWebsetItemResponse, type ListWebsetsOptions, type ListWebsetsResponse, type LivecrawlOptions, type RegularSearchOptions, ResearchStatus, type ResearchTaskResponse, type SearchResponse, type SearchResult, type SubpagesResponse, type SummaryContentsOptions, type SummaryResponse, type TextContentsOptions, type TextResponse, type UpdateWebhookParameters, type UpdateWebsetRequest, type Webhook, WebhookStatus, type Webset, type WebsetEnrichment, WebsetEnrichmentFormat, WebsetEnrichmentStatus, WebsetEnrichmentsClient, type WebsetItem, WebsetItemEvaluationSatisfied, WebsetItemSource, WebsetItemsClient, type WebsetSearch, WebsetSearchCanceledReason, WebsetSearchStatus, WebsetSearchesClient, WebsetStatus, WebsetWebhooksClient, WebsetsClient, Exa as default };
1907
+ export { type AnswerOptions, type AnswerResponse, type AnswerStreamChunk, type AnswerStreamResponse, type BaseSearchOptions, type ContentsOptions, type ContentsResultComponent, type CostDollars, type CostDollarsContents, type CostDollarsSeearch, type CreateEnrichmentParameters, CreateEnrichmentParametersFormat, type CreateWebhookParameters, type CreateWebsetParameters, type CreateWebsetSearchParameters, CreateWebsetSearchParametersBehaviour, type Default, type EnrichmentResult, type Event, EventType, Exa, ExaError, type ExtrasOptions, type ExtrasResponse, type FindSimilarOptions, type GetWebsetResponse, type HighlightsContentsOptions, type HighlightsResponse, HttpStatusCode, type JSONSchema, type ListEventsResponse, type ListWebhooksOptions, type ListWebhooksResponse, type ListWebsetItemResponse, type ListWebsetsOptions, type ListWebsetsResponse, type LivecrawlOptions, type RegularSearchOptions, ResearchClient, ResearchStatus, type ResearchTaskResponse, type SearchResponse, type SearchResult, type SubpagesResponse, type SummaryContentsOptions, type SummaryResponse, type TextContentsOptions, type TextResponse, type UpdateWebhookParameters, type UpdateWebsetRequest, type Webhook, WebhookStatus, type Webset, type WebsetEnrichment, WebsetEnrichmentFormat, WebsetEnrichmentStatus, WebsetEnrichmentsClient, type WebsetItem, WebsetItemEvaluationSatisfied, WebsetItemSource, WebsetItemsClient, type WebsetSearch, WebsetSearchCanceledReason, WebsetSearchStatus, WebsetSearchesClient, WebsetStatus, WebsetWebhooksClient, WebsetsClient, Exa as default };