
























@@ -1,21 +1,32 @@
1+import fs from "node:fs";
2+import path from "node:path";
13import { normalizeProviderId } from "../agents/provider-id.js";
24import type { ModelProviderConfig } from "../config/types.js";
35import type { OpenClawConfig } from "../config/types.openclaw.js";
6+import { resolveBundledPluginsDir } from "./bundled-dir.js";
47import type {
58ProviderApplyConfigDefaultsContext,
69ProviderNormalizeConfigContext,
710ProviderResolveConfigApiKeyContext,
811} from "./provider-config-context.types.js";
12+import type {
13+ProviderDefaultThinkingPolicyContext,
14+ProviderThinkingProfile,
15+} from "./provider-thinking.types.js";
916import { loadBundledPluginPublicArtifactModuleSync } from "./public-surface-loader.js";
10171118const PROVIDER_POLICY_ARTIFACT_CANDIDATES = ["provider-policy-api.js"] as const;
19+const providerPolicyPluginIdsByProviderId = new Map<string, string | null>();
12201321export type BundledProviderPolicySurface = {
1422normalizeConfig?: (ctx: ProviderNormalizeConfigContext) => ModelProviderConfig | null | undefined;
1523applyConfigDefaults?: (
1624ctx: ProviderApplyConfigDefaultsContext,
1725) => OpenClawConfig | null | undefined;
1826resolveConfigApiKey?: (ctx: ProviderResolveConfigApiKeyContext) => string | null | undefined;
27+resolveThinkingProfile?: (
28+ctx: ProviderDefaultThinkingPolicyContext,
29+) => ProviderThinkingProfile | null | undefined;
1930};
20312132function hasProviderPolicyHook(
@@ -24,7 +35,8 @@ function hasProviderPolicyHook(
2435return (
2536typeof mod.normalizeConfig === "function" ||
2637typeof mod.applyConfigDefaults === "function" ||
27-typeof mod.resolveConfigApiKey === "function"
38+typeof mod.resolveConfigApiKey === "function" ||
39+typeof mod.resolveThinkingProfile === "function"
2840);
2941}
3042@@ -54,12 +66,63 @@ function tryLoadBundledProviderPolicySurface(
5466return null;
5567}
566869+function resolveBundledProviderPolicyPluginId(providerId: string): string | null {
70+const normalizedProviderId = normalizeProviderId(providerId);
71+if (!normalizedProviderId) {
72+return null;
73+}
74+const bundledPluginsDir = resolveBundledPluginsDir();
75+const cacheKey = `${bundledPluginsDir ?? "<none>"}::${normalizedProviderId}`;
76+if (providerPolicyPluginIdsByProviderId.has(cacheKey)) {
77+return providerPolicyPluginIdsByProviderId.get(cacheKey) ?? null;
78+}
79+80+if (!bundledPluginsDir || !fs.existsSync(bundledPluginsDir)) {
81+providerPolicyPluginIdsByProviderId.set(cacheKey, null);
82+return null;
83+}
84+85+for (const entry of fs
86+.readdirSync(bundledPluginsDir, { withFileTypes: true })
87+.filter((candidate) => candidate.isDirectory())
88+.map((candidate) => candidate.name)
89+.toSorted((left, right) => left.localeCompare(right))) {
90+const manifestPath = path.join(bundledPluginsDir, entry, "openclaw.plugin.json");
91+if (!fs.existsSync(manifestPath)) {
92+continue;
93+}
94+let manifest: { providers?: unknown };
95+try {
96+manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8")) as { providers?: unknown };
97+} catch {
98+continue;
99+}
100+const providers = Array.isArray(manifest.providers) ? manifest.providers : [];
101+const ownsProvider = providers.some(
102+(candidate) =>
103+typeof candidate === "string" && normalizeProviderId(candidate) === normalizedProviderId,
104+);
105+if (ownsProvider) {
106+providerPolicyPluginIdsByProviderId.set(cacheKey, entry);
107+return entry;
108+}
109+}
110+111+providerPolicyPluginIdsByProviderId.set(cacheKey, null);
112+return null;
113+}
114+57115export function resolveBundledProviderPolicySurface(
58116providerId: string,
59117): BundledProviderPolicySurface | null {
60118const normalizedProviderId = normalizeProviderId(providerId);
61119if (!normalizedProviderId) {
62120return null;
63121}
64-return tryLoadBundledProviderPolicySurface(normalizedProviderId);
122+return (
123+tryLoadBundledProviderPolicySurface(normalizedProviderId) ??
124+tryLoadBundledProviderPolicySurface(
125+resolveBundledProviderPolicyPluginId(normalizedProviderId) ?? normalizedProviderId,
126+)
127+);
65128}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。