mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-02 15:21:04 +00:00
fix: migrate legacy memory auto provider
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user