@mendable/firecrawl-js 4.38.0 → 4.40.0
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 +53 -2
- package/dist/{chunk-KSTNOGOD.js → chunk-OJ4YJQ4J.js} +1 -1
- package/dist/index.cjs +204 -17
- package/dist/index.d.cts +289 -7
- package/dist/index.d.ts +289 -7
- package/dist/index.js +203 -17
- package/dist/{package-OS7RONXY.js → package-F6O7J2XI.js} +1 -1
- package/package.json +1 -1
- package/pnpm-workspace.yaml +3 -2
- package/src/__tests__/e2e/v2/batch.test.ts +13 -11
- package/src/__tests__/e2e/v2/crawl.test.ts +24 -20
- package/src/__tests__/e2e/v2/extract.test.ts +32 -7
- package/src/__tests__/e2e/v2/map.test.ts +4 -3
- package/src/__tests__/e2e/v2/parse.test.ts +4 -3
- package/src/__tests__/e2e/v2/scrape.test.ts +10 -9
- package/src/__tests__/e2e/v2/search.test.ts +9 -8
- package/src/__tests__/e2e/v2/usage.test.ts +6 -5
- package/src/__tests__/e2e/v2/utils/rateLimit.ts +257 -0
- package/src/__tests__/e2e/v2/watcher.test.ts +4 -3
- package/src/__tests__/unit/v2/agent-effort-trace.unit.test.ts +1 -1
- package/src/__tests__/unit/v2/agent-thread.unit.test.ts +164 -0
- package/src/__tests__/unit/v2/e2eRateLimitRetry.test.ts +501 -0
- package/src/__tests__/unit/v2/extract.unit.test.ts +1 -1
- package/src/__tests__/unit/v2/scrapeAutoResume.test.ts +1 -1
- package/src/__tests__/unit/v2/search-country.unit.test.ts +32 -0
- package/src/__tests__/unit/v2/search-data-property.test.ts +1 -0
- package/src/__tests__/unit/v2/threat-protection.unit.test.ts +18 -1
- package/src/__tests__/unit/v2/tools.unit.test.ts +240 -0
- package/src/__tests__/unit/v2/v1-aliases.test.ts +1 -0
- package/src/v2/client.ts +52 -4
- package/src/v2/methods/agent.ts +23 -1
- package/src/v2/methods/research.ts +14 -8
- package/src/v2/methods/scrape.ts +3 -1
- package/src/v2/methods/search.ts +8 -1
- package/src/v2/methods/tools.ts +137 -0
- package/src/v2/types.ts +307 -35
- package/src/v2/utils/errorHandler.ts +19 -3
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AlexandriaCall,
|
|
3
|
+
AlexandriaOptions,
|
|
4
|
+
AlexandriaScrapeData,
|
|
5
|
+
AlexandriaScrapeResult,
|
|
6
|
+
FindToolsData,
|
|
7
|
+
FindToolsOptions,
|
|
8
|
+
} from "../types";
|
|
9
|
+
import { SdkError } from "../types";
|
|
10
|
+
import { HttpClient } from "../utils/httpClient";
|
|
11
|
+
import {
|
|
12
|
+
normalizeAxiosError,
|
|
13
|
+
throwForBadResponse,
|
|
14
|
+
} from "../utils/errorHandler";
|
|
15
|
+
|
|
16
|
+
const ALEXANDRIA_MAX_CALLS = 10;
|
|
17
|
+
|
|
18
|
+
function prepareAlexandriaPayload(
|
|
19
|
+
calls: AlexandriaCall[],
|
|
20
|
+
opts: AlexandriaOptions,
|
|
21
|
+
): Record<string, unknown> {
|
|
22
|
+
if (!Array.isArray(calls) || calls.length === 0) {
|
|
23
|
+
throw new Error("alexandria requires at least one call");
|
|
24
|
+
}
|
|
25
|
+
if (calls.length > ALEXANDRIA_MAX_CALLS) {
|
|
26
|
+
throw new Error(`alexandria accepts at most ${ALEXANDRIA_MAX_CALLS} calls`);
|
|
27
|
+
}
|
|
28
|
+
const alexandria = calls.map((call, index) => {
|
|
29
|
+
if (!call || typeof call.provider !== "string" || !call.provider.trim()) {
|
|
30
|
+
throw new Error(`alexandria[${index}].provider cannot be empty`);
|
|
31
|
+
}
|
|
32
|
+
if (typeof call.capability !== "string" || !call.capability.trim()) {
|
|
33
|
+
throw new Error(`alexandria[${index}].capability cannot be empty`);
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
Object.keys(call).some(
|
|
37
|
+
(key) => !["provider", "capability", "options"].includes(key),
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
throw new Error("Unknown alexandria call option");
|
|
41
|
+
const item: Record<string, unknown> = {
|
|
42
|
+
provider: call.provider.trim(),
|
|
43
|
+
capability: call.capability.trim(),
|
|
44
|
+
};
|
|
45
|
+
if (call.options != null) {
|
|
46
|
+
if (typeof call.options !== "object" || Array.isArray(call.options)) {
|
|
47
|
+
throw new Error(`alexandria[${index}].options must be an object`);
|
|
48
|
+
}
|
|
49
|
+
item.options = call.options;
|
|
50
|
+
}
|
|
51
|
+
return item;
|
|
52
|
+
});
|
|
53
|
+
if (
|
|
54
|
+
opts.timeout != null &&
|
|
55
|
+
(!Number.isInteger(opts.timeout) || opts.timeout <= 0)
|
|
56
|
+
) {
|
|
57
|
+
throw new Error("timeout must be a positive integer");
|
|
58
|
+
}
|
|
59
|
+
const payload: Record<string, unknown> = { alexandria };
|
|
60
|
+
if (opts.timeout != null) payload.timeout = opts.timeout;
|
|
61
|
+
if (opts.integration && opts.integration.trim())
|
|
62
|
+
payload.integration = opts.integration.trim();
|
|
63
|
+
if (opts.origin) payload.origin = opts.origin;
|
|
64
|
+
return payload;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function scrapeAlexandria(
|
|
68
|
+
http: HttpClient,
|
|
69
|
+
calls: AlexandriaCall[],
|
|
70
|
+
opts: AlexandriaOptions = {},
|
|
71
|
+
): Promise<AlexandriaScrapeData> {
|
|
72
|
+
const payload = prepareAlexandriaPayload(calls, opts);
|
|
73
|
+
const requestId = opts.requestId ?? crypto.randomUUID();
|
|
74
|
+
if (!/^[A-Za-z0-9._:-]{1,128}$/.test(requestId))
|
|
75
|
+
throw new Error("Invalid requestId");
|
|
76
|
+
try {
|
|
77
|
+
const res = await http.post<{
|
|
78
|
+
success: boolean;
|
|
79
|
+
scrape_id?: string;
|
|
80
|
+
data?: { alexandria?: AlexandriaScrapeResult[]; creditsCost?: number };
|
|
81
|
+
error?: string;
|
|
82
|
+
}>("/v2/scrape", payload, {
|
|
83
|
+
headers: { "x-request-id": requestId },
|
|
84
|
+
// Allow response delivery after the API's capped execution deadline.
|
|
85
|
+
timeoutMs: Math.min(opts.timeout ?? 50000, 50000) + 30000,
|
|
86
|
+
});
|
|
87
|
+
if (res.status !== 200 || !res.data?.success) {
|
|
88
|
+
throwForBadResponse(res, "alexandria");
|
|
89
|
+
}
|
|
90
|
+
const data = res.data.data;
|
|
91
|
+
if (
|
|
92
|
+
!data ||
|
|
93
|
+
!Array.isArray(data.alexandria) ||
|
|
94
|
+
typeof data.creditsCost !== "number" ||
|
|
95
|
+
!Number.isInteger(data.creditsCost) ||
|
|
96
|
+
data.creditsCost < 0
|
|
97
|
+
) {
|
|
98
|
+
throw new SdkError("Invalid alexandria response");
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
scrapeId: res.data.scrape_id ?? "",
|
|
102
|
+
requestId,
|
|
103
|
+
alexandria: data.alexandria,
|
|
104
|
+
creditsCost: data.creditsCost,
|
|
105
|
+
};
|
|
106
|
+
} catch (err: any) {
|
|
107
|
+
try {
|
|
108
|
+
if (err?.isAxiosError) normalizeAxiosError(err, "alexandria");
|
|
109
|
+
throw err;
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (error && typeof error === "object")
|
|
112
|
+
Object.assign(error, { requestId });
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function findTools(
|
|
119
|
+
http: HttpClient,
|
|
120
|
+
options: FindToolsOptions = {},
|
|
121
|
+
): Promise<FindToolsData> {
|
|
122
|
+
const result = await scrapeAlexandria(http, [
|
|
123
|
+
{
|
|
124
|
+
provider: "firecrawl",
|
|
125
|
+
capability: "find-tools",
|
|
126
|
+
options: { ...options },
|
|
127
|
+
},
|
|
128
|
+
]);
|
|
129
|
+
const item = result.alexandria[0];
|
|
130
|
+
if (!item) throw new SdkError("Missing Find Tools result");
|
|
131
|
+
if (item.error)
|
|
132
|
+
throw Object.assign(
|
|
133
|
+
new SdkError(item.error.message, item.error.status, item.error.code),
|
|
134
|
+
{ requestId: result.requestId },
|
|
135
|
+
);
|
|
136
|
+
return item.data as FindToolsData;
|
|
137
|
+
}
|
package/src/v2/types.ts
CHANGED
|
@@ -275,15 +275,12 @@ export interface ScrapeOptions {
|
|
|
275
275
|
};
|
|
276
276
|
integration?: string;
|
|
277
277
|
origin?: string;
|
|
278
|
+
/** Include domain-matched Alexandria contracts for this URL in `tools`. Default off. */
|
|
279
|
+
domainTools?: boolean;
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
export type RedactPIIEntity =
|
|
281
|
-
| "
|
|
282
|
-
| "EMAIL"
|
|
283
|
-
| "PHONE"
|
|
284
|
-
| "LOCATION"
|
|
285
|
-
| "FINANCIAL"
|
|
286
|
-
| "SECRET";
|
|
283
|
+
"PERSON" | "EMAIL" | "PHONE" | "LOCATION" | "FINANCIAL" | "SECRET";
|
|
287
284
|
|
|
288
285
|
export interface RedactPIIOptions {
|
|
289
286
|
/**
|
|
@@ -324,12 +321,7 @@ export interface ThreatProtectionOptions {
|
|
|
324
321
|
}
|
|
325
322
|
|
|
326
323
|
export type ParseFileData =
|
|
327
|
-
|
|
|
328
|
-
| File
|
|
329
|
-
| Buffer
|
|
330
|
-
| Uint8Array
|
|
331
|
-
| ArrayBuffer
|
|
332
|
-
| string;
|
|
324
|
+
Blob | File | Buffer | Uint8Array | ArrayBuffer | string;
|
|
333
325
|
|
|
334
326
|
export interface ParseFile {
|
|
335
327
|
data: ParseFileData;
|
|
@@ -364,11 +356,7 @@ export interface WebhookConfig {
|
|
|
364
356
|
|
|
365
357
|
// Agent webhook events differ from crawl: has 'action' and 'cancelled', no 'page'
|
|
366
358
|
export type AgentWebhookEvent =
|
|
367
|
-
| "
|
|
368
|
-
| "action"
|
|
369
|
-
| "completed"
|
|
370
|
-
| "failed"
|
|
371
|
-
| "cancelled";
|
|
359
|
+
"started" | "action" | "completed" | "failed" | "cancelled";
|
|
372
360
|
|
|
373
361
|
export interface AgentWebhookConfig {
|
|
374
362
|
url: string;
|
|
@@ -489,10 +477,7 @@ export interface BrandingProfile {
|
|
|
489
477
|
headerHeight?: string;
|
|
490
478
|
footerHeight?: string;
|
|
491
479
|
[key: string]:
|
|
492
|
-
| number
|
|
493
|
-
| string
|
|
494
|
-
| Record<string, number | string | undefined>
|
|
495
|
-
| undefined;
|
|
480
|
+
number | string | Record<string, number | string | undefined> | undefined;
|
|
496
481
|
};
|
|
497
482
|
tone?: {
|
|
498
483
|
voice?: string;
|
|
@@ -702,6 +687,8 @@ export interface Document {
|
|
|
702
687
|
pages?: PdfPage[];
|
|
703
688
|
/** Typed PDF layout blocks, present only when `parsers[].blocks` is true. */
|
|
704
689
|
blocks?: PdfPageBlocks[];
|
|
690
|
+
/** Present when `domainTools` discovered contracts matching this URL. */
|
|
691
|
+
tools?: DiscoveredTool[];
|
|
705
692
|
}
|
|
706
693
|
|
|
707
694
|
// Pagination configuration for auto-fetching pages from v2 endpoints that return a `next` URL
|
|
@@ -814,9 +801,129 @@ export interface SearchResultImages {
|
|
|
814
801
|
}
|
|
815
802
|
|
|
816
803
|
export interface SearchData {
|
|
804
|
+
warning?: string;
|
|
817
805
|
web?: Array<SearchResultWeb | Document>;
|
|
818
806
|
news?: Array<SearchResultNews | Document>;
|
|
819
807
|
images?: Array<SearchResultImages | Document>;
|
|
808
|
+
tools?: DiscoveredTool[];
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/** A complete tool contract returned by semantic or contextual discovery. */
|
|
812
|
+
export interface DiscoveredTool {
|
|
813
|
+
id?: string;
|
|
814
|
+
provider: string;
|
|
815
|
+
capability: string;
|
|
816
|
+
name: string;
|
|
817
|
+
description: string;
|
|
818
|
+
creditsCost: number;
|
|
819
|
+
perRecord: boolean;
|
|
820
|
+
options: Array<{
|
|
821
|
+
name: string;
|
|
822
|
+
type: string;
|
|
823
|
+
required?: boolean;
|
|
824
|
+
[key: string]: unknown;
|
|
825
|
+
}>;
|
|
826
|
+
requiresOneOf?: string[][];
|
|
827
|
+
response?: {
|
|
828
|
+
about?: string;
|
|
829
|
+
key?: string;
|
|
830
|
+
fields?: Array<{ name: string; type: string; [key: string]: unknown }>;
|
|
831
|
+
[key: string]: unknown;
|
|
832
|
+
};
|
|
833
|
+
examples?: Partial<Record<"javascript" | "python" | "curl", string>> &
|
|
834
|
+
Record<string, string>;
|
|
835
|
+
example?: {
|
|
836
|
+
recordedAt: string;
|
|
837
|
+
request: Record<string, unknown>;
|
|
838
|
+
response: unknown;
|
|
839
|
+
};
|
|
840
|
+
label?: string;
|
|
841
|
+
whenToUse?: string;
|
|
842
|
+
returns?: unknown;
|
|
843
|
+
discovery?: unknown;
|
|
844
|
+
attribution?: unknown;
|
|
845
|
+
matchedBy?: Array<"semantic" | "domain">;
|
|
846
|
+
matchedUrls?: string[];
|
|
847
|
+
concept?: string;
|
|
848
|
+
cohorts?: string[];
|
|
849
|
+
similarity?: number;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
export interface FindToolsOptions {
|
|
853
|
+
urls?: string[];
|
|
854
|
+
providers?: string[];
|
|
855
|
+
categories?: string[];
|
|
856
|
+
groups?: string[];
|
|
857
|
+
capabilities?: string[];
|
|
858
|
+
level?: "providers" | "groups" | "tools";
|
|
859
|
+
expand?: Array<"options" | "response" | "examples">;
|
|
860
|
+
limit?: number;
|
|
861
|
+
offset?: number;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
export interface FindToolsData {
|
|
865
|
+
level: "providers" | "groups" | "tools";
|
|
866
|
+
items: Array<{
|
|
867
|
+
id: string;
|
|
868
|
+
name: string;
|
|
869
|
+
next?: AlexandriaCall;
|
|
870
|
+
execute?: Pick<AlexandriaCall, "provider" | "capability">;
|
|
871
|
+
[key: string]: unknown;
|
|
872
|
+
}>;
|
|
873
|
+
total: number;
|
|
874
|
+
next: AlexandriaCall | null;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
export interface AlexandriaScrapeRequest extends AlexandriaOptions {
|
|
878
|
+
alexandria: AlexandriaCall | AlexandriaCall[];
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
export interface AlexandriaCall {
|
|
882
|
+
provider: string;
|
|
883
|
+
capability: string;
|
|
884
|
+
options?: Record<string, unknown>;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
export interface AlexandriaScrapeError {
|
|
888
|
+
code: string;
|
|
889
|
+
message: string;
|
|
890
|
+
status?: number;
|
|
891
|
+
/** Present when credits were captured before the failure. */
|
|
892
|
+
chargeId?: string;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
export type AlexandriaScrapeResult =
|
|
896
|
+
| {
|
|
897
|
+
provider: string;
|
|
898
|
+
capability: string;
|
|
899
|
+
creditsCost: number;
|
|
900
|
+
data: unknown;
|
|
901
|
+
records?: number;
|
|
902
|
+
upstreamStatus?: number;
|
|
903
|
+
recordedAt?: string;
|
|
904
|
+
error?: undefined;
|
|
905
|
+
[key: string]: unknown;
|
|
906
|
+
}
|
|
907
|
+
| {
|
|
908
|
+
provider?: string;
|
|
909
|
+
capability?: string;
|
|
910
|
+
error: AlexandriaScrapeError;
|
|
911
|
+
[key: string]: unknown;
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
export interface AlexandriaScrapeData {
|
|
915
|
+
scrapeId: string;
|
|
916
|
+
requestId: string;
|
|
917
|
+
alexandria: AlexandriaScrapeResult[];
|
|
918
|
+
creditsCost: number;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
export interface AlexandriaOptions {
|
|
922
|
+
/** Reuse this ID with the identical payload when retrying an execution. */
|
|
923
|
+
requestId?: string;
|
|
924
|
+
timeout?: number;
|
|
925
|
+
integration?: string;
|
|
926
|
+
origin?: string;
|
|
820
927
|
}
|
|
821
928
|
|
|
822
929
|
/**
|
|
@@ -847,8 +954,11 @@ export interface CategoryOption {
|
|
|
847
954
|
|
|
848
955
|
export interface SearchRequest {
|
|
849
956
|
query: string;
|
|
957
|
+
/** Include domain-matched contracts in tools alongside semantic matches. */
|
|
958
|
+
domainTools?: boolean;
|
|
850
959
|
sources?: Array<
|
|
851
|
-
"web" | "news" | "images" |
|
|
960
|
+
"web" | "news" | "images" | "alexandria"
|
|
961
|
+
| { type: "web" | "news" | "images" | "alexandria" }
|
|
852
962
|
>;
|
|
853
963
|
/**
|
|
854
964
|
* Narrow web search by category. See {@link CategoryOption}.
|
|
@@ -866,6 +976,8 @@ export interface SearchRequest {
|
|
|
866
976
|
limit?: number;
|
|
867
977
|
tbs?: string;
|
|
868
978
|
location?: string;
|
|
979
|
+
/** ISO 3166-1 alpha-2 country code used to geo-target the search results. */
|
|
980
|
+
country?: string;
|
|
869
981
|
ignoreInvalidURLs?: boolean;
|
|
870
982
|
timeout?: number; // ms
|
|
871
983
|
/** Generate query-relevant highlights for search results. Defaults to true. */
|
|
@@ -1095,9 +1207,7 @@ export interface MonitorSearchTarget {
|
|
|
1095
1207
|
}
|
|
1096
1208
|
|
|
1097
1209
|
export type MonitorTarget =
|
|
1098
|
-
|
|
|
1099
|
-
| MonitorCrawlTarget
|
|
1100
|
-
| MonitorSearchTarget;
|
|
1210
|
+
MonitorScrapeTarget | MonitorCrawlTarget | MonitorSearchTarget;
|
|
1101
1211
|
|
|
1102
1212
|
export interface CreateMonitorRequest {
|
|
1103
1213
|
name: string;
|
|
@@ -1220,11 +1330,7 @@ export interface MonitorCheck {
|
|
|
1220
1330
|
reservedCredits?: number | null;
|
|
1221
1331
|
actualCredits?: number | null;
|
|
1222
1332
|
billingStatus:
|
|
1223
|
-
| "
|
|
1224
|
-
| "reserved"
|
|
1225
|
-
| "confirmed"
|
|
1226
|
-
| "released"
|
|
1227
|
-
| "failed";
|
|
1333
|
+
"not_applicable" | "reserved" | "confirmed" | "released" | "failed";
|
|
1228
1334
|
summary: MonitorSummary;
|
|
1229
1335
|
targetResults?: MonitorTargetResult[];
|
|
1230
1336
|
notificationStatus?: unknown;
|
|
@@ -1311,10 +1417,65 @@ export interface ExtractResponse {
|
|
|
1311
1417
|
creditsUsed?: number;
|
|
1312
1418
|
}
|
|
1313
1419
|
|
|
1420
|
+
/** Conversation mode for an agent run. Defaults to "extract" server-side. */
|
|
1421
|
+
export type AgentMode = "extract" | "chat";
|
|
1422
|
+
|
|
1423
|
+
/** Options forwarded verbatim to the agent; the server owns every default. */
|
|
1424
|
+
export interface AgentExchangeOptions {
|
|
1425
|
+
enabled?: boolean;
|
|
1426
|
+
/** At most 5. */
|
|
1427
|
+
toolkits?: string[];
|
|
1428
|
+
maxCalls?: number;
|
|
1429
|
+
requireApproval?: boolean;
|
|
1430
|
+
/** Answers a pendingApproval from the previous turn of the thread. */
|
|
1431
|
+
approve?: { approvalId: string; callIds?: string[]; always?: boolean };
|
|
1432
|
+
decline?: { approvalId: string };
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
/** Per-run summary reported on a status response. */
|
|
1436
|
+
export interface AgentExchangeSummary {
|
|
1437
|
+
enabled: boolean;
|
|
1438
|
+
/** What the run resolved to after thread inheritance, not what it requested. */
|
|
1439
|
+
toolkits?: string[];
|
|
1440
|
+
requireApproval?: boolean;
|
|
1441
|
+
paidCalls: number;
|
|
1442
|
+
creditsUsed: number | null;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/** A follow-up the agent offers for the next turn of the thread. */
|
|
1446
|
+
export interface AgentSuggestion {
|
|
1447
|
+
label: string;
|
|
1448
|
+
prompt: string;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/** A turn that ended waiting for the caller to allow or refuse paid calls. */
|
|
1452
|
+
export interface PendingApproval {
|
|
1453
|
+
id: string;
|
|
1454
|
+
reason: string;
|
|
1455
|
+
calls: {
|
|
1456
|
+
id: string;
|
|
1457
|
+
provider: string;
|
|
1458
|
+
capability: string;
|
|
1459
|
+
input: Record<string, unknown>;
|
|
1460
|
+
more?: Record<string, unknown>[];
|
|
1461
|
+
creditsEstimate: number | null;
|
|
1462
|
+
}[];
|
|
1463
|
+
resolution: null | {
|
|
1464
|
+
approved: boolean;
|
|
1465
|
+
callIds: string[];
|
|
1466
|
+
always: boolean;
|
|
1467
|
+
byRunId: string;
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1314
1471
|
export interface AgentResponse {
|
|
1315
1472
|
success: boolean;
|
|
1316
1473
|
id: string;
|
|
1317
1474
|
error?: string;
|
|
1475
|
+
/** Thread this run belongs to; pass it back to continue the conversation. */
|
|
1476
|
+
threadId?: string;
|
|
1477
|
+
/** 1-based position of this run in its thread. */
|
|
1478
|
+
threadTurn?: number;
|
|
1318
1479
|
}
|
|
1319
1480
|
|
|
1320
1481
|
export interface AgentStatusResponse {
|
|
@@ -1335,6 +1496,55 @@ export interface AgentStatusResponse {
|
|
|
1335
1496
|
effort?: "low" | "medium" | "high";
|
|
1336
1497
|
expiresAt: string;
|
|
1337
1498
|
creditsUsed?: number;
|
|
1499
|
+
threadId?: string;
|
|
1500
|
+
threadTurn?: number;
|
|
1501
|
+
mode?: AgentMode;
|
|
1502
|
+
/** Assistant text reply. Chat-mode runs answer here instead of in `data`. */
|
|
1503
|
+
message?: string;
|
|
1504
|
+
suggestions?: AgentSuggestion[];
|
|
1505
|
+
pendingApproval?: PendingApproval;
|
|
1506
|
+
exchange?: AgentExchangeSummary;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
/** A single run of a thread, as returned by getAgentThread. */
|
|
1510
|
+
export interface AgentThreadRun {
|
|
1511
|
+
id: string;
|
|
1512
|
+
turn: number;
|
|
1513
|
+
mode: AgentMode;
|
|
1514
|
+
prompt: string;
|
|
1515
|
+
urls?: string[];
|
|
1516
|
+
schema?: unknown;
|
|
1517
|
+
effort?: "low" | "medium" | "high";
|
|
1518
|
+
status:
|
|
1519
|
+
| "processing"
|
|
1520
|
+
| "succeeded"
|
|
1521
|
+
| "failed"
|
|
1522
|
+
| "cancelled"
|
|
1523
|
+
| "refused"
|
|
1524
|
+
| "credit_limit_reached";
|
|
1525
|
+
createdAt: string;
|
|
1526
|
+
finishedAt: string | null;
|
|
1527
|
+
creditsUsed: number | null;
|
|
1528
|
+
message: string | null;
|
|
1529
|
+
/** Only present when the request asked for includeData. */
|
|
1530
|
+
data?: unknown;
|
|
1531
|
+
suggestions?: AgentSuggestion[] | null;
|
|
1532
|
+
pendingApproval?: PendingApproval | null;
|
|
1533
|
+
exchange?: AgentExchangeSummary | null;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
export interface AgentThread {
|
|
1537
|
+
id: string;
|
|
1538
|
+
createdAt: string;
|
|
1539
|
+
updatedAt: string;
|
|
1540
|
+
status: "idle" | "running";
|
|
1541
|
+
runs: AgentThreadRun[];
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
export interface AgentThreadResponse {
|
|
1545
|
+
success: boolean;
|
|
1546
|
+
thread?: AgentThread;
|
|
1547
|
+
error?: string;
|
|
1338
1548
|
}
|
|
1339
1549
|
|
|
1340
1550
|
/** Reasoning effort for agent jobs. Every level runs spark-2. */
|
|
@@ -1384,7 +1594,8 @@ export interface AgentListOptions {
|
|
|
1384
1594
|
before?: number;
|
|
1385
1595
|
}
|
|
1386
1596
|
|
|
1387
|
-
export type AgentTraceAgentRole =
|
|
1597
|
+
export type AgentTraceAgentRole =
|
|
1598
|
+
"orchestrator" | "subagent" | "browser" | "system";
|
|
1388
1599
|
|
|
1389
1600
|
export interface AgentTraceAgentIdentity {
|
|
1390
1601
|
id: string;
|
|
@@ -1394,7 +1605,12 @@ export interface AgentTraceAgentIdentity {
|
|
|
1394
1605
|
}
|
|
1395
1606
|
|
|
1396
1607
|
export interface AgentTraceError {
|
|
1397
|
-
code:
|
|
1608
|
+
code:
|
|
1609
|
+
| "cancelled"
|
|
1610
|
+
| "credit_limit_reached"
|
|
1611
|
+
| "parent_finished"
|
|
1612
|
+
| "refused"
|
|
1613
|
+
| "internal";
|
|
1398
1614
|
source: "agent" | "tool" | "billing" | "system";
|
|
1399
1615
|
retryable: boolean;
|
|
1400
1616
|
message: string;
|
|
@@ -1432,7 +1648,8 @@ export interface AgentTraceRunCancelRequestedEvent extends AgentTraceEventBase {
|
|
|
1432
1648
|
|
|
1433
1649
|
export interface AgentTraceRunFinishedEvent extends AgentTraceEventBase {
|
|
1434
1650
|
type: "run.finished";
|
|
1435
|
-
outcome:
|
|
1651
|
+
outcome:
|
|
1652
|
+
"succeeded" | "failed" | "cancelled" | "refused" | "credit_limit_reached";
|
|
1436
1653
|
/** The canonical schema always writes this key (nullable), but older rows may omit it. */
|
|
1437
1654
|
error?: AgentTraceError | null;
|
|
1438
1655
|
}
|
|
@@ -1617,17 +1834,43 @@ export interface ErrorDetails {
|
|
|
1617
1834
|
status?: number;
|
|
1618
1835
|
}
|
|
1619
1836
|
|
|
1837
|
+
/** An out-of-band step the API requires before the request can succeed. */
|
|
1838
|
+
export interface RequiresAction {
|
|
1839
|
+
type: "accept_terms" | (string & {});
|
|
1840
|
+
terms?: string;
|
|
1841
|
+
version?: string;
|
|
1842
|
+
url?: string;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
export function parseRequiresAction(value: unknown): RequiresAction | undefined {
|
|
1846
|
+
if (!value || typeof value !== "object") return undefined;
|
|
1847
|
+
const record = value as Record<string, unknown>;
|
|
1848
|
+
if (typeof record.type !== "string") return undefined;
|
|
1849
|
+
const action: RequiresAction = { type: record.type };
|
|
1850
|
+
if (typeof record.terms === "string") action.terms = record.terms;
|
|
1851
|
+
if (typeof record.version === "string") action.version = record.version;
|
|
1852
|
+
if (typeof record.url === "string") action.url = record.url;
|
|
1853
|
+
return action;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1620
1856
|
export class SdkError extends Error {
|
|
1857
|
+
requestId?: string;
|
|
1621
1858
|
status?: number;
|
|
1622
1859
|
code?: string;
|
|
1623
1860
|
details?: unknown;
|
|
1624
1861
|
jobId?: string;
|
|
1862
|
+
/** Present on exchange-mediated scrape failures that already captured credits. */
|
|
1863
|
+
chargeId?: string;
|
|
1864
|
+
/** Present when the API needs an out-of-band step first, such as accepting provider terms. */
|
|
1865
|
+
requiresAction?: RequiresAction;
|
|
1625
1866
|
constructor(
|
|
1626
1867
|
message: string,
|
|
1627
1868
|
status?: number,
|
|
1628
1869
|
code?: string,
|
|
1629
1870
|
details?: unknown,
|
|
1630
1871
|
jobId?: string,
|
|
1872
|
+
chargeId?: string,
|
|
1873
|
+
requiresAction?: RequiresAction,
|
|
1631
1874
|
) {
|
|
1632
1875
|
super(message);
|
|
1633
1876
|
this.name = "FirecrawlSdkError";
|
|
@@ -1635,6 +1878,8 @@ export class SdkError extends Error {
|
|
|
1635
1878
|
this.code = code;
|
|
1636
1879
|
this.details = details;
|
|
1637
1880
|
this.jobId = jobId;
|
|
1881
|
+
this.chargeId = chargeId;
|
|
1882
|
+
this.requiresAction = requiresAction;
|
|
1638
1883
|
}
|
|
1639
1884
|
}
|
|
1640
1885
|
|
|
@@ -1829,7 +2074,14 @@ export interface SimilarPapersResponse {
|
|
|
1829
2074
|
note?: string | null;
|
|
1830
2075
|
}
|
|
1831
2076
|
|
|
1832
|
-
/**
|
|
2077
|
+
/**
|
|
2078
|
+
* Component scores; each field is present only when that signal contributed.
|
|
2079
|
+
*
|
|
2080
|
+
* @deprecated Use the developer index instead. The research index GitHub
|
|
2081
|
+
* search stops responding after 2026-11-03. The developer index does not
|
|
2082
|
+
* expose a score breakdown. See
|
|
2083
|
+
* https://docs.firecrawl.dev/features/developer.
|
|
2084
|
+
*/
|
|
1833
2085
|
export interface GitHubScoreBreakdown {
|
|
1834
2086
|
rrf?: number;
|
|
1835
2087
|
semantic?: number;
|
|
@@ -1838,6 +2090,11 @@ export interface GitHubScoreBreakdown {
|
|
|
1838
2090
|
rerank?: number;
|
|
1839
2091
|
}
|
|
1840
2092
|
|
|
2093
|
+
/**
|
|
2094
|
+
* @deprecated Use the developer index instead. The research index GitHub
|
|
2095
|
+
* search stops responding after 2026-11-03. See
|
|
2096
|
+
* https://docs.firecrawl.dev/features/developer.
|
|
2097
|
+
*/
|
|
1841
2098
|
export interface GitHubSearchItem {
|
|
1842
2099
|
resultType?: "github_history" | "repo_readme" | "web";
|
|
1843
2100
|
/** `owner/name`; empty for web results whose URL is not a repo page. */
|
|
@@ -1860,9 +2117,18 @@ export interface GitHubSearchItem {
|
|
|
1860
2117
|
scores: GitHubScoreBreakdown;
|
|
1861
2118
|
}
|
|
1862
2119
|
|
|
2120
|
+
/**
|
|
2121
|
+
* @deprecated Use the developer index instead. The research index GitHub
|
|
2122
|
+
* search stops responding after 2026-11-03. See
|
|
2123
|
+
* https://docs.firecrawl.dev/features/developer.
|
|
2124
|
+
*/
|
|
1863
2125
|
export interface GitHubSearchResponse {
|
|
1864
2126
|
success: boolean;
|
|
1865
2127
|
results: GitHubSearchItem[];
|
|
2128
|
+
/** Deprecation notice while the sunset window is live. */
|
|
2129
|
+
warnings?: string[];
|
|
2130
|
+
/** Replacement endpoint path, while the sunset window is live. */
|
|
2131
|
+
replacement?: string;
|
|
1866
2132
|
}
|
|
1867
2133
|
|
|
1868
2134
|
/** Options for `research.searchPapers`. */
|
|
@@ -1901,7 +2167,13 @@ export interface SimilarPapersOptions {
|
|
|
1901
2167
|
anchor?: string[];
|
|
1902
2168
|
}
|
|
1903
2169
|
|
|
1904
|
-
/**
|
|
2170
|
+
/**
|
|
2171
|
+
* Options for `research.searchGithub`.
|
|
2172
|
+
*
|
|
2173
|
+
* @deprecated Use the developer index instead. The research index GitHub
|
|
2174
|
+
* search stops responding after 2026-11-03. See
|
|
2175
|
+
* https://docs.firecrawl.dev/features/developer.
|
|
2176
|
+
*/
|
|
1905
2177
|
export interface SearchGithubOptions {
|
|
1906
2178
|
/** Number of results to return (1–100, default 20). */
|
|
1907
2179
|
k?: number;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { type AxiosError, type AxiosResponse } from "axios";
|
|
2
|
-
import { SdkError, JobTimeoutError } from "../types";
|
|
2
|
+
import { SdkError, JobTimeoutError, parseRequiresAction } from "../types";
|
|
3
3
|
|
|
4
4
|
export function throwForBadResponse(resp: AxiosResponse, action: string): never {
|
|
5
5
|
const status = resp.status;
|
|
6
6
|
const body = resp.data || {};
|
|
7
7
|
const msg = body?.error || body?.message || `Request failed (${status}) while trying to ${action}`;
|
|
8
|
-
throw new SdkError(
|
|
8
|
+
throw new SdkError(
|
|
9
|
+
msg,
|
|
10
|
+
status,
|
|
11
|
+
body?.code,
|
|
12
|
+
body?.details,
|
|
13
|
+
undefined,
|
|
14
|
+
body?.chargeId,
|
|
15
|
+
parseRequiresAction(body?.requiresAction),
|
|
16
|
+
);
|
|
9
17
|
}
|
|
10
18
|
|
|
11
19
|
export function normalizeAxiosError(err: AxiosError, action: string): never {
|
|
@@ -13,7 +21,15 @@ export function normalizeAxiosError(err: AxiosError, action: string): never {
|
|
|
13
21
|
const body: any = err.response?.data;
|
|
14
22
|
const message = body?.error || err.message || `Request failed${status ? ` (${status})` : ""} while trying to ${action}`;
|
|
15
23
|
const code = (body?.code as string) || err.code;
|
|
16
|
-
throw new SdkError(
|
|
24
|
+
throw new SdkError(
|
|
25
|
+
message,
|
|
26
|
+
status,
|
|
27
|
+
code,
|
|
28
|
+
body?.details ?? body,
|
|
29
|
+
undefined,
|
|
30
|
+
body?.chargeId,
|
|
31
|
+
parseRequiresAction(body?.requiresAction),
|
|
32
|
+
);
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
export function isRetryableError(err: any): boolean {
|