



























@@ -1,10 +1,72 @@
1-import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
1+import {
2+loadPluginManifestRegistry,
3+type PluginManifestRecord,
4+} from "../plugins/manifest-registry.js";
25import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
36import type { SecretTargetRegistryEntry } from "./target-registry-types.js";
4758const SECRET_INPUT_SHAPE = "secret_input"; // pragma: allowlist secret
69const SIBLING_REF_SHAPE = "sibling_ref"; // pragma: allowlist secret
71011+const WEB_PROVIDER_SECRET_CONFIGS = [
12+{ contract: "webSearchProviders", configPath: "webSearch.apiKey" },
13+{ contract: "webFetchProviders", configPath: "webFetch.apiKey" },
14+] as const;
15+16+type WebProviderSecretConfig = (typeof WEB_PROVIDER_SECRET_CONFIGS)[number];
17+18+function createPluginOpenClawConfigSecretTargetEntry(
19+pluginId: string,
20+configPath: string,
21+): SecretTargetRegistryEntry {
22+const pathPattern = ["plugins", "entries", pluginId, "config", ...configPath.split(".")].join(
23+".",
24+);
25+return {
26+id: pathPattern,
27+targetType: pathPattern,
28+configFile: "openclaw.json",
29+ pathPattern,
30+secretShape: SECRET_INPUT_SHAPE,
31+expectedResolvedValue: "string",
32+includeInPlan: true,
33+includeInConfigure: true,
34+includeInAudit: true,
35+};
36+}
37+38+function hasSensitiveConfigHint(
39+plugin: PluginManifestRecord,
40+configPath: WebProviderSecretConfig["configPath"],
41+): boolean {
42+return plugin.configUiHints?.[configPath]?.sensitive === true;
43+}
44+45+function hasWebProviderContract(
46+plugin: PluginManifestRecord,
47+contract: WebProviderSecretConfig["contract"],
48+): boolean {
49+return (plugin.contracts?.[contract]?.length ?? 0) > 0;
50+}
51+52+function listBundledWebProviderSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
53+const entries: SecretTargetRegistryEntry[] = [];
54+for (const record of loadPluginManifestRegistry({}).plugins) {
55+if (record.origin !== "bundled") {
56+continue;
57+}
58+for (const config of WEB_PROVIDER_SECRET_CONFIGS) {
59+if (
60+hasWebProviderContract(record, config.contract) &&
61+hasSensitiveConfigHint(record, config.configPath)
62+) {
63+entries.push(createPluginOpenClawConfigSecretTargetEntry(record.id, config.configPath));
64+}
65+}
66+}
67+return entries.toSorted((left, right) => left.id.localeCompare(right.id));
68+}
69+870function listChannelSecretTargetRegistryEntries(): SecretTargetRegistryEntry[] {
971const entries: SecretTargetRegistryEntry[] = [];
1072@@ -347,116 +409,6 @@ const CORE_SECRET_TARGET_REGISTRY: SecretTargetRegistryEntry[] = [
347409includeInConfigure: true,
348410includeInAudit: true,
349411},
350-{
351-id: "plugins.entries.brave.config.webSearch.apiKey",
352-targetType: "plugins.entries.brave.config.webSearch.apiKey",
353-configFile: "openclaw.json",
354-pathPattern: "plugins.entries.brave.config.webSearch.apiKey",
355-secretShape: SECRET_INPUT_SHAPE,
356-expectedResolvedValue: "string",
357-includeInPlan: true,
358-includeInConfigure: true,
359-includeInAudit: true,
360-},
361-{
362-id: "plugins.entries.google.config.webSearch.apiKey",
363-targetType: "plugins.entries.google.config.webSearch.apiKey",
364-configFile: "openclaw.json",
365-pathPattern: "plugins.entries.google.config.webSearch.apiKey",
366-secretShape: SECRET_INPUT_SHAPE,
367-expectedResolvedValue: "string",
368-includeInPlan: true,
369-includeInConfigure: true,
370-includeInAudit: true,
371-},
372-{
373-id: "plugins.entries.exa.config.webSearch.apiKey",
374-targetType: "plugins.entries.exa.config.webSearch.apiKey",
375-configFile: "openclaw.json",
376-pathPattern: "plugins.entries.exa.config.webSearch.apiKey",
377-secretShape: SECRET_INPUT_SHAPE,
378-expectedResolvedValue: "string",
379-includeInPlan: true,
380-includeInConfigure: true,
381-includeInAudit: true,
382-},
383-{
384-id: "plugins.entries.xai.config.webSearch.apiKey",
385-targetType: "plugins.entries.xai.config.webSearch.apiKey",
386-configFile: "openclaw.json",
387-pathPattern: "plugins.entries.xai.config.webSearch.apiKey",
388-secretShape: SECRET_INPUT_SHAPE,
389-expectedResolvedValue: "string",
390-includeInPlan: true,
391-includeInConfigure: true,
392-includeInAudit: true,
393-},
394-{
395-id: "plugins.entries.moonshot.config.webSearch.apiKey",
396-targetType: "plugins.entries.moonshot.config.webSearch.apiKey",
397-configFile: "openclaw.json",
398-pathPattern: "plugins.entries.moonshot.config.webSearch.apiKey",
399-secretShape: SECRET_INPUT_SHAPE,
400-expectedResolvedValue: "string",
401-includeInPlan: true,
402-includeInConfigure: true,
403-includeInAudit: true,
404-},
405-{
406-id: "plugins.entries.perplexity.config.webSearch.apiKey",
407-targetType: "plugins.entries.perplexity.config.webSearch.apiKey",
408-configFile: "openclaw.json",
409-pathPattern: "plugins.entries.perplexity.config.webSearch.apiKey",
410-secretShape: SECRET_INPUT_SHAPE,
411-expectedResolvedValue: "string",
412-includeInPlan: true,
413-includeInConfigure: true,
414-includeInAudit: true,
415-},
416-{
417-id: "plugins.entries.firecrawl.config.webSearch.apiKey",
418-targetType: "plugins.entries.firecrawl.config.webSearch.apiKey",
419-configFile: "openclaw.json",
420-pathPattern: "plugins.entries.firecrawl.config.webSearch.apiKey",
421-secretShape: SECRET_INPUT_SHAPE,
422-expectedResolvedValue: "string",
423-includeInPlan: true,
424-includeInConfigure: true,
425-includeInAudit: true,
426-},
427-{
428-id: "plugins.entries.firecrawl.config.webFetch.apiKey",
429-targetType: "plugins.entries.firecrawl.config.webFetch.apiKey",
430-configFile: "openclaw.json",
431-pathPattern: "plugins.entries.firecrawl.config.webFetch.apiKey",
432-secretShape: SECRET_INPUT_SHAPE,
433-expectedResolvedValue: "string",
434-includeInPlan: true,
435-includeInConfigure: true,
436-includeInAudit: true,
437-},
438-{
439-id: "plugins.entries.tavily.config.webSearch.apiKey",
440-targetType: "plugins.entries.tavily.config.webSearch.apiKey",
441-configFile: "openclaw.json",
442-pathPattern: "plugins.entries.tavily.config.webSearch.apiKey",
443-secretShape: SECRET_INPUT_SHAPE,
444-expectedResolvedValue: "string",
445-includeInPlan: true,
446-includeInConfigure: true,
447-includeInAudit: true,
448-},
449-{
450-id: "plugins.entries.minimax.config.webSearch.apiKey",
451-targetType: "plugins.entries.minimax.config.webSearch.apiKey",
452-configFile: "openclaw.json",
453-pathPattern: "plugins.entries.minimax.config.webSearch.apiKey",
454-secretShape: SECRET_INPUT_SHAPE,
455-expectedResolvedValue: "string",
456-includeInPlan: true,
457-includeInConfigure: true,
458-includeInAudit: true,
459-},
460412];
461413462414let cachedSecretTargetRegistry: SecretTargetRegistryEntry[] | null = null;
@@ -471,6 +423,7 @@ export function getSecretTargetRegistry(): SecretTargetRegistryEntry[] {
471423}
472424cachedSecretTargetRegistry = [
473425 ...CORE_SECRET_TARGET_REGISTRY,
426+ ...listBundledWebProviderSecretTargetRegistryEntries(),
474427 ...listChannelSecretTargetRegistryEntries(),
475428];
476429return cachedSecretTargetRegistry;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。