fix: migrate legacy memory auto provider

This commit is contained in:
Mariano Belinky
2026-05-27 15:40:42 +02:00
parent 09d2682cd8
commit a7d2d9c6df
3 changed files with 140 additions and 1 deletions

View File

@@ -515,7 +515,7 @@ That stages grounded durable candidates into the short-term dreaming store while
- **QMD backend**: probes whether the `qmd` binary is available and startable. If not, prints fix guidance including the npm package and a manual binary path option.
- **Explicit local provider**: checks for a local model file or a recognized remote/downloadable model URL. If missing, suggests switching to a remote provider.
- **Explicit remote provider** (`openai`, `voyage`, etc.): verifies an API key is present in the environment or auth store. Prints actionable fix hints if missing.
- **Legacy auto provider**: treats `memorySearch.provider: "auto"` as OpenAI and checks OpenAI readiness.
- **Legacy auto provider**: treats `memorySearch.provider: "auto"` as OpenAI, checks OpenAI readiness, and `doctor --fix` rewrites it to `provider: "openai"`.
When a cached gateway probe result is available (gateway was healthy at the time of the check), doctor cross-references its result with the CLI-visible config and notes any discrepancy. Doctor does not start a fresh embedding ping on the default path; use the deep memory status command when you want a live provider check.

View File

@@ -62,6 +62,75 @@ describe("compatibility binding repair migrate", () => {
});
});
describe("legacy memory search config migrate", () => {
it("rewrites top-level legacy auto provider after moving memorySearch into agent defaults", () => {
const raw = {
memorySearch: {
provider: "auto",
model: "text-embedding-3-small",
},
};
expect(findLegacyConfigIssues(raw).map((issue) => issue.path)).toEqual([
"memorySearch",
"memorySearch.provider",
]);
const res = migrateLegacyConfigForTest(raw);
expect(res.config?.agents?.defaults?.memorySearch).toEqual({
provider: "openai",
model: "text-embedding-3-small",
});
expect(res.config).not.toHaveProperty("memorySearch");
expect(res.changes).toEqual([
"Moved memorySearch → agents.defaults.memorySearch.",
'Moved agents.defaults.memorySearch.provider from legacy "auto" to "openai".',
]);
});
it("rewrites default and per-agent legacy auto memory providers", () => {
const raw = {
agents: {
defaults: {
memorySearch: {
provider: "auto",
},
},
list: [
{
id: "local",
memorySearch: {
provider: " auto ",
},
},
{
id: "custom",
memorySearch: {
provider: "openai-compatible",
},
},
],
},
};
expect(findLegacyConfigIssues(raw).map((issue) => issue.path)).toEqual([
"agents.defaults.memorySearch.provider",
"agents.list",
]);
const res = migrateLegacyConfigForTest(raw);
expect(res.config?.agents?.defaults?.memorySearch?.provider).toBe("openai");
expect(res.config?.agents?.list?.[0]?.memorySearch?.provider).toBe("openai");
expect(res.config?.agents?.list?.[1]?.memorySearch?.provider).toBe("openai-compatible");
expect(res.changes).toEqual([
'Moved agents.defaults.memorySearch.provider from legacy "auto" to "openai".',
'Moved agents.list.0.memorySearch.provider from legacy "auto" to "openai".',
]);
});
});
describe("legacy silent reply config migrate", () => {
it("removes silent reply rewrite and direct-chat silent reply config", () => {
const res = migrateLegacyConfigForTest({

View File

@@ -45,6 +45,27 @@ const MEMORY_SEARCH_RULE: LegacyConfigRule = {
'top-level memorySearch was moved; use agents.defaults.memorySearch instead. Run "openclaw doctor --fix".',
};
const LEGACY_MEMORY_SEARCH_AUTO_PROVIDER_RULES: LegacyConfigRule[] = [
{
path: ["memorySearch", "provider"],
message:
'memorySearch.provider = "auto" is legacy; use "openai" explicitly. Run "openclaw doctor --fix".',
match: isLegacyMemorySearchAutoProvider,
},
{
path: ["agents", "defaults", "memorySearch", "provider"],
message:
'agents.defaults.memorySearch.provider = "auto" is legacy; use "openai" explicitly. Run "openclaw doctor --fix".',
match: isLegacyMemorySearchAutoProvider,
},
{
path: ["agents", "list"],
message:
'agents.list[].memorySearch.provider = "auto" is legacy; use "openai" explicitly. Run "openclaw doctor --fix".',
match: hasAgentListLegacyMemorySearchAutoProvider,
},
];
const HEARTBEAT_RULE: LegacyConfigRule = {
path: ["heartbeat"],
message:
@@ -335,6 +356,31 @@ function migrateLegacyEmbeddedAgentKey(
delete container.embeddedPi;
}
function isLegacyMemorySearchAutoProvider(value: unknown): boolean {
return typeof value === "string" && value.trim().toLowerCase() === "auto";
}
function hasAgentListLegacyMemorySearchAutoProvider(value: unknown): boolean {
if (!Array.isArray(value)) {
return false;
}
return value.some((agent) =>
isLegacyMemorySearchAutoProvider(getRecord(getRecord(agent)?.memorySearch)?.provider),
);
}
function rewriteLegacyMemorySearchAutoProvider(
memorySearch: Record<string, unknown> | null,
pathLabel: string,
changes: string[],
): void {
if (!memorySearch || !isLegacyMemorySearchAutoProvider(memorySearch.provider)) {
return;
}
memorySearch.provider = "openai";
changes.push(`Moved ${pathLabel}.provider from legacy "auto" to "openai".`);
}
function migrateLegacySandboxPerSession(
sandbox: Record<string, unknown>,
pathLabel: string,
@@ -1245,6 +1291,30 @@ export const LEGACY_CONFIG_MIGRATIONS_RUNTIME_AGENTS: LegacyConfigMigrationSpec[
delete raw.memorySearch;
},
}),
defineLegacyConfigMigration({
id: "memorySearch.provider-auto->openai",
describe: 'Rewrite legacy memorySearch provider "auto" to "openai"',
legacyRules: LEGACY_MEMORY_SEARCH_AUTO_PROVIDER_RULES,
apply: (raw, changes) => {
const agents = getRecord(raw.agents);
rewriteLegacyMemorySearchAutoProvider(
getRecord(getRecord(agents?.defaults)?.memorySearch),
"agents.defaults.memorySearch",
changes,
);
if (!Array.isArray(agents?.list)) {
return;
}
for (const [index, agent] of agents.list.entries()) {
rewriteLegacyMemorySearchAutoProvider(
getRecord(getRecord(agent)?.memorySearch),
`agents.list.${index}.memorySearch`,
changes,
);
}
},
}),
defineLegacyConfigMigration({
id: "heartbeat->agents.defaults.heartbeat",
describe: "Move top-level heartbeat to agents.defaults.heartbeat/channels.defaults.heartbeat",