@keystrokehq/exa 0.0.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/dist/_official/index.d.mts +2 -0
- package/dist/_official/index.mjs +3 -0
- package/dist/index.d.mts +1261 -0
- package/dist/index.mjs +578 -0
- package/dist/integration-Bl0--6XJ.d.mts +18 -0
- package/dist/integration-C7rqRVI5.mjs +17 -0
- package/package.json +62 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
import { t as exa } from "./integration-C7rqRVI5.mjs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import Exa from "exa-js";
|
|
4
|
+
import { createOfficialOperationFactory } from "@keystrokehq/integration-authoring/official";
|
|
5
|
+
|
|
6
|
+
//#region src/client.ts
|
|
7
|
+
function createExaClient(credentials) {
|
|
8
|
+
return new Exa(credentials.EXA_API_KEY);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/factory.ts
|
|
13
|
+
const exaOperation = createOfficialOperationFactory(exa);
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/schemas.ts
|
|
17
|
+
const exaSearchResultSchema = z.object({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
url: z.string(),
|
|
20
|
+
title: z.string().nullable(),
|
|
21
|
+
publishedDate: z.string().nullable().optional(),
|
|
22
|
+
author: z.string().nullable().optional(),
|
|
23
|
+
score: z.number().optional(),
|
|
24
|
+
image: z.string().nullable().optional(),
|
|
25
|
+
favicon: z.string().nullable().optional(),
|
|
26
|
+
text: z.string().optional(),
|
|
27
|
+
highlights: z.array(z.string()).optional(),
|
|
28
|
+
highlightScores: z.array(z.number()).optional(),
|
|
29
|
+
summary: z.string().optional(),
|
|
30
|
+
subpages: z.array(z.unknown()).optional(),
|
|
31
|
+
entities: z.array(z.unknown()).optional()
|
|
32
|
+
});
|
|
33
|
+
const exaCostSchema = z.record(z.string(), z.unknown());
|
|
34
|
+
const exaSearchResponseSchema = z.object({
|
|
35
|
+
requestId: z.string().optional(),
|
|
36
|
+
results: z.array(exaSearchResultSchema),
|
|
37
|
+
searchType: z.string().optional(),
|
|
38
|
+
output: z.unknown().optional(),
|
|
39
|
+
costDollars: exaCostSchema.optional()
|
|
40
|
+
});
|
|
41
|
+
const exaContentsResponseSchema = z.object({
|
|
42
|
+
requestId: z.string().optional(),
|
|
43
|
+
results: z.array(exaSearchResultSchema),
|
|
44
|
+
statuses: z.array(z.unknown()).optional(),
|
|
45
|
+
costDollars: exaCostSchema.optional()
|
|
46
|
+
});
|
|
47
|
+
const exaAnswerCitationSchema = z.object({
|
|
48
|
+
id: z.string(),
|
|
49
|
+
url: z.string(),
|
|
50
|
+
title: z.string().nullable(),
|
|
51
|
+
author: z.string().nullable().optional(),
|
|
52
|
+
publishedDate: z.string().nullable().optional(),
|
|
53
|
+
text: z.string().optional(),
|
|
54
|
+
image: z.string().nullable().optional(),
|
|
55
|
+
favicon: z.string().nullable().optional()
|
|
56
|
+
});
|
|
57
|
+
const exaAnswerResponseSchema = z.object({
|
|
58
|
+
answer: z.union([z.string(), z.record(z.string(), z.unknown())]),
|
|
59
|
+
citations: z.array(exaAnswerCitationSchema),
|
|
60
|
+
requestId: z.string().optional(),
|
|
61
|
+
costDollars: exaCostSchema.optional()
|
|
62
|
+
});
|
|
63
|
+
const exaMonitorSchema = z.object({
|
|
64
|
+
id: z.string(),
|
|
65
|
+
name: z.string().nullable().optional(),
|
|
66
|
+
status: z.string().optional(),
|
|
67
|
+
search: z.unknown().optional(),
|
|
68
|
+
trigger: z.unknown().optional(),
|
|
69
|
+
outputSchema: z.unknown().optional(),
|
|
70
|
+
metadata: z.unknown().optional(),
|
|
71
|
+
webhook: z.unknown().optional(),
|
|
72
|
+
webhookSecret: z.string().optional(),
|
|
73
|
+
nextRunAt: z.string().nullable().optional(),
|
|
74
|
+
createdAt: z.string().optional(),
|
|
75
|
+
updatedAt: z.string().optional()
|
|
76
|
+
});
|
|
77
|
+
const exaMonitorRunSchema = z.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
monitorId: z.string(),
|
|
80
|
+
status: z.string().optional(),
|
|
81
|
+
output: z.unknown().optional(),
|
|
82
|
+
failReason: z.string().nullable().optional(),
|
|
83
|
+
startedAt: z.string().nullable().optional(),
|
|
84
|
+
completedAt: z.string().nullable().optional(),
|
|
85
|
+
durationMs: z.number().nullable().optional(),
|
|
86
|
+
createdAt: z.string().optional(),
|
|
87
|
+
updatedAt: z.string().optional()
|
|
88
|
+
});
|
|
89
|
+
const exaMonitorListResponseSchema = z.object({
|
|
90
|
+
data: z.array(exaMonitorSchema),
|
|
91
|
+
hasMore: z.boolean().optional(),
|
|
92
|
+
nextCursor: z.string().nullable().optional()
|
|
93
|
+
});
|
|
94
|
+
const exaMonitorRunListResponseSchema = z.object({
|
|
95
|
+
data: z.array(exaMonitorRunSchema),
|
|
96
|
+
hasMore: z.boolean().optional(),
|
|
97
|
+
nextCursor: z.string().nullable().optional()
|
|
98
|
+
});
|
|
99
|
+
const exaTriggerMonitorResponseSchema = z.object({ triggered: z.boolean() });
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/answer.ts
|
|
103
|
+
const answer = exaOperation({
|
|
104
|
+
id: "exa_answer",
|
|
105
|
+
name: "Exa Answer",
|
|
106
|
+
description: "Get an AI-generated answer to a query with citations from web sources using Exa.",
|
|
107
|
+
input: z.object({
|
|
108
|
+
query: z.string(),
|
|
109
|
+
text: z.boolean().optional(),
|
|
110
|
+
model: z.enum(["exa"]).optional(),
|
|
111
|
+
systemPrompt: z.string().optional(),
|
|
112
|
+
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
113
|
+
userLocation: z.string().optional()
|
|
114
|
+
}),
|
|
115
|
+
output: exaAnswerResponseSchema,
|
|
116
|
+
run: async (input, credentials) => {
|
|
117
|
+
const client = createExaClient(credentials);
|
|
118
|
+
const { query, ...options } = input;
|
|
119
|
+
return await client.answer(query, options);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
const answerTool = answer;
|
|
123
|
+
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/contents.ts
|
|
126
|
+
const getContents = exaOperation({
|
|
127
|
+
id: "exa_get_contents",
|
|
128
|
+
name: "Exa Get Contents",
|
|
129
|
+
description: "Retrieve page contents (text, highlights, summaries) for a list of URLs.",
|
|
130
|
+
input: z.object({
|
|
131
|
+
urls: z.array(z.string()).min(1),
|
|
132
|
+
text: z.union([z.literal(true), z.object({
|
|
133
|
+
maxCharacters: z.number().optional(),
|
|
134
|
+
includeHtmlTags: z.boolean().optional(),
|
|
135
|
+
verbosity: z.enum([
|
|
136
|
+
"compact",
|
|
137
|
+
"standard",
|
|
138
|
+
"full"
|
|
139
|
+
]).optional()
|
|
140
|
+
})]).optional(),
|
|
141
|
+
highlights: z.union([z.literal(true), z.object({
|
|
142
|
+
maxCharacters: z.number().optional(),
|
|
143
|
+
query: z.string().optional()
|
|
144
|
+
})]).optional(),
|
|
145
|
+
summary: z.object({
|
|
146
|
+
query: z.string().optional(),
|
|
147
|
+
schema: z.record(z.string(), z.unknown()).optional()
|
|
148
|
+
}).optional(),
|
|
149
|
+
livecrawl: z.enum([
|
|
150
|
+
"always",
|
|
151
|
+
"fallback",
|
|
152
|
+
"never",
|
|
153
|
+
"auto",
|
|
154
|
+
"preferred"
|
|
155
|
+
]).optional(),
|
|
156
|
+
livecrawlTimeout: z.number().optional(),
|
|
157
|
+
maxAgeHours: z.number().optional(),
|
|
158
|
+
subpages: z.number().optional(),
|
|
159
|
+
subpageTarget: z.union([z.string(), z.array(z.string())]).optional(),
|
|
160
|
+
extras: z.record(z.string(), z.unknown()).optional(),
|
|
161
|
+
filterEmptyResults: z.boolean().optional()
|
|
162
|
+
}),
|
|
163
|
+
output: exaContentsResponseSchema,
|
|
164
|
+
run: async (input, credentials) => {
|
|
165
|
+
const client = createExaClient(credentials);
|
|
166
|
+
const { urls, ...options } = input;
|
|
167
|
+
return await client.getContents(urls, options);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const getContentsTool = getContents;
|
|
171
|
+
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/find-similar.ts
|
|
174
|
+
const findSimilar = exaOperation({
|
|
175
|
+
id: "exa_find_similar",
|
|
176
|
+
name: "Exa Find Similar",
|
|
177
|
+
description: "Find web pages similar to a given URL.",
|
|
178
|
+
input: z.object({
|
|
179
|
+
url: z.string(),
|
|
180
|
+
excludeSourceDomain: z.boolean().optional(),
|
|
181
|
+
numResults: z.number().min(1).max(100).optional(),
|
|
182
|
+
includeDomains: z.array(z.string()).optional(),
|
|
183
|
+
excludeDomains: z.array(z.string()).optional(),
|
|
184
|
+
startCrawlDate: z.string().optional(),
|
|
185
|
+
endCrawlDate: z.string().optional(),
|
|
186
|
+
startPublishedDate: z.string().optional(),
|
|
187
|
+
endPublishedDate: z.string().optional(),
|
|
188
|
+
includeText: z.array(z.string()).optional(),
|
|
189
|
+
excludeText: z.array(z.string()).optional(),
|
|
190
|
+
moderation: z.boolean().optional()
|
|
191
|
+
}),
|
|
192
|
+
output: exaSearchResponseSchema,
|
|
193
|
+
run: async (input, credentials) => {
|
|
194
|
+
const client = createExaClient(credentials);
|
|
195
|
+
const { url, ...options } = input;
|
|
196
|
+
return await client.findSimilar(url, {
|
|
197
|
+
...options,
|
|
198
|
+
contents: false
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const findSimilarTool = findSimilar;
|
|
203
|
+
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/find-similar-with-contents.ts
|
|
206
|
+
const findSimilarWithContents = exaOperation({
|
|
207
|
+
id: "exa_find_similar_with_contents",
|
|
208
|
+
name: "Exa Find Similar with Contents",
|
|
209
|
+
description: "Find web pages similar to a given URL and retrieve their contents in a single request.",
|
|
210
|
+
input: z.object({
|
|
211
|
+
url: z.string(),
|
|
212
|
+
excludeSourceDomain: z.boolean().optional(),
|
|
213
|
+
numResults: z.number().min(1).max(100).optional(),
|
|
214
|
+
includeDomains: z.array(z.string()).optional(),
|
|
215
|
+
excludeDomains: z.array(z.string()).optional(),
|
|
216
|
+
startCrawlDate: z.string().optional(),
|
|
217
|
+
endCrawlDate: z.string().optional(),
|
|
218
|
+
startPublishedDate: z.string().optional(),
|
|
219
|
+
endPublishedDate: z.string().optional(),
|
|
220
|
+
includeText: z.array(z.string()).optional(),
|
|
221
|
+
excludeText: z.array(z.string()).optional(),
|
|
222
|
+
moderation: z.boolean().optional(),
|
|
223
|
+
text: z.union([z.literal(true), z.object({
|
|
224
|
+
maxCharacters: z.number().optional(),
|
|
225
|
+
includeHtmlTags: z.boolean().optional(),
|
|
226
|
+
verbosity: z.enum([
|
|
227
|
+
"compact",
|
|
228
|
+
"standard",
|
|
229
|
+
"full"
|
|
230
|
+
]).optional()
|
|
231
|
+
})]).optional(),
|
|
232
|
+
highlights: z.union([z.literal(true), z.object({
|
|
233
|
+
maxCharacters: z.number().optional(),
|
|
234
|
+
query: z.string().optional()
|
|
235
|
+
})]).optional(),
|
|
236
|
+
summary: z.object({
|
|
237
|
+
query: z.string().optional(),
|
|
238
|
+
schema: z.record(z.string(), z.unknown()).optional()
|
|
239
|
+
}).optional(),
|
|
240
|
+
livecrawl: z.enum([
|
|
241
|
+
"always",
|
|
242
|
+
"fallback",
|
|
243
|
+
"never",
|
|
244
|
+
"auto",
|
|
245
|
+
"preferred"
|
|
246
|
+
]).optional(),
|
|
247
|
+
livecrawlTimeout: z.number().optional(),
|
|
248
|
+
maxAgeHours: z.number().optional(),
|
|
249
|
+
subpages: z.number().optional(),
|
|
250
|
+
subpageTarget: z.union([z.string(), z.array(z.string())]).optional(),
|
|
251
|
+
extras: z.record(z.string(), z.unknown()).optional(),
|
|
252
|
+
filterEmptyResults: z.boolean().optional()
|
|
253
|
+
}),
|
|
254
|
+
output: exaSearchResponseSchema,
|
|
255
|
+
run: async (input, credentials) => {
|
|
256
|
+
const client = createExaClient(credentials);
|
|
257
|
+
const { url, text, highlights, summary, livecrawl, livecrawlTimeout, maxAgeHours, subpages, subpageTarget, extras, filterEmptyResults, ...searchOptions } = input;
|
|
258
|
+
const contents = {
|
|
259
|
+
text,
|
|
260
|
+
highlights,
|
|
261
|
+
summary,
|
|
262
|
+
livecrawl,
|
|
263
|
+
livecrawlTimeout,
|
|
264
|
+
maxAgeHours,
|
|
265
|
+
subpages,
|
|
266
|
+
subpageTarget,
|
|
267
|
+
extras,
|
|
268
|
+
filterEmptyResults
|
|
269
|
+
};
|
|
270
|
+
return await client.findSimilar(url, {
|
|
271
|
+
...searchOptions,
|
|
272
|
+
contents
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
const findSimilarWithContentsTool = findSimilarWithContents;
|
|
277
|
+
|
|
278
|
+
//#endregion
|
|
279
|
+
//#region src/monitors.ts
|
|
280
|
+
const createMonitor = exaOperation({
|
|
281
|
+
id: "exa_create_monitor",
|
|
282
|
+
name: "Create Exa Monitor",
|
|
283
|
+
description: "Create a new Exa monitor to track search results over time.",
|
|
284
|
+
needsApproval: true,
|
|
285
|
+
input: z.object({
|
|
286
|
+
name: z.string().optional(),
|
|
287
|
+
search: z.object({
|
|
288
|
+
query: z.string(),
|
|
289
|
+
numResults: z.number().optional(),
|
|
290
|
+
contents: z.unknown().optional()
|
|
291
|
+
}),
|
|
292
|
+
trigger: z.object({
|
|
293
|
+
type: z.string(),
|
|
294
|
+
period: z.string().optional()
|
|
295
|
+
}).optional(),
|
|
296
|
+
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
297
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
298
|
+
webhook: z.object({
|
|
299
|
+
url: z.string(),
|
|
300
|
+
events: z.array(z.string()).optional()
|
|
301
|
+
})
|
|
302
|
+
}),
|
|
303
|
+
output: exaMonitorSchema,
|
|
304
|
+
run: async (input, credentials) => {
|
|
305
|
+
return await createExaClient(credentials).monitors.create(input);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
const createMonitorTool = createMonitor;
|
|
309
|
+
const listMonitors = exaOperation({
|
|
310
|
+
id: "exa_list_monitors",
|
|
311
|
+
name: "List Exa Monitors",
|
|
312
|
+
description: "List all Exa monitors with optional status filtering and pagination.",
|
|
313
|
+
input: z.object({
|
|
314
|
+
status: z.enum([
|
|
315
|
+
"active",
|
|
316
|
+
"paused",
|
|
317
|
+
"disabled"
|
|
318
|
+
]).optional(),
|
|
319
|
+
cursor: z.string().optional(),
|
|
320
|
+
limit: z.number().min(1).max(100).optional()
|
|
321
|
+
}),
|
|
322
|
+
output: exaMonitorListResponseSchema,
|
|
323
|
+
run: async (input, credentials) => {
|
|
324
|
+
return await createExaClient(credentials).monitors.list(input);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
const listMonitorsTool = listMonitors;
|
|
328
|
+
const getMonitor = exaOperation({
|
|
329
|
+
id: "exa_get_monitor",
|
|
330
|
+
name: "Get Exa Monitor",
|
|
331
|
+
description: "Get details of a specific Exa monitor by ID.",
|
|
332
|
+
input: z.object({ monitorId: z.string() }),
|
|
333
|
+
output: exaMonitorSchema,
|
|
334
|
+
run: async (input, credentials) => {
|
|
335
|
+
return await createExaClient(credentials).monitors.get(input.monitorId);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
const getMonitorTool = getMonitor;
|
|
339
|
+
const updateMonitor = exaOperation({
|
|
340
|
+
id: "exa_update_monitor",
|
|
341
|
+
name: "Update Exa Monitor",
|
|
342
|
+
description: "Update an existing Exa monitor configuration.",
|
|
343
|
+
needsApproval: true,
|
|
344
|
+
input: z.object({
|
|
345
|
+
monitorId: z.string(),
|
|
346
|
+
name: z.string().optional(),
|
|
347
|
+
search: z.object({
|
|
348
|
+
query: z.string(),
|
|
349
|
+
numResults: z.number().optional(),
|
|
350
|
+
contents: z.unknown().optional()
|
|
351
|
+
}).optional(),
|
|
352
|
+
trigger: z.object({
|
|
353
|
+
type: z.string(),
|
|
354
|
+
period: z.string().optional()
|
|
355
|
+
}).optional(),
|
|
356
|
+
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
357
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
358
|
+
webhook: z.object({
|
|
359
|
+
url: z.string(),
|
|
360
|
+
events: z.array(z.string()).optional()
|
|
361
|
+
}).optional()
|
|
362
|
+
}),
|
|
363
|
+
output: exaMonitorSchema,
|
|
364
|
+
run: async (input, credentials) => {
|
|
365
|
+
const client = createExaClient(credentials);
|
|
366
|
+
const { monitorId, ...rest } = input;
|
|
367
|
+
return await client.monitors.update(monitorId, rest);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
const updateMonitorTool = updateMonitor;
|
|
371
|
+
const deleteMonitor = exaOperation({
|
|
372
|
+
id: "exa_delete_monitor",
|
|
373
|
+
name: "Delete Exa Monitor",
|
|
374
|
+
description: "Delete an Exa monitor by ID. Returns the deleted monitor object.",
|
|
375
|
+
needsApproval: true,
|
|
376
|
+
input: z.object({ monitorId: z.string() }),
|
|
377
|
+
output: exaMonitorSchema,
|
|
378
|
+
run: async (input, credentials) => {
|
|
379
|
+
return await createExaClient(credentials).monitors.delete(input.monitorId);
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
const deleteMonitorTool = deleteMonitor;
|
|
383
|
+
const triggerMonitor = exaOperation({
|
|
384
|
+
id: "exa_trigger_monitor",
|
|
385
|
+
name: "Trigger Exa Monitor",
|
|
386
|
+
description: "Manually trigger an Exa monitor to run immediately.",
|
|
387
|
+
needsApproval: true,
|
|
388
|
+
input: z.object({ monitorId: z.string() }),
|
|
389
|
+
output: exaTriggerMonitorResponseSchema,
|
|
390
|
+
run: async (input, credentials) => {
|
|
391
|
+
return await createExaClient(credentials).monitors.trigger(input.monitorId);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
const triggerMonitorTool = triggerMonitor;
|
|
395
|
+
const listMonitorRuns = exaOperation({
|
|
396
|
+
id: "exa_list_monitor_runs",
|
|
397
|
+
name: "List Exa Monitor Runs",
|
|
398
|
+
description: "List runs for a specific Exa monitor with pagination.",
|
|
399
|
+
input: z.object({
|
|
400
|
+
monitorId: z.string(),
|
|
401
|
+
cursor: z.string().optional(),
|
|
402
|
+
limit: z.number().min(1).max(100).optional()
|
|
403
|
+
}),
|
|
404
|
+
output: exaMonitorRunListResponseSchema,
|
|
405
|
+
run: async (input, credentials) => {
|
|
406
|
+
const client = createExaClient(credentials);
|
|
407
|
+
const { monitorId, ...rest } = input;
|
|
408
|
+
return await client.monitors.runs.list(monitorId, rest);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
const listMonitorRunsTool = listMonitorRuns;
|
|
412
|
+
const getMonitorRun = exaOperation({
|
|
413
|
+
id: "exa_get_monitor_run",
|
|
414
|
+
name: "Get Exa Monitor Run",
|
|
415
|
+
description: "Get details of a specific Exa monitor run.",
|
|
416
|
+
input: z.object({
|
|
417
|
+
monitorId: z.string(),
|
|
418
|
+
runId: z.string()
|
|
419
|
+
}),
|
|
420
|
+
output: exaMonitorRunSchema,
|
|
421
|
+
run: async (input, credentials) => {
|
|
422
|
+
return await createExaClient(credentials).monitors.runs.get(input.monitorId, input.runId);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
const getMonitorRunTool = getMonitorRun;
|
|
426
|
+
|
|
427
|
+
//#endregion
|
|
428
|
+
//#region src/search.ts
|
|
429
|
+
const search = exaOperation({
|
|
430
|
+
id: "exa_search",
|
|
431
|
+
name: "Exa Search",
|
|
432
|
+
description: "Search the web using Exa semantic, keyword, or hybrid search.",
|
|
433
|
+
input: z.object({
|
|
434
|
+
query: z.string(),
|
|
435
|
+
type: z.enum([
|
|
436
|
+
"auto",
|
|
437
|
+
"neural",
|
|
438
|
+
"fast",
|
|
439
|
+
"instant",
|
|
440
|
+
"deep-lite",
|
|
441
|
+
"deep",
|
|
442
|
+
"deep-reasoning",
|
|
443
|
+
"keyword",
|
|
444
|
+
"hybrid"
|
|
445
|
+
]).optional(),
|
|
446
|
+
category: z.enum([
|
|
447
|
+
"company",
|
|
448
|
+
"research paper",
|
|
449
|
+
"news",
|
|
450
|
+
"personal site",
|
|
451
|
+
"financial report",
|
|
452
|
+
"people",
|
|
453
|
+
"pdf"
|
|
454
|
+
]).optional(),
|
|
455
|
+
numResults: z.number().min(1).max(100).optional(),
|
|
456
|
+
includeDomains: z.array(z.string()).optional(),
|
|
457
|
+
excludeDomains: z.array(z.string()).optional(),
|
|
458
|
+
startPublishedDate: z.string().optional(),
|
|
459
|
+
endPublishedDate: z.string().optional(),
|
|
460
|
+
startCrawlDate: z.string().optional(),
|
|
461
|
+
endCrawlDate: z.string().optional(),
|
|
462
|
+
includeText: z.array(z.string()).optional(),
|
|
463
|
+
excludeText: z.array(z.string()).optional(),
|
|
464
|
+
moderation: z.boolean().optional(),
|
|
465
|
+
useAutoprompt: z.boolean().optional(),
|
|
466
|
+
userLocation: z.string().optional()
|
|
467
|
+
}),
|
|
468
|
+
output: exaSearchResponseSchema,
|
|
469
|
+
run: async (input, credentials) => {
|
|
470
|
+
const client = createExaClient(credentials);
|
|
471
|
+
const { query, ...options } = input;
|
|
472
|
+
return await client.search(query, {
|
|
473
|
+
...options,
|
|
474
|
+
contents: false
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
const searchTool = search;
|
|
479
|
+
|
|
480
|
+
//#endregion
|
|
481
|
+
//#region src/search-with-contents.ts
|
|
482
|
+
const contentsOptionsSchema = z.object({
|
|
483
|
+
text: z.union([z.literal(true), z.object({
|
|
484
|
+
maxCharacters: z.number().optional(),
|
|
485
|
+
includeHtmlTags: z.boolean().optional(),
|
|
486
|
+
verbosity: z.enum([
|
|
487
|
+
"compact",
|
|
488
|
+
"standard",
|
|
489
|
+
"full"
|
|
490
|
+
]).optional()
|
|
491
|
+
})]).optional(),
|
|
492
|
+
highlights: z.union([z.literal(true), z.object({
|
|
493
|
+
maxCharacters: z.number().optional(),
|
|
494
|
+
query: z.string().optional()
|
|
495
|
+
})]).optional(),
|
|
496
|
+
summary: z.object({
|
|
497
|
+
query: z.string().optional(),
|
|
498
|
+
schema: z.record(z.string(), z.unknown()).optional()
|
|
499
|
+
}).optional(),
|
|
500
|
+
livecrawl: z.enum([
|
|
501
|
+
"always",
|
|
502
|
+
"fallback",
|
|
503
|
+
"never",
|
|
504
|
+
"auto",
|
|
505
|
+
"preferred"
|
|
506
|
+
]).optional(),
|
|
507
|
+
livecrawlTimeout: z.number().optional(),
|
|
508
|
+
maxAgeHours: z.number().optional(),
|
|
509
|
+
subpages: z.number().optional(),
|
|
510
|
+
subpageTarget: z.union([z.string(), z.array(z.string())]).optional(),
|
|
511
|
+
extras: z.record(z.string(), z.unknown()).optional(),
|
|
512
|
+
filterEmptyResults: z.boolean().optional()
|
|
513
|
+
});
|
|
514
|
+
const searchWithContents = exaOperation({
|
|
515
|
+
id: "exa_search_with_contents",
|
|
516
|
+
name: "Exa Search with Contents",
|
|
517
|
+
description: "Search the web using Exa and retrieve page contents (text, highlights, summaries) in a single request.",
|
|
518
|
+
input: z.object({
|
|
519
|
+
query: z.string(),
|
|
520
|
+
type: z.enum([
|
|
521
|
+
"auto",
|
|
522
|
+
"neural",
|
|
523
|
+
"fast",
|
|
524
|
+
"instant",
|
|
525
|
+
"deep-lite",
|
|
526
|
+
"deep",
|
|
527
|
+
"deep-reasoning",
|
|
528
|
+
"keyword",
|
|
529
|
+
"hybrid"
|
|
530
|
+
]).optional(),
|
|
531
|
+
category: z.enum([
|
|
532
|
+
"company",
|
|
533
|
+
"research paper",
|
|
534
|
+
"news",
|
|
535
|
+
"personal site",
|
|
536
|
+
"financial report",
|
|
537
|
+
"people",
|
|
538
|
+
"pdf"
|
|
539
|
+
]).optional(),
|
|
540
|
+
numResults: z.number().min(1).max(100).optional(),
|
|
541
|
+
includeDomains: z.array(z.string()).optional(),
|
|
542
|
+
excludeDomains: z.array(z.string()).optional(),
|
|
543
|
+
startPublishedDate: z.string().optional(),
|
|
544
|
+
endPublishedDate: z.string().optional(),
|
|
545
|
+
startCrawlDate: z.string().optional(),
|
|
546
|
+
endCrawlDate: z.string().optional(),
|
|
547
|
+
includeText: z.array(z.string()).optional(),
|
|
548
|
+
excludeText: z.array(z.string()).optional(),
|
|
549
|
+
moderation: z.boolean().optional(),
|
|
550
|
+
useAutoprompt: z.boolean().optional(),
|
|
551
|
+
userLocation: z.string().optional()
|
|
552
|
+
}).merge(contentsOptionsSchema),
|
|
553
|
+
output: exaSearchResponseSchema,
|
|
554
|
+
run: async (input, credentials) => {
|
|
555
|
+
const client = createExaClient(credentials);
|
|
556
|
+
const { query, text, highlights, summary, livecrawl, livecrawlTimeout, maxAgeHours, subpages, subpageTarget, extras, filterEmptyResults, ...searchOptions } = input;
|
|
557
|
+
const contents = {
|
|
558
|
+
text,
|
|
559
|
+
highlights,
|
|
560
|
+
summary,
|
|
561
|
+
livecrawl,
|
|
562
|
+
livecrawlTimeout,
|
|
563
|
+
maxAgeHours,
|
|
564
|
+
subpages,
|
|
565
|
+
subpageTarget,
|
|
566
|
+
extras,
|
|
567
|
+
filterEmptyResults
|
|
568
|
+
};
|
|
569
|
+
return await client.search(query, {
|
|
570
|
+
...searchOptions,
|
|
571
|
+
contents
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
const searchWithContentsTool = searchWithContents;
|
|
576
|
+
|
|
577
|
+
//#endregion
|
|
578
|
+
export { answer, answerTool, createExaClient, createMonitor, createMonitorTool, deleteMonitor, deleteMonitorTool, exa, exaAnswerCitationSchema, exaAnswerResponseSchema, exaContentsResponseSchema, exaCostSchema, exaMonitorListResponseSchema, exaMonitorRunListResponseSchema, exaMonitorRunSchema, exaMonitorSchema, exaOperation, exaSearchResponseSchema, exaSearchResultSchema, exaTriggerMonitorResponseSchema, findSimilar, findSimilarTool, findSimilarWithContents, findSimilarWithContentsTool, getContents, getContentsTool, getMonitor, getMonitorRun, getMonitorRunTool, getMonitorTool, listMonitorRuns, listMonitorRunsTool, listMonitors, listMonitorsTool, search, searchTool, searchWithContents, searchWithContentsTool, triggerMonitor, triggerMonitorTool, updateMonitor, updateMonitorTool };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as _keystrokehq_integration_authoring_official0 from "@keystrokehq/integration-authoring/official";
|
|
3
|
+
import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
|
|
4
|
+
import { InferCredentialSetAuth } from "@keystrokehq/core/credential-set";
|
|
5
|
+
import * as _keystrokehq_core0 from "@keystrokehq/core";
|
|
6
|
+
|
|
7
|
+
//#region src/integration.d.ts
|
|
8
|
+
declare const exaBundle: _keystrokehq_integration_authoring_official0.OfficialIntegrationBundle<"exa", z.ZodObject<{
|
|
9
|
+
EXA_API_KEY: z.ZodString;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
declare const exa: _keystrokehq_core0.CredentialSet<"exa", z.ZodObject<{
|
|
12
|
+
EXA_API_KEY: z.ZodString;
|
|
13
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
14
|
+
EXA_API_KEY: z.ZodString;
|
|
15
|
+
}, z.core.$strip>>[] | undefined>;
|
|
16
|
+
type ExaCredentials = InferCredentialSetAuth<typeof exa>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { exa as n, exaBundle as r, ExaCredentials as t };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineOfficialIntegration } from "@keystrokehq/integration-authoring/official";
|
|
3
|
+
|
|
4
|
+
//#region src/integration.ts
|
|
5
|
+
const exaAuthSchema = z.object({ EXA_API_KEY: z.string().min(1) });
|
|
6
|
+
const exaOfficialIntegration = {
|
|
7
|
+
id: "exa",
|
|
8
|
+
name: "Exa",
|
|
9
|
+
description: "AI-native semantic web search, content extraction, and monitoring",
|
|
10
|
+
auth: exaAuthSchema,
|
|
11
|
+
proxy: { hosts: ["api.exa.ai"] }
|
|
12
|
+
};
|
|
13
|
+
const exaBundle = defineOfficialIntegration(exaOfficialIntegration);
|
|
14
|
+
const exa = exaBundle.credentialSet;
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { exaBundle as n, exa as t };
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@keystrokehq/exa",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"default": "./dist/index.mjs"
|
|
11
|
+
},
|
|
12
|
+
"./_official": {
|
|
13
|
+
"types": "./dist/_official/index.d.mts",
|
|
14
|
+
"default": "./dist/_official/index.mjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsdown",
|
|
24
|
+
"typecheck": "tsgo --build",
|
|
25
|
+
"lint": "biome check .",
|
|
26
|
+
"lint:fix": "biome check --write .",
|
|
27
|
+
"test:unit": "vitest run --passWithNoTests --project unit",
|
|
28
|
+
"test:int": "vitest run --passWithNoTests --project int",
|
|
29
|
+
"prepublishOnly": "pnpm build"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"exa-js": "^2.11.0",
|
|
33
|
+
"@keystrokehq/integration-authoring": "^0.0.1",
|
|
34
|
+
"@keystrokehq/core": "^0.0.5",
|
|
35
|
+
"zod": "^4.3.6"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "catalog:",
|
|
39
|
+
"tsdown": "catalog:",
|
|
40
|
+
"typescript": "catalog:",
|
|
41
|
+
"vitest": "catalog:",
|
|
42
|
+
"@keystrokehq/test-utils": "workspace:*",
|
|
43
|
+
"@keystrokehq/typescript-config": "workspace:*"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"exa",
|
|
47
|
+
"web-search",
|
|
48
|
+
"semantic-search",
|
|
49
|
+
"keystroke",
|
|
50
|
+
"integration"
|
|
51
|
+
],
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "https://github.com/keystrokehq/integrations",
|
|
55
|
+
"directory": "integrations/exa"
|
|
56
|
+
},
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"access": "public",
|
|
60
|
+
"registry": "https://registry.npmjs.org/"
|
|
61
|
+
}
|
|
62
|
+
}
|