exa-js 1.7.0 → 1.7.1
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 +82 -31
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- 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
|
@@ -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(
|
|
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(
|
|
45
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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(
|
|
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(
|
|
127
|
+
const response = await exa.search("funny article about tech culture", {
|
|
90
128
|
numResults: 5,
|
|
91
|
-
includeDomains: [
|
|
92
|
-
startPublishedDate:
|
|
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(
|
|
101
|
-
|
|
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([
|
|
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(
|
|
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,17 @@ 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?", {
|
|
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
|
|
|
143
193
|
# Contributing
|
|
194
|
+
|
|
144
195
|
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
|
@@ -1644,23 +1644,25 @@ type SearchResponse<T extends ContentsOptions> = {
|
|
|
1644
1644
|
* @property {boolean} [text] - Whether to include text in the source results. Default false.
|
|
1645
1645
|
* @property {"exa" | "exa-pro"} [model] - The model to use for generating the answer. Default "exa".
|
|
1646
1646
|
* @property {string} [systemPrompt] - A system prompt to guide the LLM's behavior when generating the answer.
|
|
1647
|
+
* @property {Object} [outputSchema] - A JSON Schema specification for the structure you expect the output to take
|
|
1647
1648
|
*/
|
|
1648
1649
|
type AnswerOptions = {
|
|
1649
1650
|
stream?: boolean;
|
|
1650
1651
|
text?: boolean;
|
|
1651
1652
|
model?: "exa" | "exa-pro";
|
|
1652
1653
|
systemPrompt?: string;
|
|
1654
|
+
outputSchema?: Record<string, unknown>;
|
|
1653
1655
|
};
|
|
1654
1656
|
/**
|
|
1655
1657
|
* Represents an answer response object from the /answer endpoint.
|
|
1656
1658
|
* @typedef {Object} AnswerResponse
|
|
1657
|
-
* @property {string} answer - The generated answer text
|
|
1659
|
+
* @property {string | Object} answer - The generated answer text (or an object matching `outputSchema`, if provided)
|
|
1658
1660
|
* @property {SearchResult<{}>[]} citations - The sources used to generate the answer.
|
|
1659
1661
|
* @property {CostDollars} [costDollars] - The cost breakdown for this request.
|
|
1660
1662
|
* @property {string} [requestId] - Optional request ID for the answer.
|
|
1661
1663
|
*/
|
|
1662
1664
|
type AnswerResponse = {
|
|
1663
|
-
answer: string
|
|
1665
|
+
answer: string | Record<string, unknown>;
|
|
1664
1666
|
citations: SearchResult<{}>[];
|
|
1665
1667
|
requestId?: string;
|
|
1666
1668
|
costDollars?: CostDollars;
|
|
@@ -1828,6 +1830,7 @@ declare class Exa {
|
|
|
1828
1830
|
text?: boolean;
|
|
1829
1831
|
model?: "exa" | "exa-pro";
|
|
1830
1832
|
systemPrompt?: string;
|
|
1833
|
+
outputSchema?: Record<string, unknown>;
|
|
1831
1834
|
}): AsyncGenerator<AnswerStreamChunk>;
|
|
1832
1835
|
private processChunk;
|
|
1833
1836
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1644,23 +1644,25 @@ type SearchResponse<T extends ContentsOptions> = {
|
|
|
1644
1644
|
* @property {boolean} [text] - Whether to include text in the source results. Default false.
|
|
1645
1645
|
* @property {"exa" | "exa-pro"} [model] - The model to use for generating the answer. Default "exa".
|
|
1646
1646
|
* @property {string} [systemPrompt] - A system prompt to guide the LLM's behavior when generating the answer.
|
|
1647
|
+
* @property {Object} [outputSchema] - A JSON Schema specification for the structure you expect the output to take
|
|
1647
1648
|
*/
|
|
1648
1649
|
type AnswerOptions = {
|
|
1649
1650
|
stream?: boolean;
|
|
1650
1651
|
text?: boolean;
|
|
1651
1652
|
model?: "exa" | "exa-pro";
|
|
1652
1653
|
systemPrompt?: string;
|
|
1654
|
+
outputSchema?: Record<string, unknown>;
|
|
1653
1655
|
};
|
|
1654
1656
|
/**
|
|
1655
1657
|
* Represents an answer response object from the /answer endpoint.
|
|
1656
1658
|
* @typedef {Object} AnswerResponse
|
|
1657
|
-
* @property {string} answer - The generated answer text
|
|
1659
|
+
* @property {string | Object} answer - The generated answer text (or an object matching `outputSchema`, if provided)
|
|
1658
1660
|
* @property {SearchResult<{}>[]} citations - The sources used to generate the answer.
|
|
1659
1661
|
* @property {CostDollars} [costDollars] - The cost breakdown for this request.
|
|
1660
1662
|
* @property {string} [requestId] - Optional request ID for the answer.
|
|
1661
1663
|
*/
|
|
1662
1664
|
type AnswerResponse = {
|
|
1663
|
-
answer: string
|
|
1665
|
+
answer: string | Record<string, unknown>;
|
|
1664
1666
|
citations: SearchResult<{}>[];
|
|
1665
1667
|
requestId?: string;
|
|
1666
1668
|
costDollars?: CostDollars;
|
|
@@ -1828,6 +1830,7 @@ declare class Exa {
|
|
|
1828
1830
|
text?: boolean;
|
|
1829
1831
|
model?: "exa" | "exa-pro";
|
|
1830
1832
|
systemPrompt?: string;
|
|
1833
|
+
outputSchema?: Record<string, unknown>;
|
|
1831
1834
|
}): AsyncGenerator<AnswerStreamChunk>;
|
|
1832
1835
|
private processChunk;
|
|
1833
1836
|
/**
|
package/dist/index.js
CHANGED
|
@@ -915,7 +915,8 @@ var Exa2 = class {
|
|
|
915
915
|
stream: false,
|
|
916
916
|
text: options?.text ?? false,
|
|
917
917
|
model: options?.model ?? "exa",
|
|
918
|
-
systemPrompt: options?.systemPrompt
|
|
918
|
+
systemPrompt: options?.systemPrompt,
|
|
919
|
+
outputSchema: options?.outputSchema
|
|
919
920
|
};
|
|
920
921
|
return await this.request("/answer", "POST", requestBody);
|
|
921
922
|
}
|
|
@@ -944,7 +945,8 @@ var Exa2 = class {
|
|
|
944
945
|
text: options?.text ?? false,
|
|
945
946
|
stream: true,
|
|
946
947
|
model: options?.model ?? "exa",
|
|
947
|
-
systemPrompt: options?.systemPrompt
|
|
948
|
+
systemPrompt: options?.systemPrompt,
|
|
949
|
+
outputSchema: options?.outputSchema
|
|
948
950
|
};
|
|
949
951
|
const response = await fetchImpl(this.baseURL + "/answer", {
|
|
950
952
|
method: "POST",
|