@openclaw/firecrawl-plugin 2026.9.1-beta.1 → 2026.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1,18 +1,19 @@
1
- import { n as runFirecrawlScrape } from "./firecrawl-client-DQx3FAys.js";
1
+ import { n as runFirecrawlScrape } from "./firecrawl-client-BPFpIblh.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) {
5
+ const cfg = { plugins: { entries: { firecrawl: {
6
+ enabled: true,
7
+ config: { webFetch: {
8
+ apiKey: params.apiKey,
9
+ baseUrl: params.baseUrl,
10
+ onlyMainContent: params.onlyMainContent,
11
+ maxAgeMs: params.maxAgeMs,
12
+ timeoutSeconds: params.timeoutSeconds
13
+ } }
14
+ } } } };
5
15
  const result = await runFirecrawlScrape({
6
- cfg: { plugins: { entries: { firecrawl: {
7
- enabled: true,
8
- config: { webFetch: {
9
- apiKey: params.apiKey,
10
- baseUrl: params.baseUrl,
11
- onlyMainContent: params.onlyMainContent,
12
- maxAgeMs: params.maxAgeMs,
13
- timeoutSeconds: params.timeoutSeconds
14
- } }
15
- } } } },
16
+ cfg,
16
17
  url: params.url,
17
18
  extractMode: params.extractMode,
18
19
  maxChars: params.maxChars,
@@ -77,7 +77,8 @@ function resolveFirecrawlMaxAgeMs(cfg, override) {
77
77
  return DEFAULT_FIRECRAWL_MAX_AGE_MS;
78
78
  }
79
79
  function resolveFirecrawlScrapeTimeoutSeconds(cfg, override) {
80
- return resolvePositiveTimeoutSeconds(override, resolvePositiveTimeoutSeconds(resolveFirecrawlFetchConfig(cfg)?.timeoutSeconds, DEFAULT_FIRECRAWL_SCRAPE_TIMEOUT_SECONDS));
80
+ const fetch = resolveFirecrawlFetchConfig(cfg);
81
+ return resolvePositiveTimeoutSeconds(override, resolvePositiveTimeoutSeconds(fetch?.timeoutSeconds, DEFAULT_FIRECRAWL_SCRAPE_TIMEOUT_SECONDS));
81
82
  }
82
83
  function resolveFirecrawlSearchTimeoutSeconds(override) {
83
84
  return resolvePositiveTimeoutSeconds(override, DEFAULT_FIRECRAWL_SEARCH_TIMEOUT_SECONDS);
@@ -98,7 +99,7 @@ const FIRECRAWL_SEARCH_MAX_CONTENT_CHARS = 2e4;
98
99
  const DEFAULT_SCRAPE_MAX_CHARS = 5e4;
99
100
  const FIRECRAWL_SCRAPE_METADATA_MAX_CHARS = 4e3;
100
101
  const FIRECRAWL_RESULT_URL_MAX_CHARS = 2048;
101
- const FIRECRAWL_SCRAPE_RESPONSE_MAX_BYTES = 64 * 1024 * 1024;
102
+ const FIRECRAWL_SCRAPE_RESPONSE_MAX_BYTES = 67108864;
102
103
  const ALLOWED_FIRECRAWL_HOSTS = /* @__PURE__ */ new Set(["api.firecrawl.dev"]);
103
104
  const FIRECRAWL_PUBLISHED_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:[T ][\d:.+Z-]{0,20})?$/u;
104
105
  const FIRECRAWL_SELF_HOSTED_PRIVATE_ERROR = "Firecrawl custom baseUrl must target a private or internal self-hosted endpoint.";
@@ -337,7 +338,8 @@ async function runFirecrawlSearch(params) {
337
338
  country,
338
339
  scrapeResults
339
340
  }));
