






















@@ -1,3 +1,4 @@
1+import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
12import {
23createWebSearchProviderContractFields,
34mergeScopedSearchConfig,
@@ -12,6 +13,7 @@ import {
1213} from "./gemini-web-search-provider.shared.js";
13141415const GEMINI_CREDENTIAL_PATH = "plugins.entries.google.config.webSearch.apiKey";
16+const GOOGLE_PROVIDER_CREDENTIAL_PATH = "models.providers.google.apiKey";
15171618type GeminiWebSearchRuntime = typeof import("./gemini-web-search-provider.runtime.js");
1719@@ -64,7 +66,54 @@ function createGeminiToolDefinition(
6466};
6567}
666869+function isRecord(value: unknown): value is Record<string, unknown> {
70+return typeof value === "object" && value !== null && !Array.isArray(value);
71+}
72+73+function resolveGoogleModelProviderConfig(
74+config?: OpenClawConfig,
75+): Record<string, unknown> | undefined {
76+const provider = config?.models?.providers?.google;
77+return isRecord(provider) ? provider : undefined;
78+}
79+80+function getGoogleModelProviderCredentialFallback(
81+config?: OpenClawConfig,
82+): { path: string; value: unknown } | undefined {
83+const provider = resolveGoogleModelProviderConfig(config);
84+return provider && provider.apiKey !== undefined
85+ ? { path: GOOGLE_PROVIDER_CREDENTIAL_PATH, value: provider.apiKey }
86+ : undefined;
87+}
88+89+function withGoogleModelProviderFallbacks(
90+searchConfig: Record<string, unknown> | undefined,
91+config?: OpenClawConfig,
92+): Record<string, unknown> | undefined {
93+const provider = resolveGoogleModelProviderConfig(config);
94+if (!provider || (provider.apiKey === undefined && provider.baseUrl === undefined)) {
95+return searchConfig;
96+}
97+const gemini = isRecord(searchConfig?.gemini) ? { ...searchConfig.gemini } : {};
98+if (provider.apiKey !== undefined) {
99+gemini.providerApiKey = provider.apiKey;
100+}
101+if (provider.baseUrl !== undefined) {
102+gemini.providerBaseUrl = provider.baseUrl;
103+}
104+return {
105+ ...(searchConfig ?? {}),
106+ gemini,
107+};
108+}
109+67110export function createGeminiWebSearchProvider(): WebSearchProviderPlugin {
111+const contractFields = createWebSearchProviderContractFields({
112+credentialPath: GEMINI_CREDENTIAL_PATH,
113+searchCredential: { type: "scoped", scopeId: "gemini" },
114+configuredCredential: { pluginId: "google" },
115+});
116+68117return {
69118id: "gemini",
70119label: "Gemini (Google Search)",
@@ -77,17 +126,17 @@ export function createGeminiWebSearchProvider(): WebSearchProviderPlugin {
77126docsUrl: "https://docs.openclaw.ai/tools/web",
78127autoDetectOrder: 20,
79128credentialPath: GEMINI_CREDENTIAL_PATH,
80- ...createWebSearchProviderContractFields({
81-credentialPath: GEMINI_CREDENTIAL_PATH,
82-searchCredential: { type: "scoped", scopeId: "gemini" },
83-configuredCredential: { pluginId: "google" },
84-}),
129+ ...contractFields,
130+getConfiguredCredentialFallback: getGoogleModelProviderCredentialFallback,
85131createTool: (ctx) =>
86132createGeminiToolDefinition(
87-mergeScopedSearchConfig(
88-ctx.searchConfig,
89-"gemini",
90-resolveProviderWebSearchPluginConfig(ctx.config, "google"),
133+withGoogleModelProviderFallbacks(
134+mergeScopedSearchConfig(
135+ctx.searchConfig,
136+"gemini",
137+resolveProviderWebSearchPluginConfig(ctx.config, "google"),
138+),
139+ctx.config,
91140),
92141),
93142};
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。