mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 09:41:11 +00:00
fix(runtime): drop legacy x_search auth shim
This commit is contained in:
@@ -80,6 +80,42 @@ describe("legacy x_search config migration", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("moves legacy x_search SecretRefs into the xai plugin auth slot unchanged", () => {
|
||||
const res = migrateLegacyXSearchConfig({
|
||||
tools: {
|
||||
web: {
|
||||
x_search: {
|
||||
apiKey: {
|
||||
source: "env",
|
||||
provider: "default",
|
||||
id: "X_SEARCH_KEY_REF",
|
||||
},
|
||||
enabled: true,
|
||||
},
|
||||
} as Record<string, unknown>,
|
||||
},
|
||||
} as OpenClawConfig);
|
||||
|
||||
expect((res.config.tools?.web as Record<string, unknown> | undefined)?.x_search).toEqual({
|
||||
enabled: true,
|
||||
});
|
||||
expect(res.config.plugins?.entries?.xai).toEqual({
|
||||
enabled: true,
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: {
|
||||
source: "env",
|
||||
provider: "default",
|
||||
id: "X_SEARCH_KEY_REF",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(res.changes).toEqual([
|
||||
"Moved tools.web.x_search.apiKey → plugins.entries.xai.config.webSearch.apiKey.",
|
||||
]);
|
||||
});
|
||||
|
||||
it("does nothing for knob-only x_search config without a legacy apiKey", () => {
|
||||
const config = {
|
||||
tools: {
|
||||
|
||||
@@ -651,6 +651,41 @@ describe("config strict validation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts legacy x_search SecretRefs via auto-migration and reports legacyIssues", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
await writeOpenClawConfig(home, {
|
||||
tools: {
|
||||
web: {
|
||||
x_search: {
|
||||
apiKey: {
|
||||
source: "env",
|
||||
provider: "default",
|
||||
id: "X_SEARCH_KEY_REF",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const snap = await readConfigFileSnapshot();
|
||||
|
||||
expect(snap.valid).toBe(true);
|
||||
expect(snap.legacyIssues.some((issue) => issue.path === "tools.web.x_search.apiKey")).toBe(
|
||||
true,
|
||||
);
|
||||
expect(snap.sourceConfig.plugins?.entries?.xai?.config?.webSearch).toMatchObject({
|
||||
apiKey: {
|
||||
source: "env",
|
||||
provider: "default",
|
||||
id: "X_SEARCH_KEY_REF",
|
||||
},
|
||||
});
|
||||
expect(
|
||||
(snap.sourceConfig.tools?.web?.x_search as Record<string, unknown> | undefined)?.apiKey,
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts legacy thread binding ttlHours via auto-migration and reports legacyIssues", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
await writeOpenClawConfig(home, {
|
||||
|
||||
@@ -382,16 +382,6 @@ export async function resolveRuntimeWebTools(params: {
|
||||
|
||||
const sourceTools = isRecord(params.sourceConfig.tools) ? params.sourceConfig.tools : undefined;
|
||||
const sourceWeb = isRecord(sourceTools?.web) ? sourceTools.web : undefined;
|
||||
const resolvedTools = isRecord(params.resolvedConfig.tools)
|
||||
? params.resolvedConfig.tools
|
||||
: undefined;
|
||||
const resolvedWeb = isRecord(resolvedTools?.web) ? resolvedTools.web : undefined;
|
||||
const legacyXSearchSourceRaw: unknown = sourceWeb?.x_search;
|
||||
const legacyXSearchResolvedRaw: unknown = resolvedWeb?.x_search;
|
||||
const legacyXSearchSource = isRecord(legacyXSearchSourceRaw) ? legacyXSearchSourceRaw : undefined;
|
||||
const legacyXSearchResolved = isRecord(legacyXSearchResolvedRaw)
|
||||
? legacyXSearchResolvedRaw
|
||||
: undefined;
|
||||
if (!sourceWeb && !hasPluginWebToolConfig(params.sourceConfig)) {
|
||||
return {
|
||||
search: {
|
||||
@@ -405,24 +395,6 @@ export async function resolveRuntimeWebTools(params: {
|
||||
diagnostics,
|
||||
};
|
||||
}
|
||||
if (
|
||||
legacyXSearchSource &&
|
||||
legacyXSearchResolved &&
|
||||
Object.prototype.hasOwnProperty.call(legacyXSearchSource, "apiKey")
|
||||
) {
|
||||
const apiKey = legacyXSearchSource["apiKey"];
|
||||
const resolution = await resolveSecretInputWithEnvFallback({
|
||||
sourceConfig: params.sourceConfig,
|
||||
context: params.context,
|
||||
defaults,
|
||||
value: apiKey,
|
||||
path: "tools.web.x_search.apiKey",
|
||||
envVars: ["XAI_API_KEY"],
|
||||
});
|
||||
if (resolution.value) {
|
||||
legacyXSearchResolved["apiKey"] = resolution.value;
|
||||
}
|
||||
}
|
||||
const search = isRecord(sourceWeb?.search) ? sourceWeb.search : undefined;
|
||||
const rawProvider =
|
||||
typeof search?.provider === "string" ? search.provider.trim().toLowerCase() : "";
|
||||
|
||||
@@ -1947,7 +1947,7 @@ describe("secrets runtime snapshot", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps legacy x_search SecretRefs in place until doctor repairs them", async () => {
|
||||
it("leaves legacy x_search SecretRefs untouched so doctor owns the migration", async () => {
|
||||
const snapshot = await prepareSecretsRuntimeSnapshot({
|
||||
config: asConfig({
|
||||
tools: {
|
||||
@@ -1968,45 +1968,13 @@ describe("secrets runtime snapshot", () => {
|
||||
});
|
||||
|
||||
expect((snapshot.config.tools?.web as Record<string, unknown> | undefined)?.x_search).toEqual({
|
||||
apiKey: "xai-runtime-key",
|
||||
apiKey: { source: "env", provider: "default", id: "X_SEARCH_KEY_REF" },
|
||||
enabled: true,
|
||||
model: "grok-4-1-fast",
|
||||
});
|
||||
expect(snapshot.config.plugins?.entries?.xai).toBeUndefined();
|
||||
});
|
||||
|
||||
it("still resolves legacy x_search auth in place even when unrelated legacy config is present", async () => {
|
||||
const snapshot = await prepareSecretsRuntimeSnapshot({
|
||||
config: asConfig({
|
||||
tools: {
|
||||
web: {
|
||||
x_search: {
|
||||
apiKey: { source: "env", provider: "default", id: "X_SEARCH_KEY_REF" },
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
channels: {
|
||||
telegram: {
|
||||
groupMentionsOnly: true,
|
||||
groups: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
env: {
|
||||
X_SEARCH_KEY_REF: "xai-runtime-key-invalid-config",
|
||||
},
|
||||
agentDirs: ["/tmp/openclaw-agent-main"],
|
||||
loadAuthStore: () => ({ version: 1, profiles: {} }),
|
||||
});
|
||||
|
||||
expect((snapshot.config.tools?.web as Record<string, unknown> | undefined)?.x_search).toEqual({
|
||||
apiKey: "xai-runtime-key-invalid-config",
|
||||
enabled: true,
|
||||
});
|
||||
expect(snapshot.config.plugins?.entries?.xai).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not force-enable xai at runtime for knob-only x_search config", async () => {
|
||||
const snapshot = await prepareSecretsRuntimeSnapshot({
|
||||
config: asConfig({
|
||||
|
||||
Reference in New Issue
Block a user