@keystrokehq/exa 0.0.16 → 0.0.56

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.
Files changed (45) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +90 -2
  3. package/dist/actions/index.cjs +17 -0
  4. package/dist/actions/index.d.cts +2 -0
  5. package/dist/actions/index.d.mts +2 -0
  6. package/dist/actions/index.mjs +2 -0
  7. package/dist/actions-Bl-9uz6K.cjs +491 -0
  8. package/dist/actions-Bl-9uz6K.cjs.map +1 -0
  9. package/dist/actions-DnHafheX.mjs +373 -0
  10. package/dist/actions-DnHafheX.mjs.map +1 -0
  11. package/dist/credential-BWous9Uu.cjs +16 -0
  12. package/dist/credential-BWous9Uu.cjs.map +1 -0
  13. package/dist/credential-NfXyV_Vy.mjs +11 -0
  14. package/dist/credential-NfXyV_Vy.mjs.map +1 -0
  15. package/dist/index-BwCGHs6v.d.cts +357 -0
  16. package/dist/index-BwCGHs6v.d.cts.map +1 -0
  17. package/dist/index-BwCGHs6v.d.mts +357 -0
  18. package/dist/index-BwCGHs6v.d.mts.map +1 -0
  19. package/dist/index.cjs +14 -0
  20. package/dist/index.d.cts +20 -0
  21. package/dist/index.d.cts.map +1 -0
  22. package/dist/index.d.mts +20 -4
  23. package/dist/index.d.mts.map +1 -0
  24. package/dist/index.mjs +4 -5
  25. package/dist/mcp.cjs +57 -0
  26. package/dist/mcp.cjs.map +1 -0
  27. package/dist/mcp.d.cts +16 -0
  28. package/dist/mcp.d.cts.map +1 -0
  29. package/dist/mcp.d.mts +16 -0
  30. package/dist/mcp.d.mts.map +1 -0
  31. package/dist/mcp.mjs +54 -0
  32. package/dist/mcp.mjs.map +1 -0
  33. package/package.json +49 -54
  34. package/dist/contents.schema-BNgTB2DN.mjs +0 -133
  35. package/dist/credential-sets/index.d.mts +0 -2
  36. package/dist/credential-sets/index.mjs +0 -3
  37. package/dist/exa.credential-set-BGLENRlR.d.mts +0 -14
  38. package/dist/exa.credential-set-Ba-RsxL2.mjs +0 -15
  39. package/dist/operations/index.d.mts +0 -2
  40. package/dist/operations/index.mjs +0 -3
  41. package/dist/schemas/index.d.mts +0 -2
  42. package/dist/schemas/index.mjs +0 -3
  43. package/dist/search.schema-Cw-d91N6.d.mts +0 -204
  44. package/dist/update-monitor.operation-D-vWJFP3.mjs +0 -478
  45. package/dist/update-monitor.operation-Dm50YoS7.d.mts +0 -570
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Buster
3
+ Copyright (c) 2026 Dallin
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,5 +1,93 @@
1
1
  # @keystrokehq/exa
2
2
 