340
- const cached = readCache(SEARCH_CACHE, cacheKey);
341
+ const cacheTtlMs = resolveCacheTtlMs(params.cfg?.tools?.web?.search?.cacheTtlMinutes, DEFAULT_CACHE_TTL_MINUTES);
342
+ const cached = readCache(SEARCH_CACHE, cacheKey, cacheTtlMs);
341
343
  if (cached) return {
342
344
  ...cached.value,
343
345
  cached: true
@@ -367,7 +369,8 @@ async function runFirecrawlSearch(params) {
367
369
  }, async (response) => {
368
370
  const payloadValue = await readProviderJsonObjectResponse(response, "Firecrawl Search API error");
369
371
  if (payloadValue.success === false) {
370
- const safeError = wrapWebContent(truncateSanitizedExternalContent(typeof payloadValue.error === "string" ? payloadValue.error : typeof payloadValue.message === "string" ? payloadValue.message : "unknown error", 1e3).text, "web_search");
372
+ const error = typeof payloadValue.error === "string" ? payloadValue.error : typeof payloadValue.message === "string" ? payloadValue.message : "unknown error";
373
+ const safeError = wrapWebContent(truncateSanitizedExternalContent(error, 1e3).text, "web_search");
371
374
  throw new Error(`Firecrawl Search API error: ${safeError}`);
372
375
  }
373
376
  return payloadValue;
@@ -379,7 +382,7 @@ async function runFirecrawlSearch(params) {
379
382
  tookMs: Date.now() - start,
380
383
  scrapeResults
381
384
  });
382
- writeCache(SEARCH_CACHE, cacheKey, result, resolveCacheTtlMs(void 0, DEFAULT_CACHE_TTL_MINUTES));
385
+ writeCache(SEARCH_CACHE, cacheKey, result, cacheTtlMs);
383
386
  return result;
384
387
  }
