@openclaw/firecrawl-plugin 2026.7.2-beta.5 → 2026.8.1-beta.2
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/api.js +1 -1
- package/dist/{firecrawl-client-DZohiNQK.js → firecrawl-client-Aw46OXVC.js} +71 -35
- package/dist/{firecrawl-fetch-provider-DXmd_5yB.js → firecrawl-fetch-provider-CYViV-li.js} +1 -1
- package/dist/{firecrawl-free-search-provider-D_QqmJGK.js → firecrawl-free-search-provider-nqgr2mhw.js} +10 -6
- package/dist/index.js +13 -7
- package/dist/web-fetch-provider.js +1 -1
- package/dist/web-search-provider.js +1 -1
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as runFirecrawlScrape } from "./firecrawl-client-
|
|
1
|
+
import { n as runFirecrawlScrape } from "./firecrawl-client-Aw46OXVC.js";
|
|
2
2
|
import { readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
//#region extensions/firecrawl/api.ts
|
|
4
4
|
async function fetchFirecrawlContent(params) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { readProviderJsonObjectResponse } from "openclaw/plugin-sdk/provider-http";
|
|
2
|
-
import { DEFAULT_CACHE_TTL_MINUTES, markdownToText, normalizeCacheKey, readCache, readResponseText, resolveCacheTtlMs, resolvePositiveTimeoutSeconds,
|
|
2
|
+
import { DEFAULT_CACHE_TTL_MINUTES, markdownToText, normalizeCacheKey, readCache, readResponseText, resolveCacheTtlMs, resolvePositiveTimeoutSeconds, withSelfHostedWebToolsEndpoint, withStrictWebToolsEndpoint, writeCache } from "openclaw/plugin-sdk/provider-web-fetch";
|
|
3
3
|
import { normalizeSecretInput, resolveSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
4
|
-
import { wrapExternalContent, wrapWebContent } from "openclaw/plugin-sdk/security-runtime";
|
|
4
|
+
import { truncateSanitizedExternalContent, wrapExternalContent, wrapWebContent } from "openclaw/plugin-sdk/security-runtime";
|
|
5
5
|
import { SsrFBlockedError, isBlockedHostnameOrIp, isPrivateIpAddress, resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
6
6
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
-
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
8
7
|
import { canResolveEnvSecretRefInReadOnlyPath } from "openclaw/plugin-sdk/extension-shared";
|
|
9
8
|
//#region \0rolldown/runtime.js
|
|
10
9
|
var __defProp = Object.defineProperty;
|
|
@@ -103,7 +102,6 @@ function resolveFirecrawlSearchTimeoutSeconds(override) {
|
|
|
103
102
|
//#endregion
|
|
104
103
|
//#region extensions/firecrawl/src/firecrawl-client.ts
|
|
105
104
|
var firecrawl_client_exports = /* @__PURE__ */ __exportAll({
|
|
106
|
-
__testing: () => testing,
|
|
107
105
|
assertFirecrawlScrapeTargetAllowed: () => assertFirecrawlScrapeTargetAllowed,
|
|
108
106
|
parseFirecrawlScrapePayload: () => parseFirecrawlScrapePayload,
|
|
109
107
|
runFirecrawlScrape: () => runFirecrawlScrape,
|
|
@@ -113,9 +111,14 @@ var firecrawl_client_exports = /* @__PURE__ */ __exportAll({
|
|
|
113
111
|
const SEARCH_CACHE = /* @__PURE__ */ new Map();
|
|
114
112
|
const SCRAPE_CACHE = /* @__PURE__ */ new Map();
|
|
115
113
|
const DEFAULT_SEARCH_COUNT = 5;
|
|
114
|
+
const FIRECRAWL_SEARCH_MAX_RESULTS = 100;
|
|
115
|
+
const FIRECRAWL_SEARCH_MAX_CONTENT_CHARS = 2e4;
|
|
116
116
|
const DEFAULT_SCRAPE_MAX_CHARS = 5e4;
|
|
117
|
+
const FIRECRAWL_SCRAPE_METADATA_MAX_CHARS = 4e3;
|
|
118
|
+
const FIRECRAWL_RESULT_URL_MAX_CHARS = 2048;
|
|
117
119
|
const FIRECRAWL_SCRAPE_RESPONSE_MAX_BYTES = 64 * 1024 * 1024;
|
|
118
120
|
const ALLOWED_FIRECRAWL_HOSTS = /* @__PURE__ */ new Set(["api.firecrawl.dev"]);
|
|
121
|
+
const FIRECRAWL_PUBLISHED_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:[T ][\d:.+Z-]{0,20})?$/u;
|
|
119
122
|
const FIRECRAWL_SELF_HOSTED_PRIVATE_ERROR = "Firecrawl custom baseUrl must target a private or internal self-hosted endpoint.";
|
|
120
123
|
const FIRECRAWL_HTTP_PRIVATE_ERROR = "Firecrawl HTTP baseUrl must target a private or internal self-hosted endpoint. Use https:// for public hosts.";
|
|
121
124
|
async function readFirecrawlJsonResponse(response, label, opts) {
|
|
@@ -176,6 +179,7 @@ async function postFirecrawlJson(params, parse) {
|
|
|
176
179
|
return await ((params.mode ?? await validateFirecrawlBaseUrl(params.url)) === "selfHosted" ? withSelfHostedWebToolsEndpoint : withStrictWebToolsEndpoint)({
|
|
177
180
|
url: params.url,
|
|
178
181
|
timeoutSeconds: params.timeoutSeconds,
|
|
182
|
+
...params.signal ? { signal: params.signal } : {},
|
|
179
183
|
init: {
|
|
180
184
|
method: "POST",
|
|
181
185
|
headers: {
|
|
@@ -204,7 +208,7 @@ async function postFirecrawlJson(params, parse) {
|
|
|
204
208
|
const errorBody = await readResponseText(response, { maxBytes: 64e3 });
|
|
205
209
|
if (errorBody.text) detail = errorBody.text;
|
|
206
210
|
}
|
|
207
|
-
const safeDetail = wrapWebContent(
|
|
211
|
+
const safeDetail = wrapWebContent(truncateSanitizedExternalContent(detail, 1e3).text, "web_fetch");
|
|
208
212
|
throw new Error(`${params.errorLabel} API error (${response.status}): ${safeDetail}`);
|
|
209
213
|
}
|
|
210
214
|
return await parse(response);
|
|
@@ -217,6 +221,16 @@ function resolveSiteName(urlRaw) {
|
|
|
217
221
|
return;
|
|
218
222
|
}
|
|
219
223
|
}
|
|
224
|
+
function normalizeFirecrawlResultUrl(value) {
|
|
225
|
+
if (typeof value !== "string" || value.length > FIRECRAWL_RESULT_URL_MAX_CHARS) return;
|
|
226
|
+
try {
|
|
227
|
+
const url = new URL(value);
|
|
228
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || url.href.length > FIRECRAWL_RESULT_URL_MAX_CHARS) return;
|
|
229
|
+
return url.href === `${value}/` ? value : url.href;
|
|
230
|
+
} catch {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
220
234
|
function resolveSearchItems(payload) {
|
|
221
235
|
const rawItems = [
|
|
222
236
|
payload.data,
|
|
@@ -228,16 +242,17 @@ function resolveSearchItems(payload) {
|
|
|
228
242
|
].find((candidate) => Array.isArray(candidate));
|
|
229
243
|
if (!Array.isArray(rawItems)) return [];
|
|
230
244
|
const items = [];
|
|
231
|
-
for (const entry of rawItems) {
|
|
245
|
+
for (const entry of rawItems.slice(0, FIRECRAWL_SEARCH_MAX_RESULTS)) {
|
|
232
246
|
if (!entry || typeof entry !== "object") continue;
|
|
233
247
|
const record = entry;
|
|
234
248
|
const metadata = record.metadata && typeof record.metadata === "object" ? record.metadata : void 0;
|
|
235
|
-
const url = typeof record.url === "string" && record.url || typeof record.sourceURL === "string" && record.sourceURL || typeof record.sourceUrl === "string" && record.sourceUrl || typeof metadata?.sourceURL === "string" && metadata.sourceURL || "";
|
|
249
|
+
const url = normalizeFirecrawlResultUrl(typeof record.url === "string" && record.url || typeof record.sourceURL === "string" && record.sourceURL || typeof record.sourceUrl === "string" && record.sourceUrl || typeof metadata?.sourceURL === "string" && metadata.sourceURL || "");
|
|
236
250
|
if (!url) continue;
|
|
237
251
|
const title = typeof record.title === "string" && record.title || typeof metadata?.title === "string" && metadata.title || "";
|
|
238
252
|
const description = typeof record.description === "string" && record.description || typeof record.snippet === "string" && record.snippet || typeof record.summary === "string" && record.summary || void 0;
|
|
239
253
|
const content = typeof record.markdown === "string" && record.markdown || typeof record.content === "string" && record.content || typeof record.text === "string" && record.text || void 0;
|
|
240
|
-
const
|
|
254
|
+
const rawPublished = typeof record.publishedDate === "string" && record.publishedDate || typeof record.published === "string" && record.published || typeof metadata?.publishedTime === "string" && metadata.publishedTime || typeof metadata?.publishedDate === "string" && metadata.publishedDate || void 0;
|
|
255
|
+
const published = rawPublished && FIRECRAWL_PUBLISHED_DATE_RE.test(rawPublished) ? rawPublished : void 0;
|
|
241
256
|
items.push({
|
|
242
257
|
title,
|
|
243
258
|
url,
|
|
@@ -250,6 +265,22 @@ function resolveSearchItems(payload) {
|
|
|
250
265
|
return items;
|
|
251
266
|
}
|
|
252
267
|
function buildSearchPayload(params) {
|
|
268
|
+
let remainingContentChars = FIRECRAWL_SEARCH_MAX_CONTENT_CHARS;
|
|
269
|
+
let truncated = false;
|
|
270
|
+
const wrapBoundedContent = (value) => {
|
|
271
|
+
const bounded = truncateSanitizedExternalContent(value, remainingContentChars);
|
|
272
|
+
truncated ||= bounded.truncated;
|
|
273
|
+
remainingContentChars -= bounded.text.length;
|
|
274
|
+
return wrapWebContent(bounded.text, "web_search");
|
|
275
|
+
};
|
|
276
|
+
const results = params.items.map((entry) => ({
|
|
277
|
+
title: entry.title ? wrapBoundedContent(entry.title) : "",
|
|
278
|
+
url: entry.url,
|
|
279
|
+
description: entry.description ? wrapBoundedContent(entry.description) : "",
|
|
280
|
+
...entry.published ? { published: entry.published } : {},
|
|
281
|
+
...entry.siteName ? { siteName: entry.siteName } : {},
|
|
282
|
+
...params.scrapeResults && entry.content ? { content: wrapBoundedContent(entry.content) } : {}
|
|
283
|
+
}));
|
|
253
284
|
return {
|
|
254
285
|
query: params.query,
|
|
255
286
|
provider: params.provider,
|
|
@@ -261,17 +292,12 @@ function buildSearchPayload(params) {
|
|
|
261
292
|
provider: params.provider,
|
|
262
293
|
wrapped: true
|
|
263
294
|
},
|
|
264
|
-
results
|
|
265
|
-
|
|
266
|
-
url: entry.url,
|
|
267
|
-
description: entry.description ? wrapWebContent(entry.description, "web_search") : "",
|
|
268
|
-
...entry.published ? { published: entry.published } : {},
|
|
269
|
-
...entry.siteName ? { siteName: entry.siteName } : {},
|
|
270
|
-
...params.scrapeResults && entry.content ? { content: wrapWebContent(entry.content, "web_search") } : {}
|
|
271
|
-
}))
|
|
295
|
+
results,
|
|
296
|
+
...truncated ? { truncated: true } : {}
|
|
272
297
|
};
|
|
273
298
|
}
|
|
274
299
|
async function runFirecrawlSearch(params) {
|
|
300
|
+
params.signal?.throwIfAborted();
|
|
275
301
|
const keyless = params.access === "keyless";
|
|
276
302
|
const providerId = keyless ? "firecrawl-free" : "firecrawl";
|
|
277
303
|
const apiKey = keyless ? void 0 : resolveFirecrawlApiKey(params.cfg);
|
|
@@ -328,19 +354,20 @@ async function runFirecrawlSearch(params) {
|
|
|
328
354
|
timeoutSeconds,
|
|
329
355
|
apiKey,
|
|
330
356
|
body,
|
|
331
|
-
errorLabel: "Firecrawl Search"
|
|
357
|
+
errorLabel: "Firecrawl Search",
|
|
358
|
+
...params.signal ? { signal: params.signal } : {}
|
|
332
359
|
}, async (response) => {
|
|
333
360
|
const payloadValue = await readFirecrawlJsonResponse(response, "Firecrawl Search API error");
|
|
334
361
|
if (payloadValue.success === false) {
|
|
335
|
-
const
|
|
336
|
-
throw new Error(`Firecrawl Search API error: ${
|
|
362
|
+
const safeError = wrapWebContent(truncateSanitizedExternalContent(typeof payloadValue.error === "string" ? payloadValue.error : typeof payloadValue.message === "string" ? payloadValue.message : "unknown error", 1e3).text, "web_search");
|
|
363
|
+
throw new Error(`Firecrawl Search API error: ${safeError}`);
|
|
337
364
|
}
|
|
338
365
|
return payloadValue;
|
|
339
366
|
});
|
|
340
367
|
const result = buildSearchPayload({
|
|
341
368
|
query: params.query,
|
|
342
369
|
provider: providerId,
|
|
343
|
-
items: resolveSearchItems(payload),
|
|
370
|
+
items: resolveSearchItems(payload).slice(0, count),
|
|
344
371
|
tookMs: Date.now() - start,
|
|
345
372
|
scrapeResults
|
|
346
373
|
});
|
|
@@ -358,23 +385,28 @@ function parseFirecrawlScrapePayload(params) {
|
|
|
358
385
|
const markdown = typeof data.markdown === "string" && data.markdown || typeof data.content === "string" && data.content || "";
|
|
359
386
|
if (!markdown) throw new Error("Firecrawl scrape returned no content.");
|
|
360
387
|
const rawText = params.extractMode === "text" ? markdownToText(markdown) : markdown;
|
|
361
|
-
const
|
|
362
|
-
|
|
388
|
+
const boundedText = truncateSanitizedExternalContent(rawText, params.maxChars);
|
|
389
|
+
let truncated = boundedText.truncated;
|
|
390
|
+
let remainingMetadataChars = FIRECRAWL_SCRAPE_METADATA_MAX_CHARS;
|
|
391
|
+
const wrapBoundedMetadata = (value) => {
|
|
392
|
+
const bounded = truncateSanitizedExternalContent(value, remainingMetadataChars);
|
|
393
|
+
truncated ||= bounded.truncated;
|
|
394
|
+
remainingMetadataChars -= bounded.text.length;
|
|
395
|
+
return wrapExternalContent(bounded.text, {
|
|
396
|
+
source: "web_fetch",
|
|
397
|
+
includeWarning: false
|
|
398
|
+
});
|
|
399
|
+
};
|
|
400
|
+
const wrappedText = wrapExternalContent(boundedText.text, {
|
|
363
401
|
source: "web_fetch",
|
|
364
402
|
includeWarning: false
|
|
365
403
|
});
|
|
366
404
|
const status = typeof metadata?.statusCode === "number" && metadata.statusCode || typeof data.statusCode === "number" && data.statusCode || void 0;
|
|
367
|
-
const title = typeof metadata?.title === "string" && metadata.title ?
|
|
368
|
-
|
|
369
|
-
includeWarning: false
|
|
370
|
-
}) : void 0;
|
|
371
|
-
const warning = typeof params.payload.warning === "string" && params.payload.warning ? wrapExternalContent(params.payload.warning, {
|
|
372
|
-
source: "web_fetch",
|
|
373
|
-
includeWarning: false
|
|
374
|
-
}) : void 0;
|
|
405
|
+
const title = typeof metadata?.title === "string" && metadata.title ? wrapBoundedMetadata(metadata.title) : void 0;
|
|
406
|
+
const warning = typeof params.payload.warning === "string" && params.payload.warning ? wrapBoundedMetadata(params.payload.warning) : void 0;
|
|
375
407
|
return {
|
|
376
408
|
url: params.url,
|
|
377
|
-
finalUrl:
|
|
409
|
+
finalUrl: normalizeFirecrawlResultUrl(metadata?.sourceURL) ?? normalizeFirecrawlResultUrl(data.url) ?? params.url,
|
|
378
410
|
...status !== void 0 ? { status } : {},
|
|
379
411
|
...title ? { title } : {},
|
|
380
412
|
extractor: "firecrawl",
|
|
@@ -384,7 +416,7 @@ function parseFirecrawlScrapePayload(params) {
|
|
|
384
416
|
source: "web_fetch",
|
|
385
417
|
wrapped: true
|
|
386
418
|
},
|
|
387
|
-
truncated
|
|
419
|
+
truncated,
|
|
388
420
|
rawLength: rawText.length,
|
|
389
421
|
length: wrappedText.length,
|
|
390
422
|
text: wrappedText,
|
|
@@ -392,6 +424,7 @@ function parseFirecrawlScrapePayload(params) {
|
|
|
392
424
|
};
|
|
393
425
|
}
|
|
394
426
|
async function runFirecrawlScrape(params) {
|
|
427
|
+
params.signal?.throwIfAborted();
|
|
395
428
|
assertFirecrawlScrapeTargetAllowed(params.url);
|
|
396
429
|
const apiKey = resolveFirecrawlApiKey(params.cfg);
|
|
397
430
|
if (!apiKey && params.access !== "keyless") throw new Error("firecrawl_scrape needs a Firecrawl API key. Set FIRECRAWL_API_KEY in the Gateway environment, or configure plugins.entries.firecrawl.config.webFetch.apiKey.");
|
|
@@ -401,7 +434,10 @@ async function runFirecrawlScrape(params) {
|
|
|
401
434
|
const maxAgeMs = resolveFirecrawlMaxAgeMs(params.cfg, params.maxAgeMs);
|
|
402
435
|
const proxy = params.proxy ?? "auto";
|
|
403
436
|
const storeInCache = params.storeInCache ?? true;
|
|
404
|
-
const
|
|
437
|
+
const configuredMaxCharsCap = params.cfg?.tools?.web?.fetch?.maxCharsCap;
|
|
438
|
+
const maxCharsCap = typeof configuredMaxCharsCap === "number" && Number.isFinite(configuredMaxCharsCap) && configuredMaxCharsCap > 0 ? Math.floor(configuredMaxCharsCap) : DEFAULT_SCRAPE_MAX_CHARS;
|
|
439
|
+
const requestedMaxChars = typeof params.maxChars === "number" && Number.isFinite(params.maxChars) && params.maxChars > 0 ? Math.floor(params.maxChars) : DEFAULT_SCRAPE_MAX_CHARS;
|
|
440
|
+
const maxChars = Math.min(requestedMaxChars, maxCharsCap);
|
|
405
441
|
const cacheKey = normalizeCacheKey(JSON.stringify({
|
|
406
442
|
type: "firecrawl-scrape",
|
|
407
443
|
url: params.url,
|
|
@@ -426,6 +462,7 @@ async function runFirecrawlScrape(params) {
|
|
|
426
462
|
timeoutSeconds,
|
|
427
463
|
apiKey,
|
|
428
464
|
errorLabel: "Firecrawl",
|
|
465
|
+
...params.signal ? { signal: params.signal } : {},
|
|
429
466
|
body: {
|
|
430
467
|
url: params.url,
|
|
431
468
|
formats: ["markdown"],
|
|
@@ -439,7 +476,7 @@ async function runFirecrawlScrape(params) {
|
|
|
439
476
|
const payloadLocal = await readFirecrawlJsonResponse(response, "Firecrawl fetch failed", { maxBytes: FIRECRAWL_SCRAPE_RESPONSE_MAX_BYTES });
|
|
440
477
|
if (payloadLocal.success === false) {
|
|
441
478
|
const detail = typeof payloadLocal.error === "string" ? payloadLocal.error : typeof payloadLocal.message === "string" ? payloadLocal.message : response.statusText;
|
|
442
|
-
throw new Error(`Firecrawl fetch failed (${response.status}): ${wrapWebContent(detail, "web_fetch")}`.trim());
|
|
479
|
+
throw new Error(`Firecrawl fetch failed (${response.status}): ${wrapWebContent(truncateSanitizedExternalContent(detail, FIRECRAWL_SCRAPE_METADATA_MAX_CHARS).text, "web_fetch")}`.trim());
|
|
443
480
|
}
|
|
444
481
|
return payloadLocal;
|
|
445
482
|
}),
|
|
@@ -456,7 +493,6 @@ const testing = {
|
|
|
456
493
|
postFirecrawlJson,
|
|
457
494
|
readFirecrawlJsonResponse,
|
|
458
495
|
resolveEndpoint,
|
|
459
|
-
validateFirecrawlBaseUrl,
|
|
460
496
|
resolveSearchItems
|
|
461
497
|
};
|
|
462
498
|
//#endregion
|
|
@@ -4,7 +4,7 @@ import { enablePluginInConfig } from "openclaw/plugin-sdk/provider-web-fetch-con
|
|
|
4
4
|
//#region extensions/firecrawl/src/firecrawl-fetch-provider.ts
|
|
5
5
|
let firecrawlClientModulePromise;
|
|
6
6
|
function loadFirecrawlClientModule() {
|
|
7
|
-
firecrawlClientModulePromise ??= import("./firecrawl-client-
|
|
7
|
+
firecrawlClientModulePromise ??= import("./firecrawl-client-Aw46OXVC.js").then((n) => n.t);
|
|
8
8
|
return firecrawlClientModulePromise;
|
|
9
9
|
}
|
|
10
10
|
function createFirecrawlWebFetchProvider() {
|
|
@@ -2,7 +2,7 @@ import { buildFirecrawlFreeWebSearchProviderBase, buildFirecrawlWebSearchProvide
|
|
|
2
2
|
import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
|
|
3
3
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
4
4
|
//#region extensions/firecrawl/src/firecrawl-search-provider.ts
|
|
5
|
-
const loadFirecrawlClientModule$1 = createLazyRuntimeModule(() => import("./firecrawl-client-
|
|
5
|
+
const loadFirecrawlClientModule$1 = createLazyRuntimeModule(() => import("./firecrawl-client-Aw46OXVC.js").then((n) => n.t));
|
|
6
6
|
const GenericFirecrawlSearchSchema = {
|
|
7
7
|
type: "object",
|
|
8
8
|
properties: {
|
|
@@ -25,7 +25,8 @@ function createFirecrawlWebSearchProvider() {
|
|
|
25
25
|
createTool: (ctx) => ({
|
|
26
26
|
description: "Search the web using Firecrawl. Returns structured results with snippets from Firecrawl Search. Use firecrawl_search for Firecrawl-specific knobs like sources or categories.",
|
|
27
27
|
parameters: GenericFirecrawlSearchSchema,
|
|
28
|
-
execute: async (args) => {
|
|
28
|
+
execute: async (args, executionContext) => {
|
|
29
|
+
executionContext?.signal?.throwIfAborted();
|
|
29
30
|
const { runFirecrawlSearch } = await loadFirecrawlClientModule$1();
|
|
30
31
|
return await runFirecrawlSearch({
|
|
31
32
|
cfg: ctx.config,
|
|
@@ -33,7 +34,8 @@ function createFirecrawlWebSearchProvider() {
|
|
|
33
34
|
count: readPositiveIntegerParam(args, "count", {
|
|
34
35
|
message: "count must be an integer from 1 to 10",
|
|
35
36
|
max: 10
|
|
36
|
-
})
|
|
37
|
+
}),
|
|
38
|
+
...executionContext?.signal ? { signal: executionContext.signal } : {}
|
|
37
39
|
});
|
|
38
40
|
}
|
|
39
41
|
})
|
|
@@ -43,7 +45,7 @@ function createFirecrawlWebSearchProvider() {
|
|
|
43
45
|
//#region extensions/firecrawl/src/firecrawl-free-search-provider.ts
|
|
44
46
|
let firecrawlClientModulePromise;
|
|
45
47
|
function loadFirecrawlClientModule() {
|
|
46
|
-
firecrawlClientModulePromise ??= import("./firecrawl-client-
|
|
48
|
+
firecrawlClientModulePromise ??= import("./firecrawl-client-Aw46OXVC.js").then((n) => n.t);
|
|
47
49
|
return firecrawlClientModulePromise;
|
|
48
50
|
}
|
|
49
51
|
function createFirecrawlFreeWebSearchProvider() {
|
|
@@ -52,7 +54,8 @@ function createFirecrawlFreeWebSearchProvider() {
|
|
|
52
54
|
createTool: (ctx) => ({
|
|
53
55
|
description: "Search the web using Firecrawl's free hosted starter tier (no API key required). Returns structured results with snippets. Use firecrawl_search for Firecrawl-specific knobs like sources or categories.",
|
|
54
56
|
parameters: GenericFirecrawlSearchSchema,
|
|
55
|
-
execute: async (args) => {
|
|
57
|
+
execute: async (args, executionContext) => {
|
|
58
|
+
executionContext?.signal?.throwIfAborted();
|
|
56
59
|
const { runFirecrawlSearch } = await loadFirecrawlClientModule();
|
|
57
60
|
return await runFirecrawlSearch({
|
|
58
61
|
cfg: ctx.config,
|
|
@@ -61,7 +64,8 @@ function createFirecrawlFreeWebSearchProvider() {
|
|
|
61
64
|
message: "count must be an integer from 1 to 10",
|
|
62
65
|
max: 10
|
|
63
66
|
}),
|
|
64
|
-
access: "keyless"
|
|
67
|
+
access: "keyless",
|
|
68
|
+
...executionContext?.signal ? { signal: executionContext.signal } : {}
|
|
65
69
|
});
|
|
66
70
|
}
|
|
67
71
|
})
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as runFirecrawlScrape, r as runFirecrawlSearch } from "./firecrawl-client-
|
|
2
|
-
import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-
|
|
3
|
-
import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-
|
|
1
|
+
import { n as runFirecrawlScrape, r as runFirecrawlSearch } from "./firecrawl-client-Aw46OXVC.js";
|
|
2
|
+
import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-CYViV-li.js";
|
|
3
|
+
import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-nqgr2mhw.js";
|
|
4
4
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
5
5
|
import { optionalStringEnum } from "openclaw/plugin-sdk/channel-actions";
|
|
6
6
|
import { jsonResult, readNonNegativeIntegerParam, readPositiveIntegerParam, readStringArrayParam, readStringParam } from "openclaw/plugin-sdk/provider-web-search";
|
|
@@ -33,9 +33,11 @@ function createFirecrawlScrapeTool(api) {
|
|
|
33
33
|
return {
|
|
34
34
|
name: "firecrawl_scrape",
|
|
35
35
|
label: "Firecrawl Scrape",
|
|
36
|
+
resultContentSource: "network",
|
|
36
37
|
description: "Scrape a page using Firecrawl v2/scrape. Useful for JS-heavy or bot-protected pages where plain web_fetch is weak.",
|
|
37
38
|
parameters: FirecrawlScrapeToolSchema,
|
|
38
|
-
execute: async (_toolCallId, rawParams) => {
|
|
39
|
+
execute: async (_toolCallId, rawParams, signal) => {
|
|
40
|
+
signal?.throwIfAborted();
|
|
39
41
|
const url = readStringParam(rawParams, "url", { required: true });
|
|
40
42
|
const extractMode = readStringParam(rawParams, "extractMode") === "text" ? "text" : "markdown";
|
|
41
43
|
const maxChars = readPositiveIntegerParam(rawParams, "maxChars");
|
|
@@ -54,7 +56,8 @@ function createFirecrawlScrapeTool(api) {
|
|
|
54
56
|
maxAgeMs,
|
|
55
57
|
proxy,
|
|
56
58
|
storeInCache,
|
|
57
|
-
timeoutSeconds
|
|
59
|
+
timeoutSeconds,
|
|
60
|
+
...signal ? { signal } : {}
|
|
58
61
|
}));
|
|
59
62
|
}
|
|
60
63
|
};
|
|
@@ -85,9 +88,11 @@ function createFirecrawlSearchTool(api) {
|
|
|
85
88
|
return {
|
|
86
89
|
name: "firecrawl_search",
|
|
87
90
|
label: "Firecrawl Search",
|
|
91
|
+
resultContentSource: "network",
|
|
88
92
|
description: "Search the web using Firecrawl v2/search. Supports includeDomains/excludeDomains filtering and tbs time filters (day/week/month/year). Can optionally include scraped content from result pages.",
|
|
89
93
|
parameters: FirecrawlSearchToolSchema,
|
|
90
|
-
execute: async (_toolCallId, rawParams) => {
|
|
94
|
+
execute: async (_toolCallId, rawParams, signal) => {
|
|
95
|
+
signal?.throwIfAborted();
|
|
91
96
|
const query = readStringParam(rawParams, "query", { required: true });
|
|
92
97
|
const count = readPositiveIntegerParam(rawParams, "count", {
|
|
93
98
|
max: 100,
|
|
@@ -114,7 +119,8 @@ function createFirecrawlSearchTool(api) {
|
|
|
114
119
|
tbs,
|
|
115
120
|
location,
|
|
116
121
|
country,
|
|
117
|
-
scrapeResults
|
|
122
|
+
scrapeResults,
|
|
123
|
+
...signal ? { signal } : {}
|
|
118
124
|
}));
|
|
119
125
|
}
|
|
120
126
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-
|
|
1
|
+
import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-CYViV-li.js";
|
|
2
2
|
export { createFirecrawlWebFetchProvider };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-
|
|
1
|
+
import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-nqgr2mhw.js";
|
|
2
2
|
export { createFirecrawlFreeWebSearchProvider, createFirecrawlWebSearchProvider };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/firecrawl-plugin",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.8.1-beta.2",
|
|
4
4
|
"description": "OpenClaw Firecrawl plugin.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"minHostVersion": ">=2026.6.8"
|
|
22
22
|
},
|
|
23
23
|
"compat": {
|
|
24
|
-
"pluginApi": ">=2026.
|
|
24
|
+
"pluginApi": ">=2026.8.1-beta.2"
|
|
25
25
|
},
|
|
26
26
|
"build": {
|
|
27
|
-
"openclawVersion": "2026.
|
|
27
|
+
"openclawVersion": "2026.8.1-beta.2",
|
|
28
28
|
"bundledDist": false
|
|
29
29
|
},
|
|
30
30
|
"release": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"README.md"
|
|
42
42
|
],
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"openclaw": ">=2026.
|
|
44
|
+
"openclaw": ">=2026.8.1-beta.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"openclaw": {
|