3
- Keystroke official integration for [Exa](https://exa.ai) AI-native semantic web search, content extraction, and monitoring.
3
+ Exa Search API integration — static API key credential and importable agent actions.
4
4
 
5
- Credential sets live under [`./credential-sets`](./src/credential-sets/index.ts). Operations live under [`./operations`](./src/operations/index.ts).
5
+ Reference for building a **custom integration package**: credential actions optional MCP → publish as `@your-org/my-api`.
6
+
7
+ ## Package layout
8
+
9
+ ```
10
+ src/
11
+ credential.ts # defineCredential — vault key "exa"
12
+ actions/ # defineAction exports
13
+ mcp.ts # defineMcp (uses @keystrokehq/credentials)
14
+ client.ts # raw HTTP client
15
+ index.ts # public exports
16
+ ```
17
+
18
+ ## Credential
19
+
20
+ ```ts
21
+ // src/credential.ts
22
+ import { defineCredential } from "@keystrokehq/keystroke/credentials";
23
+ import { z } from "zod";
24
+
25
+ export const exaCredential = defineCredential({
26
+ key: "exa",
27
+ fields: { apiKey: z.string() },
28
+ });
29
+ ```
30
+
31
+ ```bash
32
+ keystroke credentials set exa --scope org --set apiKey=...
33
+ ```
34
+
35
+ ## Setup
36
+
37
+ 1. Get an API key from [Exa Dashboard](https://dashboard.exa.ai/api-keys).
38
+ 2. Store on vault key `exa` (org/project/user scope per your credential chain).
39
+
40
+ ## Actions
41
+
42
+ | Key | Description |
43
+ | ----------------------- | ---------------------------------------------------------------- |
44
+ | `exa-search` | Web search with category, type, filters, highlights/text/summary |
45
+ | `exa-search-structured` | Search + `outputSchema` for grounded structured JSON |
46
+ | `exa-get-contents` | Extract content from known URLs |
47
+ | `exa-answer` | Grounded Q&A with citations |
48
+ | `exa-get-context` | Exa Code — docs/snippets for coding agents |
49
+
50
+ ```ts
51
+ import { defineAgent } from "@keystrokehq/keystroke/agent";
52
+ import { exaSearch, exaAnswer } from "@keystrokehq/exa/actions";
53
+
54
+ export default defineAgent({
55
+ key: "researcher",
56
+ tools: [exaSearch, exaAnswer],
57
+ });
58
+ ```
59
+
60
+ ## MCP
61
+
62
+ | Export | Server | Docs |
63
+ | --------------- | ------------------------------- | -------------------------------------------------------- |
64
+ | `exaSearchMcp` | `https://mcp.exa.ai/mcp` | [Web Search MCP](https://exa.ai/docs/reference/exa-mcp) |
65
+ | `exaWebsetsMcp` | `https://websetsmcp.exa.ai/mcp` | [Websets MCP](https://exa.ai/docs/reference/websets-mcp) |
66
+
67
+ Both use `exaCredential` and resolve the API key at agent runtime.
68
+
69
+ ```ts
70
+ import { exaSearchMcp, exaWebsetsMcp } from "@keystrokehq/exa/mcp";
71
+
72
+ tools: [exaSearchMcp, exaWebsetsMcp],
73
+ ```
74
+
75
+ ## Client
76
+
77
+ ```ts
78
+ import { createExaClient, exaCredential } from "@keystrokehq/exa";
79
+ ```
80
+
81
+ ## Dependencies
82
+
83
+ ```json
84
+ {
85
+ "dependencies": {
86
+ "@keystrokehq/keystroke": "^0.0.3",
87
+ "@keystrokehq/credentials": "^0.0.3",
88
+ "@keystrokehq/mcp": "^0.0.3"
89
+ }
90
+ }
91
+ ```
92
+
93
+ Author with `@keystrokehq/keystroke/*`. Use `@keystrokehq/credentials` only when wiring MCP OAuth/auth mappers.
@@ -0,0 +1,17 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_actions = require("../actions-Bl-9uz6K.cjs");
3
+ exports.ExaAnswerInput = require_actions.ExaAnswerInput;
4
+ exports.ExaAnswerOutput = require_actions.ExaAnswerOutput;
5
+ exports.ExaGetContentsInput = require_actions.ExaGetContentsInput;
6
+ exports.ExaGetContentsOutput = require_actions.ExaGetContentsOutput;
7
+ exports.ExaGetContextInput = require_actions.ExaGetContextInput;
8
+ exports.ExaGetContextOutput = require_actions.ExaGetContextOutput;
9
+ exports.ExaSearchInput = require_actions.ExaSearchInput;
10
+ exports.ExaSearchOutput = require_actions.ExaSearchOutput;
11
+ exports.ExaSearchStructuredInput = require_actions.ExaSearchStructuredInput;
12
+ exports.ExaSearchStructuredOutput = require_actions.ExaSearchStructuredOutput;
13
+ exports.exaAnswer = require_actions.exaAnswer;
14
+ exports.exaGetContents = require_actions.exaGetContents;
15
+ exports.exaGetContext = require_actions.exaGetContext;
16
+ exports.exaSearch = require_actions.exaSearch;
17
+ exports.exaSearchStructured = require_actions.exaSearchStructured;
@@ -0,0 +1,2 @@
1
+ import { a as ExaSearchOutput, c as ExaGetContextOutput, d as ExaGetContentsOutput, f as exaGetContents, h as exaAnswer, i as ExaSearchInput, l as exaGetContext, m as ExaAnswerOutput, n as ExaSearchStructuredOutput, o as exaSearch, p as ExaAnswerInput, r as exaSearchStructured, s as ExaGetContextInput, t as ExaSearchStructuredInput, u as ExaGetContentsInput } from "../index-BwCGHs6v.cjs";
2
+ export { ExaAnswerInput, ExaAnswerOutput, ExaGetContentsInput, ExaGetContentsOutput, ExaGetContextInput, ExaGetContextOutput, ExaSearchInput, ExaSearchOutput, ExaSearchStructuredInput, ExaSearchStructuredOutput, exaAnswer, exaGetContents, exaGetContext, exaSearch, exaSearchStructured };
@@ -0,0 +1,2 @@
1
+ import { a as ExaSearchOutput, c as ExaGetContextOutput, d as ExaGetContentsOutput, f as exaGetContents, h as exaAnswer, i as ExaSearchInput, l as exaGetContext, m as ExaAnswerOutput, n as ExaSearchStructuredOutput, o as exaSearch, p as ExaAnswerInput, r as exaSearchStructured, s as ExaGetContextInput, t as ExaSearchStructuredInput, u as ExaGetContentsInput } from "../index-BwCGHs6v.mjs";
2
+ export { ExaAnswerInput, ExaAnswerOutput, ExaGetContentsInput, ExaGetContentsOutput, ExaGetContextInput, ExaGetContextOutput, ExaSearchInput, ExaSearchOutput, ExaSearchStructuredInput, ExaSearchStructuredOutput, exaAnswer, exaGetContents, exaGetContext, exaSearch, exaSearchStructured };
@@ -0,0 +1,2 @@
1
+ import { a as ExaSearchOutput, c as ExaGetContextOutput, d as ExaGetContentsOutput, f as exaGetContents, h as exaAnswer, i as ExaSearchInput, l as exaGetContext, m as ExaAnswerOutput, n as ExaSearchStructuredOutput, o as exaSearch, p as ExaAnswerInput, r as exaSearchStructured, s as ExaGetContextInput, t as ExaSearchStructuredInput, u as ExaGetContentsInput } from "../actions-DnHafheX.mjs";
2
+ export { ExaAnswerInput, ExaAnswerOutput, ExaGetContentsInput, ExaGetContentsOutput, ExaGetContextInput, ExaGetContextOutput, ExaSearchInput, ExaSearchOutput, ExaSearchStructuredInput, ExaSearchStructuredOutput, exaAnswer, exaGetContents, exaGetContext, exaSearch, exaSearchStructured };
@@ -0,0 +1,491 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ const require_credential = require("./credential-BWous9Uu.cjs");
24
+ let zod = require("zod");
25
+ let ky = require("ky");
26
+ ky = __toESM(ky, 1);
27
+ let _keystrokehq_keystroke_action = require("@keystrokehq/keystroke/action");
28
+ //#region src/client.ts
29
+ const EXA_API_BASE = "https://api.exa.ai";
30
+ function createExaClient(apiKey) {
31
+ const api = ky.default.create({
32
+ prefix: EXA_API_BASE,
33
+ headers: {
34
+ "x-api-key": apiKey,
35
+ "Content-Type": "application/json"
36
+ }
37
+ });
38
+ return {
39
+ search: (body) => api.post("search", { json: body }).json(),
40
+ contents: (body) => api.post("contents", { json: body }).json(),
41
+ answer: (body) => api.post("answer", { json: body }).json(),
42
+ context: (body) => api.post("context", { json: body }).json()
43
+ };
44
+ }
45
+ //#endregion
46
+ //#region src/schemas.ts
47
+ const exaSearchTypeSchema = zod.z.enum([
48
+ "instant",
49
+ "fast",
50
+ "auto",
51
+ "deep-lite",
52
+ "deep",
53
+ "deep-reasoning"
54
+ ]);
55
+ const exaCategorySchema = zod.z.enum([
56
+ "company",
57
+ "people",
58
+ "research paper",
59
+ "news",
60
+ "personal site",
61
+ "financial report"
62
+ ]);
63
+ const exaSearchResultSchema = zod.z.object({
64
+ title: zod.z.string().nullable().optional(),
65
+ url: zod.z.string(),
66
+ id: zod.z.string().optional(),
67
+ publishedDate: zod.z.string().nullable().optional(),
68
+ author: zod.z.string().nullable().optional(),
69
+ text: zod.z.string().nullable().optional(),
70
+ highlights: zod.z.array(zod.z.string()).optional(),
71
+ summary: zod.z.string().nullable().optional(),
72
+ entities: zod.z.unknown().optional()
73
+ });
74
+ const exaGroundingCitationSchema = zod.z.object({
75
+ url: zod.z.string(),
76
+ title: zod.z.string().optional()
77
+ });
78
+ const exaGroundingSchema = zod.z.object({
79
+ field: zod.z.string(),
80
+ citations: zod.z.array(exaGroundingCitationSchema),
81
+ confidence: zod.z.enum([
82
+ "low",
83
+ "medium",
84
+ "high"
85
+ ]).optional()
86
+ });
87
+ const exaContentStatusSchema = zod.z.object({
88
+ id: zod.z.string(),
89
+ status: zod.z.enum(["success", "error"]),
90
+ source: zod.z.enum(["cached", "crawled"]).optional(),
91
+ error: zod.z.object({
92
+ tag: zod.z.string().optional(),
93
+ httpStatusCode: zod.z.number().optional()
94
+ }).optional()
95
+ });
96
+ const exaCitationSchema = zod.z.object({
97
+ title: zod.z.string().nullable().optional(),
98
+ url: zod.z.string(),
99
+ id: zod.z.string().optional(),
100
+ publishedDate: zod.z.string().nullable().optional(),
101
+ author: zod.z.string().nullable().optional(),
102
+ text: zod.z.string().nullable().optional()
103
+ });
104
+ const restrictedCategory = new Set(["company", "people"]);
105
+ function assertCategoryFilters(category, filters) {
106
+ if (!category || !restrictedCategory.has(category)) return;
107
+ if (filters.excludeDomains?.length) throw new Error("excludeDomains is not supported for company or people category searches");
108
+ if (filters.startPublishedDate || filters.endPublishedDate) throw new Error("published date filters are not supported for company or people category searches");
109
+ }
110
+ function buildSearchContents(input) {
111
+ const contents = {};
112
+ if (input.highlights !== false) contents.highlights = input.highlights === true ? true : { maxCharacters: 4e3 };
113
+ if (input.text) contents.text = true;
114
+ if (input.summary) contents.summary = true;
115
+ return Object.keys(contents).length > 0 ? contents : void 0;
116
+ }
117
+ function buildContentsOptions(input) {
118
+ const body = {};
119
+ if (input.highlights) body.highlights = typeof input.highlights === "boolean" ? true : input.highlights;
120
+ if (input.text) body.text = true;
121
+ if (input.summary) body.summary = true;
122
+ if (!Object.keys(body).length) body.highlights = { maxCharacters: 4e3 };
123
+ return body;
124
+ }
125
+ //#endregion
126
+ //#region src/actions/answer.ts
127
+ const ExaAnswerInput = zod.z.object({
128
+ query: zod.z.string().describe("Natural-language question."),
129
+ includeCitationText: zod.z.boolean().default(false).describe("Include full text bodies on citations."),
130
+ outputSchema: zod.z.record(zod.z.string(), zod.z.unknown()).optional().describe("JSON Schema for structured answer output.")
131
+ });
132
+ const ExaAnswerOutput = zod.z.object({
133
+ requestId: zod.z.string().optional(),
134
+ answer: zod.z.unknown(),
135
+ citations: zod.z.array(exaCitationSchema),
136
+ costDollars: zod.z.object({ total: zod.z.number().optional() }).optional()
137
+ });
138
+ const exaAnswer = (0, _keystrokehq_keystroke_action.defineAction)({
139
+ key: "exa-answer",
140
+ name: "Exa Answer",
141
+ description: "Search-backed grounded Q&A with citations.",
142
+ input: ExaAnswerInput,
143
+ output: ExaAnswerOutput,
144
+ credentials: [require_credential.exaCredential],
145
+ async run(input, credentials) {
146
+ const client = createExaClient(credentials.exa.apiKey);
147
+ const body = {
148
+ query: input.query,
149
+ text: input.includeCitationText
150
+ };
151
+ if (input.outputSchema) body.outputSchema = input.outputSchema;
152
+ const response = await client.answer(body);
153
+ return {
154
+ requestId: response.requestId,
155
+ answer: response.answer ?? null,
156
+ citations: (response.citations ?? []).map((row) => exaCitationSchema.parse(row)),
157
+ costDollars: response.costDollars
158
+ };
159
+ }
160
+ });
161
+ //#endregion
162
+ //#region src/actions/get-contents.ts
163
+ const ExaGetContentsInput = zod.z.object({
164
+ urls: zod.z.array(zod.z.string().url()).min(1).max(100).describe("URLs to extract content from."),
165
+ highlights: zod.z.boolean().optional().describe("Return token-efficient excerpts."),
166
+ text: zod.z.boolean().optional().describe("Return full page markdown."),
167
+ summary: zod.z.boolean().optional().describe("Return LLM summary per URL.")
168
+ });
169
+ const ExaGetContentsOutput = zod.z.object({
170
+ requestId: zod.z.string().optional(),
171
+ results: zod.z.array(exaSearchResultSchema),
172
+ statuses: zod.z.array(exaContentStatusSchema),
173
+ costDollars: zod.z.object({ total: zod.z.number().optional() }).optional()
174
+ });
175
+ const exaGetContents = (0, _keystrokehq_keystroke_action.defineAction)({
176
+ key: "exa-get-contents",
177
+ name: "Exa Get Contents",
178
+ description: "Extract webpage content from known URLs. Check statuses for per-URL errors (API returns 200 with error statuses).",
179
+ input: ExaGetContentsInput,
180
+ output: ExaGetContentsOutput,
181
+ credentials: [require_credential.exaCredential],
182
+ async run(input, credentials) {
183
+ const client = createExaClient(credentials.exa.apiKey);
184
+ const body = {
185
+ urls: input.urls,
186
+ ...buildContentsOptions({
187
+ highlights: input.highlights,
188
+ text: input.text,
189
+ summary: input.summary
190
+ })
191
+ };
192
+ const response = await client.contents(body);
193
+ return {
194
+ requestId: response.requestId,
195
+ results: (response.results ?? []).map((row) => exaSearchResultSchema.parse(row)),
196
+ statuses: (response.statuses ?? []).map((row) => exaContentStatusSchema.parse(row)),
197
+ costDollars: response.costDollars
198
+ };
199
+ }
200
+ });
201
+ //#endregion
202
+ //#region src/actions/get-context.ts
203
+ const ExaGetContextInput = zod.z.object({
204
+ query: zod.z.string().min(1).max(2e3).describe("Code, API, or how-to question for Exa Code context."),
205
+ tokensNum: zod.z.union([zod.z.number().int().min(50).max(1e5), zod.z.literal("dynamic")]).default("dynamic").describe("Max output tokens or dynamic sizing.")
206
+ });
207
+ const ExaGetContextOutput = zod.z.object({
208
+ requestId: zod.z.string().optional(),
209
+ query: zod.z.string().optional(),
210
+ response: zod.z.string(),
211
+ resultsCount: zod.z.number().optional(),
212
+ searchTime: zod.z.number().optional(),
213
+ outputTokens: zod.z.number().optional(),
214
+ costDollars: zod.z.object({ total: zod.z.number().optional() }).optional()
215
+ });
216
+ const exaGetContext = (0, _keystrokehq_keystroke_action.defineAction)({
217
+ key: "exa-get-context",
218
+ name: "Exa Get Context",
219
+ description: "Exa Code — token-efficient documentation and code snippets for coding agents.",
220
+ input: ExaGetContextInput,
221
+ output: ExaGetContextOutput,
222
+ credentials: [require_credential.exaCredential],
223
+ async run(input, credentials) {
224
+ const response = await createExaClient(credentials.exa.apiKey).context({
225
+ query: input.query,
226
+ tokensNum: input.tokensNum
227
+ });
228
+ return {
229
+ requestId: response.requestId,
230
+ query: response.query,
231
+ response: response.response ?? "",
232
+ resultsCount: response.resultsCount,
233
+ searchTime: response.searchTime,
234
+ outputTokens: response.outputTokens,
235
+ costDollars: response.costDollars
236
+ };
237
+ }
238
+ });
239
+ //#endregion
240
+ //#region src/actions/search.ts
241
+ const ExaSearchInput = zod.z.object({
242
+ query: zod.z.string().describe("Natural-language search query."),
243
+ type: exaSearchTypeSchema.default("auto").describe("Search latency/depth profile."),
244
+ category: exaCategorySchema.optional().describe("Vertical index: company, people, research paper, news, personal site, financial report."),
245
+ numResults: zod.z.number().int().min(1).max(100).default(10),
246
+ includeDomains: zod.z.array(zod.z.string()).max(1200).optional(),
247
+ excludeDomains: zod.z.array(zod.z.string()).max(1200).optional(),
248
+ startPublishedDate: zod.z.string().optional().describe("ISO8601 published-after filter."),
249
+ endPublishedDate: zod.z.string().optional().describe("ISO8601 published-before filter."),
250
+ userLocation: zod.z.string().length(2).optional().describe("Two-letter ISO country code for localized results."),
251
+ additionalQueries: zod.z.array(zod.z.string()).max(10).optional().describe("Extra queries for deep search types only."),
252
+ systemPrompt: zod.z.string().optional().describe("Guides deep search planning."),
253
+ highlights: zod.z.boolean().default(true).describe("Return token-efficient page excerpts (recommended)."),
254
+ text: zod.z.boolean().optional().describe("Include full page markdown text."),
255
+ summary: zod.z.boolean().optional().describe("Include LLM summary per result.")
256
+ }).superRefine((input, ctx) => {
257
+ try {
258
+ assertCategoryFilters(input.category, {
259
+ excludeDomains: input.excludeDomains,
260
+ startPublishedDate: input.startPublishedDate,
261
+ endPublishedDate: input.endPublishedDate
262
+ });
263
+ } catch (error) {
264
+ ctx.addIssue({
265
+ code: "custom",
266
+ message: error instanceof Error ? error.message : "Invalid category filters"
267
+ });
268
+ }
269
+ });
270
+ const ExaSearchOutput = zod.z.object({
271
+ requestId: zod.z.string().optional(),
272
+ searchType: zod.z.string().optional(),
273
+ results: zod.z.array(exaSearchResultSchema),
274
+ costDollars: zod.z.object({ total: zod.z.number().optional() }).optional()
275
+ });
276
+ const exaSearch = (0, _keystrokehq_keystroke_action.defineAction)({
277
+ key: "exa-search",
278
+ name: "Exa Search",
279
+ description: "Search the web with Exa. Supports categories (company, people, news, research paper, etc.), filters, and content modes.",
280
+ input: ExaSearchInput,
281
+ output: ExaSearchOutput,
282
+ credentials: [require_credential.exaCredential],
283
+ async run(input, credentials) {
284
+ const client = createExaClient(credentials.exa.apiKey);
285
+ const body = {
286
+ query: input.query,
287
+ type: input.type,
288
+ numResults: input.numResults
289
+ };
290
+ if (input.category) body.category = input.category;
291
+ if (input.includeDomains?.length) body.includeDomains = input.includeDomains;
292
+ if (input.excludeDomains?.length) body.excludeDomains = input.excludeDomains;
293
+ if (input.startPublishedDate) body.startPublishedDate = input.startPublishedDate;
294
+ if (input.endPublishedDate) body.endPublishedDate = input.endPublishedDate;
295
+ if (input.userLocation) body.userLocation = input.userLocation;
296
+ if (input.additionalQueries?.length) body.additionalQueries = input.additionalQueries;
297
+ if (input.systemPrompt) body.systemPrompt = input.systemPrompt;
298
+ const contents = buildSearchContents({
299
+ highlights: input.highlights,
300
+ text: input.text,
301
+ summary: input.summary
302
+ });
303
+ if (contents) body.contents = contents;
304
+ const response = await client.search(body);
305
+ return {
306
+ requestId: response.requestId,
307
+ searchType: response.searchType,
308
+ results: (response.results ?? []).map((row) => exaSearchResultSchema.parse(row)),
309
+ costDollars: response.costDollars
310
+ };
311
+ }
312
+ });
313
+ //#endregion
314
+ //#region src/actions/search-structured.ts
315
+ const ExaSearchStructuredInput = zod.z.object({
316
+ query: zod.z.string().describe("Natural-language search query."),
317
+ outputSchema: zod.z.record(zod.z.string(), zod.z.unknown()).describe("JSON Schema object for structured synthesis output."),
318
+ type: exaSearchTypeSchema.default("deep").describe("Prefer deep or deep-reasoning for synthesis."),
319
+ category: exaCategorySchema.optional(),
320
+ numResults: zod.z.number().int().min(1).max(100).default(10),
321
+ includeDomains: zod.z.array(zod.z.string()).max(1200).optional(),
322
+ excludeDomains: zod.z.array(zod.z.string()).max(1200).optional(),
323
+ startPublishedDate: zod.z.string().optional(),
324
+ endPublishedDate: zod.z.string().optional(),
325
+ systemPrompt: zod.z.string().optional(),
326
+ additionalQueries: zod.z.array(zod.z.string()).max(10).optional(),
327
+ highlights: zod.z.boolean().default(true),
328
+ text: zod.z.boolean().optional()
329
+ }).superRefine((input, ctx) => {
330
+ try {
331
+ assertCategoryFilters(input.category, {
332
+ excludeDomains: input.excludeDomains,
333
+ startPublishedDate: input.startPublishedDate,
334
+ endPublishedDate: input.endPublishedDate
335
+ });
336
+ } catch (error) {
337
+ ctx.addIssue({
338
+ code: "custom",
339
+ message: error instanceof Error ? error.message : "Invalid category filters"
340
+ });
341
+ }
342
+ });
343
+ const ExaSearchStructuredOutput = zod.z.object({
344
+ requestId: zod.z.string().optional(),
345
+ searchType: zod.z.string().optional(),
346
+ results: zod.z.array(exaSearchResultSchema),
347
+ output: zod.z.object({
348
+ content: zod.z.unknown(),
349
+ grounding: zod.z.array(exaGroundingSchema).optional()
350
+ }).optional(),
351
+ costDollars: zod.z.object({ total: zod.z.number().optional() }).optional()
352
+ });
353
+ const exaSearchStructured = (0, _keystrokehq_keystroke_action.defineAction)({
354
+ key: "exa-search-structured",
355
+ name: "Exa Structured Search",
356
+ description: "Exa search with outputSchema for grounded structured JSON synthesis across sources.",
357
+ input: ExaSearchStructuredInput,
358
+ output: ExaSearchStructuredOutput,
359
+ credentials: [require_credential.exaCredential],
360
+ async run(input, credentials) {
361
+ const client = createExaClient(credentials.exa.apiKey);
362
+ const body = {
363
+ query: input.query,
364
+ type: input.type,
365
+ numResults: input.numResults,
366
+ outputSchema: input.outputSchema
367
+ };
368
+ if (input.category) body.category = input.category;
369
+ if (input.includeDomains?.length) body.includeDomains = input.includeDomains;
370
+ if (input.excludeDomains?.length) body.excludeDomains = input.excludeDomains;
371
+ if (input.startPublishedDate) body.startPublishedDate = input.startPublishedDate;
372
+ if (input.endPublishedDate) body.endPublishedDate = input.endPublishedDate;
373
+ if (input.systemPrompt) body.systemPrompt = input.systemPrompt;
374
+ if (input.additionalQueries?.length) body.additionalQueries = input.additionalQueries;
375
+ const contents = buildSearchContents({
376
+ highlights: input.highlights,
377
+ text: input.text
378
+ });
379
+ if (contents) body.contents = contents;
380
+ const response = await client.search(body);
381
+ return {
382
+ requestId: response.requestId,
383
+ searchType: response.searchType,
384
+ results: (response.results ?? []).map((row) => exaSearchResultSchema.parse(row)),
385
+ output: response.output ? {
386
+ content: response.output.content,
387
+ grounding: response.output.grounding?.map((g) => exaGroundingSchema.parse(g))
388
+ } : void 0,
389
+ costDollars: response.costDollars
390
+ };
391
+ }
392
+ });
393
+ //#endregion
394
+ Object.defineProperty(exports, "ExaAnswerInput", {
395
+ enumerable: true,
396
+ get: function() {
397
+ return ExaAnswerInput;
398
+ }
399
+ });
400
+ Object.defineProperty(exports, "ExaAnswerOutput", {
401
+ enumerable: true,
402
+ get: function() {
403
+ return ExaAnswerOutput;
404
+ }
405
+ });
406
+ Object.defineProperty(exports, "ExaGetContentsInput", {
407
+ enumerable: true,
408
+ get: function() {
409
+ return ExaGetContentsInput;
410
+ }
411
+ });
412
+ Object.defineProperty(exports, "ExaGetContentsOutput", {
413
+ enumerable: true,
414
+ get: function() {
415
+ return ExaGetContentsOutput;
416
+ }
417
+ });
418
+ Object.defineProperty(exports, "ExaGetContextInput", {
419
+ enumerable: true,
420
+ get: function() {
421
+ return ExaGetContextInput;
422
+ }
423
+ });
424
+ Object.defineProperty(exports, "ExaGetContextOutput", {
425
+ enumerable: true,
426
+ get: function() {
427
+ return ExaGetContextOutput;
428
+ }
429
+ });
430
+ Object.defineProperty(exports, "ExaSearchInput", {
431
+ enumerable: true,
432
+ get: function() {
433
+ return ExaSearchInput;
434
+ }
435
+ });
436
+ Object.defineProperty(exports, "ExaSearchOutput", {
437
+ enumerable: true,
438
+ get: function() {
439
+ return ExaSearchOutput;
440
+ }
441
+ });
442
+ Object.defineProperty(exports, "ExaSearchStructuredInput", {
443
+ enumerable: true,
444
+ get: function() {
445
+ return ExaSearchStructuredInput;
446
+ }
447
+ });
448
+ Object.defineProperty(exports, "ExaSearchStructuredOutput", {
449
+ enumerable: true,
450
+ get: function() {
451
+ return ExaSearchStructuredOutput;
452
+ }
453
+ });
454
+ Object.defineProperty(exports, "createExaClient", {
455
+ enumerable: true,
456
+ get: function() {
457
+ return createExaClient;
458
+ }
459
+ });
460
+ Object.defineProperty(exports, "exaAnswer", {
461
+ enumerable: true,
462
+ get: function() {
463
+ return exaAnswer;
464
+ }
465
+ });
466
+ Object.defineProperty(exports, "exaGetContents", {
467
+ enumerable: true,
468
+ get: function() {
469
+ return exaGetContents;
470
+ }
471
+ });
472
+ Object.defineProperty(exports, "exaGetContext", {
473
+ enumerable: true,
474
+ get: function() {
475
+ return exaGetContext;
476
+ }
477
+ });
478
+ Object.defineProperty(exports, "exaSearch", {
479
+ enumerable: true,
480
+ get: function() {
481
+ return exaSearch;
482
+ }
483
+ });
484
+ Object.defineProperty(exports, "exaSearchStructured", {
485
+ enumerable: true,
486
+ get: function() {
487
+ return exaSearchStructured;
488
+ }
489
+ });
490
+
491
+ //# sourceMappingURL=actions-Bl-9uz6K.cjs.map