refactor: dedupe firecrawl and directive helpers

This commit is contained in:
Peter Steinberger
2026-04-08 14:37:16 +01:00
parent 34f73abfd3
commit 82a958dc79
4 changed files with 100 additions and 198 deletions

View File

@@ -0,0 +1,60 @@
import type { WebFetchProviderPlugin } from "openclaw/plugin-sdk/provider-web-fetch-contract";
type FirecrawlWebFetchProviderSharedFields = Omit<
WebFetchProviderPlugin,
"applySelectionConfig" | "createTool"
>;
function ensureRecord(target: Record<string, unknown>, key: string): Record<string, unknown> {
const current = target[key];
if (current && typeof current === "object" && !Array.isArray(current)) {
return current as Record<string, unknown>;
}
const next: Record<string, unknown> = {};
target[key] = next;
return next;
}
export const FIRECRAWL_WEB_FETCH_PROVIDER_SHARED = {
id: "firecrawl",
label: "Firecrawl",
hint: "Fetch pages with Firecrawl for JS-heavy or bot-protected sites.",
envVars: ["FIRECRAWL_API_KEY"],
placeholder: "fc-...",
signupUrl: "https://www.firecrawl.dev/",
docsUrl: "https://docs.firecrawl.dev",
autoDetectOrder: 50,
credentialPath: "plugins.entries.firecrawl.config.webFetch.apiKey",
inactiveSecretPaths: [
"plugins.entries.firecrawl.config.webFetch.apiKey",
"tools.web.fetch.firecrawl.apiKey",
],
getCredentialValue: (fetchConfig) => {
if (!fetchConfig || typeof fetchConfig !== "object") {
return undefined;
}
const legacy = fetchConfig.firecrawl;
if (!legacy || typeof legacy !== "object" || Array.isArray(legacy)) {
return undefined;
}
if ((legacy as { enabled?: boolean }).enabled === false) {
return undefined;
}
return (legacy as { apiKey?: unknown }).apiKey;
},
setCredentialValue: (fetchConfigTarget, value) => {
const firecrawl = ensureRecord(fetchConfigTarget, "firecrawl");
firecrawl.apiKey = value;
},
getConfiguredCredentialValue: (config) =>
(config?.plugins?.entries?.firecrawl?.config as { webFetch?: { apiKey?: unknown } } | undefined)
?.webFetch?.apiKey,
setConfiguredCredentialValue: (configTarget, value) => {
const plugins = ensureRecord(configTarget as unknown as Record<string, unknown>, "plugins");
const entries = ensureRecord(plugins, "entries");
const firecrawlEntry = ensureRecord(entries, "firecrawl");
const pluginConfig = ensureRecord(firecrawlEntry, "config");
const webFetch = ensureRecord(pluginConfig, "webFetch");
webFetch.apiKey = value;
},
} satisfies FirecrawlWebFetchProviderSharedFields;

View File

@@ -1,68 +1,11 @@
import type { WebFetchProviderPlugin } from "openclaw/plugin-sdk/provider-web-fetch";
import { enablePluginInConfig } from "openclaw/plugin-sdk/provider-web-fetch";
import { runFirecrawlScrape } from "./firecrawl-client.js";
import { FIRECRAWL_WEB_FETCH_PROVIDER_SHARED } from "./firecrawl-fetch-provider-shared.js";
export function createFirecrawlWebFetchProvider(): WebFetchProviderPlugin {
return {
id: "firecrawl",
label: "Firecrawl",
hint: "Fetch pages with Firecrawl for JS-heavy or bot-protected sites.",
envVars: ["FIRECRAWL_API_KEY"],
placeholder: "fc-...",
signupUrl: "https://www.firecrawl.dev/",
docsUrl: "https://docs.firecrawl.dev",
autoDetectOrder: 50,
credentialPath: "plugins.entries.firecrawl.config.webFetch.apiKey",
inactiveSecretPaths: [
"plugins.entries.firecrawl.config.webFetch.apiKey",
"tools.web.fetch.firecrawl.apiKey",
],
getCredentialValue: (fetchConfig) => {
if (!fetchConfig || typeof fetchConfig !== "object") {
return undefined;
}
const legacy = fetchConfig.firecrawl;
if (!legacy || typeof legacy !== "object" || Array.isArray(legacy)) {
return undefined;
}
if ((legacy as { enabled?: boolean }).enabled === false) {
return undefined;
}
return (legacy as { apiKey?: unknown }).apiKey;
},
setCredentialValue: (fetchConfigTarget, value) => {
const existing = fetchConfigTarget.firecrawl;
const firecrawl =
existing && typeof existing === "object" && !Array.isArray(existing)
? (existing as Record<string, unknown>)
: {};
firecrawl.apiKey = value;
fetchConfigTarget.firecrawl = firecrawl;
},
getConfiguredCredentialValue: (config) =>
(
config?.plugins?.entries?.firecrawl?.config as
| { webFetch?: { apiKey?: unknown } }
| undefined
)?.webFetch?.apiKey,
setConfiguredCredentialValue: (configTarget, value) => {
const plugins = (configTarget.plugins ??= {});
const entries = (plugins.entries ??= {});
const firecrawlEntry = (entries.firecrawl ??= {});
const pluginConfig =
firecrawlEntry.config &&
typeof firecrawlEntry.config === "object" &&
!Array.isArray(firecrawlEntry.config)
? firecrawlEntry.config
: ((firecrawlEntry.config = {}), firecrawlEntry.config);
const webFetch =
pluginConfig.webFetch &&
typeof pluginConfig.webFetch === "object" &&
!Array.isArray(pluginConfig.webFetch)
? (pluginConfig.webFetch as Record<string, unknown>)
: ((pluginConfig.webFetch = {}), pluginConfig.webFetch as Record<string, unknown>);
webFetch.apiKey = value;
},
...FIRECRAWL_WEB_FETCH_PROVIDER_SHARED,
applySelectionConfig: (config) => enablePluginInConfig(config, "firecrawl").config,
createTool: ({ config }) => ({
description: "Fetch a page using Firecrawl.",