mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:50:43 +00:00
fix(active-memory): fast-fail stalled recall paths
This commit is contained in:
@@ -14,6 +14,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- CLI/plugins: stop treating the non-plugin `auth` command root as a bundled plugin id, so restrictive `plugins.allow` configs no longer tell users to add stale `auth` plugin entries.
|
||||
- Doctor/plugins: update configured plugin installs whose stale manifests still declare channels without `channelConfigs`, so beta upgrades repair old Discord-style package payloads during `doctor --fix`.
|
||||
- Active Memory: keep non-empty `memory_search` results from being fast-failed as empty when debug telemetry reports zero hits.
|
||||
- Plugins/externalization: repair missing configured plugin installs from npm by default, reserve ClawHub downloads for explicit `clawhubSpec` metadata, and cover agent-runtime/env-selected plugin repair. Thanks @vincentkoc.
|
||||
- Upgrade/config: validate configured web-search providers and statically suppressed model/provider pairs against the active plugin set at config load, so stale plugin state fails loud before runtime fallback.
|
||||
- Status/update: resolve beta update-channel checks from the installed version when config still says `stable`, and let `status --deep` reuse live gateway channel credential state instead of warning on command-path-only token misses.
|
||||
|
||||
@@ -2342,6 +2342,49 @@ describe("active-memory plugin", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("does not fast-fail memory_search results solely because debug hits is zero", async () => {
|
||||
__testing.setMinimumTimeoutMsForTests(1);
|
||||
__testing.setSetupGraceTimeoutMsForTests(0);
|
||||
api.pluginConfig = {
|
||||
agents: ["main"],
|
||||
timeoutMs: 500,
|
||||
logging: true,
|
||||
};
|
||||
plugin.register(api as unknown as OpenClawPluginApi);
|
||||
const sessionKey = "agent:main:terminal-zero-hit-with-results";
|
||||
hoisted.sessionStore[sessionKey] = {
|
||||
sessionId: "s-terminal-zero-hit-with-results",
|
||||
updatedAt: 0,
|
||||
};
|
||||
runEmbeddedPiAgent.mockImplementationOnce(async (params: { sessionFile: string }) => {
|
||||
await writeTranscriptJsonl(params.sessionFile, [
|
||||
{
|
||||
message: {
|
||||
role: "toolResult",
|
||||
toolName: "memory_search",
|
||||
details: {
|
||||
results: [{ path: "memory/food.md", text: "User usually orders ramen." }],
|
||||
debug: { backend: "qmd", hits: 0, searchMs: 8 },
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
return { payloads: [{ text: "User usually orders ramen." }] };
|
||||
});
|
||||
|
||||
const result = await hooks.before_prompt_build(
|
||||
{ prompt: "what food do i usually order? zero hit with results", messages: [] },
|
||||
{ agentId: "main", trigger: "user", sessionKey, messageProvider: "webchat" },
|
||||
);
|
||||
|
||||
expect(result?.prependContext).toContain("User usually orders ramen.");
|
||||
expect(getActiveMemoryLines(sessionKey)).toEqual([
|
||||
expect.stringContaining("🧩 Active Memory: status=ok"),
|
||||
expect.stringContaining("🔎 Active Memory Debug: backend=qmd searchMs=8 hits=0"),
|
||||
]);
|
||||
});
|
||||
|
||||
it("fast-fails unavailable memory_search results without injecting provider errors", async () => {
|
||||
const CONFIGURED_TIMEOUT_MS = 1_000;
|
||||
__testing.setMinimumTimeoutMsForTests(1);
|
||||
|
||||
@@ -1595,13 +1595,10 @@ function extractTerminalMemorySearchResultFromSessionRecord(
|
||||
const disabled = details?.disabled === true;
|
||||
const unavailable =
|
||||
disabled || Boolean(debug?.warning) || Boolean(debug?.error) || Boolean(details?.error);
|
||||
const hits =
|
||||
typeof debug?.hits === "number" && Number.isFinite(debug.hits)
|
||||
? debug.hits
|
||||
: results
|
||||
? results.length
|
||||
: undefined;
|
||||
if (unavailable || hits === 0) {
|
||||
const debugHits =
|
||||
typeof debug?.hits === "number" && Number.isFinite(debug.hits) ? debug.hits : undefined;
|
||||
const zeroHitSearch = results !== undefined ? results.length === 0 : debugHits === 0;
|
||||
if (unavailable || zeroHitSearch) {
|
||||
return { status: "empty", searchDebug: debug };
|
||||
}
|
||||
return undefined;
|
||||
|
||||
Reference in New Issue
Block a user