mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 20:04:32 +00:00
Memory/QMD: handle fallback init failures gracefully
This commit is contained in:
@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Memory/QMD: make QMD result JSON parsing resilient to noisy command output by extracting the first JSON array from noisy `stdout`.
|
- Memory/QMD: make QMD result JSON parsing resilient to noisy command output by extracting the first JSON array from noisy `stdout`.
|
||||||
- Memory/QMD: treat prefixed `no results found` marker output as an empty result set in qmd JSON parsing. (#11302) Thanks @blazerui.
|
- Memory/QMD: treat prefixed `no results found` marker output as an empty result set in qmd JSON parsing. (#11302) Thanks @blazerui.
|
||||||
- Memory/QMD: make `memory status` read-only by skipping QMD boot update/embed side effects for status-only manager checks.
|
- Memory/QMD: make `memory status` read-only by skipping QMD boot update/embed side effects for status-only manager checks.
|
||||||
|
- Memory/QMD: keep original QMD failures when builtin fallback initialization fails (for example missing embedding API keys), instead of replacing them with fallback init errors.
|
||||||
- Memory/QMD: pass result limits to `search`/`vsearch` commands so QMD can cap results earlier.
|
- Memory/QMD: pass result limits to `search`/`vsearch` commands so QMD can cap results earlier.
|
||||||
- Memory/QMD: avoid reading full markdown files when a `from/lines` window is requested in QMD reads.
|
- Memory/QMD: avoid reading full markdown files when a `from/lines` window is requested in QMD reads.
|
||||||
- Memory/QMD: skip rewriting unchanged session export markdown files during sync to reduce disk churn.
|
- Memory/QMD: skip rewriting unchanged session export markdown files during sync to reduce disk churn.
|
||||||
|
|||||||
@@ -209,4 +209,22 @@ describe("getMemorySearchManager caching", () => {
|
|||||||
expect(results[0]?.path).toBe("MEMORY.md");
|
expect(results[0]?.path).toBe("MEMORY.md");
|
||||||
expect(fallbackSearch).toHaveBeenCalledTimes(1);
|
expect(fallbackSearch).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps original qmd error when fallback manager initialization fails", async () => {
|
||||||
|
const retryAgentId = "retry-agent-no-fallback-auth";
|
||||||
|
const cfg = {
|
||||||
|
memory: { backend: "qmd", qmd: {} },
|
||||||
|
agents: { list: [{ id: retryAgentId, default: true, workspace: "/tmp/workspace" }] },
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
mockPrimary.search.mockRejectedValueOnce(new Error("qmd query failed"));
|
||||||
|
mockMemoryIndexGet.mockRejectedValueOnce(new Error("No API key found for provider openai"));
|
||||||
|
|
||||||
|
const first = await getMemorySearchManager({ cfg, agentId: retryAgentId });
|
||||||
|
if (!first.manager) {
|
||||||
|
throw new Error("manager missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
await expect(first.manager.search("hello")).rejects.toThrow("qmd query failed");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -191,9 +191,16 @@ class FallbackMemoryManager implements MemorySearchManager {
|
|||||||
if (this.fallback) {
|
if (this.fallback) {
|
||||||
return this.fallback;
|
return this.fallback;
|
||||||
}
|
}
|
||||||
const fallback = await this.deps.fallbackFactory();
|
let fallback: MemorySearchManager | null;
|
||||||
if (!fallback) {
|
try {
|
||||||
log.warn("memory fallback requested but builtin index is unavailable");
|
fallback = await this.deps.fallbackFactory();
|
||||||
|
if (!fallback) {
|
||||||
|
log.warn("memory fallback requested but builtin index is unavailable");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
log.warn(`memory fallback unavailable: ${message}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.fallback = fallback;
|
this.fallback = fallback;
|
||||||
|
|||||||
Reference in New Issue
Block a user