mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-03 13:03:43 +00:00
fix: allow config.patch with defaulted provider baseUrl
This commit is contained in:
@@ -498,7 +498,7 @@ function parseValidateConfigFromRawOrRespond(
|
||||
: restored.result;
|
||||
const validationCandidate = stripBundledProviderRuntimeDefaults({
|
||||
candidate: projectedValidationCandidate,
|
||||
sourceConfig: snapshot.parsed,
|
||||
sourceConfig: snapshot.sourceConfig,
|
||||
});
|
||||
const sourceValidated = validateConfigObjectRawWithPlugins(validationCandidate);
|
||||
if (!sourceValidated.ok) {
|
||||
@@ -859,7 +859,27 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
});
|
||||
return;
|
||||
}
|
||||
const validated = validateConfigObjectWithPlugins(restoredMerge.result);
|
||||
const validationCandidate = stripBundledProviderRuntimeDefaults({
|
||||
candidate: restoredMerge.result,
|
||||
sourceConfig: snapshot.sourceConfig,
|
||||
});
|
||||
const sourceValidated = validateConfigObjectRawWithPlugins(validationCandidate);
|
||||
if (!sourceValidated.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
summarizeConfigValidationIssues(sourceValidated.issues),
|
||||
{
|
||||
details: { issues: sourceValidated.issues },
|
||||
},
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const writeConfig = validationCandidate as OpenClawConfig;
|
||||
const validated = validateConfigObjectWithPlugins(validationCandidate);
|
||||
if (!validated.ok) {
|
||||
respond(
|
||||
false,
|
||||
@@ -908,7 +928,7 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
const writeResult = await commitGatewayConfigWrite({
|
||||
snapshot,
|
||||
writeOptions,
|
||||
nextConfig: validated.config,
|
||||
nextConfig: writeConfig,
|
||||
context,
|
||||
disconnectSharedAuthClients,
|
||||
});
|
||||
|
||||
@@ -280,6 +280,82 @@ describe("gateway config methods", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("accepts config.patch when bundled provider baseUrl was only defaulted", async () => {
|
||||
const { createConfigIO, resetConfigRuntimeState } = await import("../config/config.js");
|
||||
const configPath = createConfigIO().configPath;
|
||||
try {
|
||||
await writeJsonFile(configPath, {
|
||||
models: {
|
||||
providers: {
|
||||
openai: {
|
||||
agentRuntime: { id: "openclaw" },
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
resetConfigRuntimeState();
|
||||
|
||||
const current = await getCurrentConfigObject();
|
||||
|
||||
const res = await rpcReq<{
|
||||
ok?: boolean;
|
||||
error?: { message?: string };
|
||||
}>(requireWs(), "config.patch", {
|
||||
raw: JSON.stringify({ gateway: { port: 19003 } }),
|
||||
baseHash: current.hash,
|
||||
});
|
||||
|
||||
expect(res.error).toBeUndefined();
|
||||
expect(res.ok).toBe(true);
|
||||
const persisted = await fs.readFile(configPath, "utf-8");
|
||||
expect(persisted).toContain('"port": 19003');
|
||||
expect(persisted).not.toContain('"baseUrl"');
|
||||
expect(persisted).not.toContain('"models": []');
|
||||
} finally {
|
||||
await fs.rm(configPath, { force: true });
|
||||
resetConfigRuntimeState();
|
||||
}
|
||||
});
|
||||
|
||||
it("preserves authored empty bundled provider models during config.patch", async () => {
|
||||
const { createConfigIO, resetConfigRuntimeState } = await import("../config/config.js");
|
||||
const configPath = createConfigIO().configPath;
|
||||
try {
|
||||
await writeJsonFile(configPath, {
|
||||
models: {
|
||||
providers: {
|
||||
openai: {
|
||||
agentRuntime: { id: "openclaw" },
|
||||
models: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
resetConfigRuntimeState();
|
||||
|
||||
const current = await getCurrentConfigObject();
|
||||
|
||||
const res = await rpcReq<{
|
||||
ok?: boolean;
|
||||
error?: { message?: string };
|
||||
}>(requireWs(), "config.patch", {
|
||||
raw: JSON.stringify({ gateway: { port: 19004 } }),
|
||||
baseHash: current.hash,
|
||||
});
|
||||
|
||||
expect(res.error).toBeUndefined();
|
||||
expect(res.ok).toBe(true);
|
||||
const persisted = JSON.parse(await fs.readFile(configPath, "utf-8")) as {
|
||||
models?: { providers?: { openai?: { baseUrl?: unknown; models?: unknown } } };
|
||||
};
|
||||
expect(persisted.models?.providers?.openai?.baseUrl).toBeUndefined();
|
||||
expect(persisted.models?.providers?.openai?.models).toEqual([]);
|
||||
} finally {
|
||||
await fs.rm(configPath, { force: true });
|
||||
resetConfigRuntimeState();
|
||||
}
|
||||
});
|
||||
|
||||
it("redacts browser cdpUrl credentials from config.get responses", async () => {
|
||||
const { createConfigIO, resetConfigRuntimeState } = await import("../config/config.js");
|
||||
const configPath = createConfigIO().configPath;
|
||||
|
||||
Reference in New Issue
Block a user