385
388
  function resolveScrapeData(payload) {
@@ -51,7 +51,7 @@ const FIRECRAWL_WEB_FETCH_PROVIDER_SHARED = {
51
51
  };
52
52
  //#endregion
53
53
  //#region extensions/firecrawl/src/firecrawl-fetch-provider.ts
54
- const loadFirecrawlClientModule = createLazyRuntimeModule(() => import("./firecrawl-client-DQx3FAys.js").then((n) => n.t));
54
+ const loadFirecrawlClientModule = createLazyRuntimeModule(() => import("./firecrawl-client-BPFpIblh.js").then((n) => n.t));
55
55
  function createFirecrawlWebFetchProvider() {
56
56
  return {
57
57
  ...FIRECRAWL_WEB_FETCH_PROVIDER_SHARED,
@@ -59,7 +59,8 @@ function createFirecrawlWebFetchProvider() {
59
59
  createTool: ({ config }) => ({
60
60
  description: "Fetch a page using Firecrawl.",
61
61
  parameters: {},
62
- execute: async (args) => {
62
+ execute: async (args, executionContext) => {
63
+ executionContext?.signal?.throwIfAborted();
63
64
  const url = typeof args.url === "string" ? args.url : "";
64
65
  const extractMode = args.extractMode === "text" ? "text" : "markdown";
65
66
  const maxChars = readPositiveIntegerParam(args, "maxChars");
@@ -72,6 +73,7 @@ function createFirecrawlWebFetchProvider() {
72
73
  extractMode,
73
74
  access: "keyless",
74
75
  maxChars,
76
+ ...executionContext?.signal ? { signal: executionContext.signal } : {},
75
77
  ...proxy ? { proxy } : {},
76
78
  ...storeInCache !== void 0 ? { storeInCache } : {}
77
79
  });
@@ -0,0 +1,108 @@
1
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
+ import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
3
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createWebSearchProviderContractFields, enablePluginInConfig } from "openclaw/plugin-sdk/provider-web-search-contract";
5
+ //#region extensions/firecrawl/src/firecrawl-search-provider.ts
6
+ const FIRECRAWL_CREDENTIAL_PATH = "plugins.entries.firecrawl.config.webSearch.apiKey";
7
+ const loadFirecrawlClientModule = createLazyRuntimeModule(() => import("./firecrawl-client-BPFpIblh.js").then((n) => n.t));
8
+ const GenericFirecrawlSearchSchema = {
9
+ type: "object",
10
+ properties: {
11
+ query: {
12
+ type: "string",
13
+ description: "Search query string."
14
+ },
15
+ count: {
16
+ type: "integer",
17
+ description: "Number of results to return (1-10).",
18
+ minimum: 1,
19
+ maximum: 10
20
+ }
21
+ },
22
+ additionalProperties: false
23
+ };
24
+ function getConfiguredFirecrawlFetchCredentialFallback(config) {
25
+ const pluginConfig = asOptionalRecord(config?.plugins?.entries?.firecrawl?.config);
26
+ const value = asOptionalRecord(pluginConfig?.webFetch)?.apiKey;
27
+ return value === void 0 ? void 0 : {
28
+ path: "plugins.entries.firecrawl.config.webFetch.apiKey",
29
+ value
30
+ };
31
+ }
32
+ function createFirecrawlSearchProvider(keyless) {
33
+ const id = keyless ? "firecrawl-free" : "firecrawl";
34
+ const credentialPath = keyless ? "" : FIRECRAWL_CREDENTIAL_PATH;
35
+ return {
36
+ id,
37
+ label: keyless ? "Firecrawl Search (Free)" : "Firecrawl Search",
38
+ hint: keyless ? "Free web search via Firecrawl's hosted starter tier — no API key required" : "Structured results with optional result scraping",
39
+ onboardingScopes: ["text-inference"],
40
+ ...keyless ? {
41
+ requiresCredential: false,
42
+ envVars: [],
43
+ placeholder: "(no key needed)"
44
+ } : {
45
+ credentialLabel: "Firecrawl API key",
46
+ envVars: ["FIRECRAWL_API_KEY"],
47
+ placeholder: "fc-..."
48
+ },
49
+ signupUrl: "https://www.firecrawl.dev/",
50
+ docsUrl: "https://docs.openclaw.ai/tools/firecrawl",
51
+ ...keyless ? {} : { autoDetectOrder: 60 },
52
+ credentialPath,
53
+ ...createWebSearchProviderContractFields({
54
+ credentialPath,
55
+ searchCredential: {
56
+ type: "scoped",
57
+ scopeId: id
58
+ },
59
+ ...keyless ? { selectionPluginId: "firecrawl" } : { configuredCredential: { pluginId: "firecrawl" } }
60
+ }),
61
+ ...keyless ? {} : {
62
+ applySelectionConfig: (config) => {
63
+ const enabled = enablePluginInConfig(config, "firecrawl");
64
+ if (!enabled.enabled || enabled.config.tools?.web?.fetch?.provider) return enabled.config;
65
+ return {
66
+ ...enabled.config,
67
+ tools: {
68
+ ...enabled.config.tools,
69
+ web: {
70
+ ...enabled.config.tools?.web,
71
+ fetch: {
72
+ ...enabled.config.tools?.web?.fetch,
73
+ provider: "firecrawl"
74
+ }
75
+ }
76
+ }
77
+ };
78
+ },
79
+ getConfiguredCredentialFallback: getConfiguredFirecrawlFetchCredentialFallback
80
+ },
81
+ createTool: (ctx) => ({
82
+ description: keyless ? "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." : "Search the web using Firecrawl. Returns structured results with snippets from Firecrawl Search. Use firecrawl_search for Firecrawl-specific knobs like sources or categories.",
83
+ parameters: GenericFirecrawlSearchSchema,
84
+ execute: async (args, executionContext) => {
85
+ executionContext?.signal?.throwIfAborted();
86
+ const { runFirecrawlSearch } = await loadFirecrawlClientModule();
87
+ return await runFirecrawlSearch({
88
+ cfg: ctx.config,
89
+ query: typeof args.query === "string" ? args.query : "",
90
+ count: readPositiveIntegerParam(args, "count", {
91
+ message: "count must be an integer from 1 to 10",
92
+ max: 10
93
+ }),
94
+ ...keyless ? { access: "keyless" } : {},
95
+ ...executionContext?.signal ? { signal: executionContext.signal } : {}
96
+ });
97
+ }
98
+ })
99
+ };
100
+ }
101
+ function createFirecrawlWebSearchProvider() {
102
+ return createFirecrawlSearchProvider(false);
103
+ }
104
+ function createFirecrawlFreeWebSearchProvider() {
105
+ return createFirecrawlSearchProvider(true);
106
+ }
107
+ //#endregion
108
+ export { createFirecrawlWebSearchProvider as n, createFirecrawlFreeWebSearchProvider as t };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { n as runFirecrawlScrape, r as runFirecrawlSearch } from "./firecrawl-client-DQx3FAys.js";
2
- import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-C8gB71c0.js";
3
- import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-5eCE16v7.js";
1
+ import { n as runFirecrawlScrape, r as runFirecrawlSearch } from "./firecrawl-client-BPFpIblh.js";
2
+ import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-CIpxLKLq.js";
3
+ import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-search-provider-80szkO8A.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";
@@ -1,3 +1,3 @@
1
- import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-C8gB71c0.js";
1
+ import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-CIpxLKLq.js";
2
2
  import "./web-fetch-provider.js";
3
3
  export { createFirecrawlWebFetchProvider };
@@ -1,2 +1,2 @@
1
- import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-C8gB71c0.js";
1
+ import { t as createFirecrawlWebFetchProvider } from "./firecrawl-fetch-provider-CIpxLKLq.js";
2
2
  export { createFirecrawlWebFetchProvider };
@@ -1,3 +1,3 @@
1
- import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-5eCE16v7.js";
1
+ import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-search-provider-80szkO8A.js";
2
2
  import "./web-search-provider.js";
3
3
  export { createFirecrawlFreeWebSearchProvider, createFirecrawlWebSearchProvider };
@@ -1,2 +1,2 @@
1
- import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-free-search-provider-5eCE16v7.js";
1
+ import { n as createFirecrawlWebSearchProvider, t as createFirecrawlFreeWebSearchProvider } from "./firecrawl-search-provider-80szkO8A.js";
2
2
  export { createFirecrawlFreeWebSearchProvider, createFirecrawlWebSearchProvider };
@@ -1,4 +1,4 @@
1
- const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\.)*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
1
+ const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\[\x20-\x7e])*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
2
2
  /**
3
3
  * Returns true if the value is an Email
4
4
  * @specification https://datatracker.ietf.org/doc/html/rfc5322
@@ -1,6 +1,9 @@
1
1
  import * as FormatBidi from './format/bidi.mjs';
2
2
  import * as LabelUnicode from './label/unicode.mjs';
3
3
  import * as LabelPuny from './label/puny.mjs';
4
+ // ------------------------------------------------------------------
5
+ // IsLabel
6
+ // ------------------------------------------------------------------
4
7
  function IsValidLabelLength(value) {
5
8
  return value.length > 0 && value.length <= 63;
6
9
  }
@@ -8,9 +11,24 @@ function IsLabel(value) {
8
11
  return IsValidLabelLength(value) && (LabelPuny.IsPunyLabel(value) ||
9
12
  LabelUnicode.IsUnicodeLabel(value));
10
13
  }
14
+ // ------------------------------------------------------------------
15
+ // NormalizeHostname
16
+ //
17
+ // Normalizes a hostname for label validation. Normalizes for NFC
18
+ // such that equivalent codepoint sequences can be uniformly
19
+ // compared. It also removes codepoints that IDNA mapping ignores,
20
+ // and converts full stop variants to ASCII '.' so the hostname can
21
+ // be split into labels.
22
+ // ------------------------------------------------------------------
11
23
  function NormalizeHostname(value) {
12
- return value.normalize('NFC').replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.');
24
+ return value
25
+ .normalize('NFC')
26
+ .replace(/[\u00ad\u034f\u180b-\u180d\u200b\ufe00-\ufe0f\u{e0100}-\u{e01ef}]/gu, '') // RE_IGNORED_MAPPING
27
+ .replace(/[\u002E\u3002\uFF0E\uFF61]/g, '.'); // RE_FULL_STOP_MAPPING
13
28
  }
29
+ // ------------------------------------------------------------------
30
+ // IsIdnHostname
31
+ // ------------------------------------------------------------------
14
32
  export function IsIdnHostname(value) {
15
33
  if (value.length === 0 || value.includes(' '))
16
34
  return false;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.3.16",
4
+ "version": "1.3.17",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/firecrawl-plugin",
3
- "version": "2026.9.1-beta.1",
3
+ "version": "2026.9.1",
4
4
  "description": "OpenClaw Firecrawl plugin.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "typebox": "1.3.16",
11
+ "typebox": "1.3.17",
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "openclaw": {
@@ -22,10 +22,10 @@
22
22
  "minHostVersion": ">=2026.6.8"
23
23
  },
24
24
  "compat": {
25
- "pluginApi": ">=2026.9.1-beta.1"
25
+ "pluginApi": ">=2026.9.1"
26
26
  },
27
27
  "build": {
28
- "openclawVersion": "2026.9.1-beta.1",
28
+ "openclawVersion": "2026.9.1",
29
29
  "bundledDist": false
30
30
  },
31
31
  "release": {
@@ -42,7 +42,7 @@
42
42
  "README.md"
43
43
  ],
44
44
  "peerDependencies": {
45
- "openclaw": ">=2026.9.1-beta.1"
45
+ "openclaw": ">=2026.9.1"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "openclaw": {
@@ -1,71 +0,0 @@
1
- import { buildFirecrawlFreeWebSearchProviderBase, buildFirecrawlWebSearchProviderBase } from "./web-search-shared.js";
2
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
3
- import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
4
- //#region extensions/firecrawl/src/firecrawl-search-provider.ts
5
- const loadFirecrawlClientModule$1 = createLazyRuntimeModule(() => import("./firecrawl-client-DQx3FAys.js").then((n) => n.t));
6
- const GenericFirecrawlSearchSchema = {
7
- type: "object",
8
- properties: {
9
- query: {
10
- type: "string",
11
- description: "Search query string."
12
- },
13
- count: {
14
- type: "integer",
15
- description: "Number of results to return (1-10).",
16
- minimum: 1,
17
- maximum: 10
18
- }
19
- },
20
- additionalProperties: false
21
- };
22
- function createFirecrawlWebSearchProvider() {
23
- return {
24
- ...buildFirecrawlWebSearchProviderBase(),
25
- createTool: (ctx) => ({
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
- parameters: GenericFirecrawlSearchSchema,
28
- execute: async (args, executionContext) => {
29
- executionContext?.signal?.throwIfAborted();
30
- const { runFirecrawlSearch } = await loadFirecrawlClientModule$1();
31
- return await runFirecrawlSearch({
32
- cfg: ctx.config,
33
- query: typeof args.query === "string" ? args.query : "",
34
- count: readPositiveIntegerParam(args, "count", {
35
- message: "count must be an integer from 1 to 10",
36
- max: 10
37
- }),
38
- ...executionContext?.signal ? { signal: executionContext.signal } : {}
39
- });
40
- }
41
- })
42
- };
43
- }
44
- //#endregion
45
- //#region extensions/firecrawl/src/firecrawl-free-search-provider.ts
46
- const loadFirecrawlClientModule = createLazyRuntimeModule(() => import("./firecrawl-client-DQx3FAys.js").then((n) => n.t));
47
- function createFirecrawlFreeWebSearchProvider() {
48
- return {
49
- ...buildFirecrawlFreeWebSearchProviderBase(),
50
- createTool: (ctx) => ({
51
- 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.",
52
- parameters: GenericFirecrawlSearchSchema,
53
- execute: async (args, executionContext) => {
54
- executionContext?.signal?.throwIfAborted();
55
- const { runFirecrawlSearch } = await loadFirecrawlClientModule();
56
- return await runFirecrawlSearch({
57
- cfg: ctx.config,
58
- query: typeof args.query === "string" ? args.query : "",
59
- count: readPositiveIntegerParam(args, "count", {
60
- message: "count must be an integer from 1 to 10",
61
- max: 10
62
- }),
63
- access: "keyless",
64
- ...executionContext?.signal ? { signal: executionContext.signal } : {}
65
- });
66
- }
67
- })
68
- };
69
- }
70
- //#endregion
71
- export { createFirecrawlWebSearchProvider as n, createFirecrawlFreeWebSearchProvider as t };
@@ -1,77 +0,0 @@
1
- import { createWebSearchProviderContractFields, enablePluginInConfig } from "openclaw/plugin-sdk/provider-web-search-contract";
2
- //#region extensions/firecrawl/web-search-shared.ts
3
- const FIRECRAWL_CREDENTIAL_PATH = "plugins.entries.firecrawl.config.webSearch.apiKey";
4
- const FIRECRAWL_FETCH_CREDENTIAL_PATH = "plugins.entries.firecrawl.config.webFetch.apiKey";
5
- function getConfiguredFirecrawlFetchCredentialFallback(config) {
6
- const apiKey = (config?.plugins?.entries?.firecrawl?.config)?.webFetch?.apiKey;
7
- return apiKey === void 0 ? void 0 : {
8
- path: FIRECRAWL_FETCH_CREDENTIAL_PATH,
9
- value: apiKey
10
- };
11
- }
12
- function buildFirecrawlWebSearchProviderBase() {
13
- const contractFields = createWebSearchProviderContractFields({
14
- credentialPath: FIRECRAWL_CREDENTIAL_PATH,
15
- searchCredential: {
16
- type: "scoped",
17
- scopeId: "firecrawl"
18
- },
19
- configuredCredential: { pluginId: "firecrawl" }
20
- });
21
- return {
22
- id: "firecrawl",
23
- label: "Firecrawl Search",
24
- hint: "Structured results with optional result scraping",
25
- onboardingScopes: ["text-inference"],
26
- credentialLabel: "Firecrawl API key",
27
- envVars: ["FIRECRAWL_API_KEY"],
28
- placeholder: "fc-...",
29
- signupUrl: "https://www.firecrawl.dev/",
30
- docsUrl: "https://docs.openclaw.ai/tools/firecrawl",
31
- autoDetectOrder: 60,
32
- credentialPath: FIRECRAWL_CREDENTIAL_PATH,
33
- ...contractFields,
34
- applySelectionConfig: (config) => {
35
- const enabled = enablePluginInConfig(config, "firecrawl");
36
- if (!enabled.enabled || enabled.config.tools?.web?.fetch?.provider) return enabled.config;
37
- return {
38
- ...enabled.config,
39
- tools: {
40
- ...enabled.config.tools,
41
- web: {
42
- ...enabled.config.tools?.web,
43
- fetch: {
44
- ...enabled.config.tools?.web?.fetch,
45
- provider: "firecrawl"
46
- }
47
- }
48
- }
49
- };
50
- },
51
- getConfiguredCredentialFallback: getConfiguredFirecrawlFetchCredentialFallback
52
- };
53
- }
54
- function buildFirecrawlFreeWebSearchProviderBase() {
55
- return {
56
- id: "firecrawl-free",
57
- label: "Firecrawl Search (Free)",
58
- hint: "Free web search via Firecrawl's hosted starter tier — no API key required",
59
- onboardingScopes: ["text-inference"],
60
- requiresCredential: false,
61
- envVars: [],
62
- placeholder: "(no key needed)",
63
- signupUrl: "https://www.firecrawl.dev/",
64
- docsUrl: "https://docs.openclaw.ai/tools/firecrawl",
65
- credentialPath: "",
66
- ...createWebSearchProviderContractFields({
67
- credentialPath: "",
68
- searchCredential: {
69
- type: "scoped",
70
- scopeId: "firecrawl-free"
71
- },
72
- selectionPluginId: "firecrawl"
73
- })
74
- };
75
- }
76
- //#endregion
77
- export { buildFirecrawlFreeWebSearchProviderBase, buildFirecrawlWebSearchProviderBase };