exa-js 1.7.1 → 1.7.3
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 +28 -0
- package/dist/index.d.mts +107 -64
- package/dist/index.d.ts +107 -64
- package/dist/index.js +161 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -636,14 +636,95 @@ var WebsetsClient = class extends WebsetsBaseClient {
|
|
|
636
636
|
}
|
|
637
637
|
};
|
|
638
638
|
|
|
639
|
-
// src/
|
|
640
|
-
var
|
|
641
|
-
|
|
639
|
+
// src/research/base.ts
|
|
640
|
+
var ResearchBaseClient = class {
|
|
641
|
+
/**
|
|
642
|
+
* Initialize a new Research base client
|
|
643
|
+
* @param client The Exa client instance
|
|
644
|
+
*/
|
|
645
|
+
constructor(client) {
|
|
646
|
+
this.client = client;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Make a request to the Research API (prefixes all paths with `/research`).
|
|
650
|
+
* @param endpoint The endpoint path, beginning with a slash (e.g. "/tasks").
|
|
651
|
+
* @param method The HTTP method. Defaults to "POST".
|
|
652
|
+
* @param data Optional request body
|
|
653
|
+
* @param params Optional query parameters
|
|
654
|
+
* @returns The parsed JSON response
|
|
655
|
+
*/
|
|
656
|
+
async request(endpoint, method = "POST", data, params) {
|
|
657
|
+
return this.client.request(`/research${endpoint}`, method, data, params);
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
// src/research/client.ts
|
|
662
|
+
var ResearchClient = class extends ResearchBaseClient {
|
|
663
|
+
constructor(client) {
|
|
664
|
+
super(client);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Create a research task.
|
|
668
|
+
*
|
|
669
|
+
* Both parameters are required and have fixed shapes:
|
|
670
|
+
* 1. `input`
|
|
671
|
+
* `{ instructions: string }`
|
|
672
|
+
* • `instructions` – High-level guidance that tells the research agent what to do.
|
|
673
|
+
* 2. `output`
|
|
674
|
+
* defines the exact structure you expect back, and guides the research conducted by the agent.
|
|
675
|
+
* `{ schema: JSONSchema }`.
|
|
676
|
+
* The agent's response will be validated against this schema.
|
|
677
|
+
*
|
|
678
|
+
* @param input Object containing high-level research instructions.
|
|
679
|
+
* @param output Object containing the expected output schema.
|
|
680
|
+
* @returns The ResearchTaskResponse returned by the API.
|
|
681
|
+
*/
|
|
682
|
+
async createTask(input, output) {
|
|
683
|
+
return this.request("/tasks", "POST", {
|
|
684
|
+
input,
|
|
685
|
+
output
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Retrieve a research task by ID.
|
|
690
|
+
*/
|
|
691
|
+
async getTask(id) {
|
|
692
|
+
return this.request(`/tasks/${id}`, "GET");
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Poll a research task until completion or failure.
|
|
696
|
+
* Polls every 1 second with a maximum timeout of 10 minutes.
|
|
697
|
+
*/
|
|
698
|
+
async pollTask(id) {
|
|
699
|
+
const pollingInterval = 1e3;
|
|
700
|
+
const maxPollingTime = 10 * 60 * 1e3;
|
|
701
|
+
const startTime = Date.now();
|
|
702
|
+
while (true) {
|
|
703
|
+
const task = await this.request(`/tasks/${id}`, "GET");
|
|
704
|
+
if (task.status === "completed" || task.status === "failed") {
|
|
705
|
+
return task;
|
|
706
|
+
}
|
|
707
|
+
if (Date.now() - startTime > maxPollingTime) {
|
|
708
|
+
throw new Error(
|
|
709
|
+
`Polling timeout: Task ${id} did not complete within 10 minutes`
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
// src/research/types.ts
|
|
642
718
|
var ResearchStatus = /* @__PURE__ */ ((ResearchStatus2) => {
|
|
719
|
+
ResearchStatus2["in_progress"] = "in_progress";
|
|
643
720
|
ResearchStatus2["completed"] = "completed";
|
|
644
721
|
ResearchStatus2["failed"] = "failed";
|
|
645
722
|
return ResearchStatus2;
|
|
646
723
|
})(ResearchStatus || {});
|
|
724
|
+
|
|
725
|
+
// src/index.ts
|
|
726
|
+
var fetchImpl = typeof global !== "undefined" && global.fetch ? global.fetch : fetch;
|
|
727
|
+
var HeadersImpl = typeof global !== "undefined" && global.Headers ? global.Headers : Headers;
|
|
647
728
|
var Exa2 = class {
|
|
648
729
|
/**
|
|
649
730
|
* Helper method to separate out the contents-specific options from the rest.
|
|
@@ -701,6 +782,7 @@ var Exa2 = class {
|
|
|
701
782
|
"User-Agent": "exa-node 1.4.0"
|
|
702
783
|
});
|
|
703
784
|
this.websets = new WebsetsClient(this);
|
|
785
|
+
this.research = new ResearchClient(this);
|
|
704
786
|
}
|
|
705
787
|
/**
|
|
706
788
|
* Makes a request to the Exa API.
|
|
@@ -750,6 +832,10 @@ var Exa2 = class {
|
|
|
750
832
|
errorData.path
|
|
751
833
|
);
|
|
752
834
|
}
|
|
835
|
+
const contentType = response.headers.get("content-type") || "";
|
|
836
|
+
if (contentType.includes("text/event-stream")) {
|
|
837
|
+
return await this.parseSSEStream(response);
|
|
838
|
+
}
|
|
753
839
|
return await response.json();
|
|
754
840
|
}
|
|
755
841
|
/**
|
|
@@ -973,47 +1059,76 @@ var Exa2 = class {
|
|
|
973
1059
|
}
|
|
974
1060
|
return { content, citations };
|
|
975
1061
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1062
|
+
async parseSSEStream(response) {
|
|
1063
|
+
const reader = response.body?.getReader();
|
|
1064
|
+
if (!reader) {
|
|
1065
|
+
throw new ExaError(
|
|
1066
|
+
"No response body available for streaming.",
|
|
1067
|
+
500,
|
|
1068
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
const decoder = new TextDecoder();
|
|
1072
|
+
let buffer = "";
|
|
1073
|
+
return new Promise(async (resolve, reject) => {
|
|
1074
|
+
try {
|
|
1075
|
+
while (true) {
|
|
1076
|
+
const { done, value } = await reader.read();
|
|
1077
|
+
if (done) break;
|
|
1078
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1079
|
+
const lines = buffer.split("\n");
|
|
1080
|
+
buffer = lines.pop() || "";
|
|
1081
|
+
for (const line of lines) {
|
|
1082
|
+
if (!line.startsWith("data: ")) continue;
|
|
1083
|
+
const jsonStr = line.replace(/^data:\s*/, "").trim();
|
|
1084
|
+
if (!jsonStr || jsonStr === "[DONE]") {
|
|
1085
|
+
continue;
|
|
1086
|
+
}
|
|
1087
|
+
let chunk;
|
|
1088
|
+
try {
|
|
1089
|
+
chunk = JSON.parse(jsonStr);
|
|
1090
|
+
} catch {
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
switch (chunk.tag) {
|
|
1094
|
+
case "complete":
|
|
1095
|
+
reader.releaseLock();
|
|
1096
|
+
resolve(chunk.data);
|
|
1097
|
+
return;
|
|
1098
|
+
case "error": {
|
|
1099
|
+
const message = chunk.error?.message || "Unknown error";
|
|
1100
|
+
reader.releaseLock();
|
|
1101
|
+
reject(
|
|
1102
|
+
new ExaError(
|
|
1103
|
+
message,
|
|
1104
|
+
500 /* InternalServerError */,
|
|
1105
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
1106
|
+
)
|
|
1107
|
+
);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
// 'progress' and any other tags are ignored for the blocking variant
|
|
1111
|
+
default:
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
reject(
|
|
1117
|
+
new ExaError(
|
|
1118
|
+
"Stream ended without a completion event.",
|
|
1119
|
+
500 /* InternalServerError */,
|
|
1120
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
1121
|
+
)
|
|
1122
|
+
);
|
|
1123
|
+
} catch (err) {
|
|
1124
|
+
reject(err);
|
|
1125
|
+
} finally {
|
|
1126
|
+
try {
|
|
1127
|
+
reader.releaseLock();
|
|
1128
|
+
} catch {
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1017
1132
|
}
|
|
1018
1133
|
};
|
|
1019
1134
|
var index_default = Exa2;
|
|
@@ -1024,6 +1139,7 @@ export {
|
|
|
1024
1139
|
Exa2 as Exa,
|
|
1025
1140
|
ExaError,
|
|
1026
1141
|
HttpStatusCode,
|
|
1142
|
+
ResearchClient,
|
|
1027
1143
|
ResearchStatus,
|
|
1028
1144
|
WebhookStatus,
|
|
1029
1145
|
WebsetEnrichmentFormat,
|