mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:20:45 +00:00
fix(memory): refresh tool config at execution
This commit is contained in:
@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
- Memory-core: re-resolve the active runtime config whenever `memory_search` or `memory_get` executes, so provider changes made by `config.patch` stop leaving stale embedding backends behind in existing tool instances. Fixes #61098. Thanks @BradGroux and @Linux2010.
|
||||||
- Channels/setup: treat bundled channel plugins as already bundled during `channels add` and onboarding, enabling them without writing redundant `plugins.load.paths` entries or path install records. Fixes #72740. Thanks @iCodePoet.
|
- Channels/setup: treat bundled channel plugins as already bundled during `channels add` and onboarding, enabling them without writing redundant `plugins.load.paths` entries or path install records. Fixes #72740. Thanks @iCodePoet.
|
||||||
- WhatsApp: honor gateway `HTTPS_PROXY` / `HTTP_PROXY` env vars for QR-login WebSocket connections, while respecting `NO_PROXY`, so proxied networks no longer fall back to direct `mmg.whatsapp.net` connections that time out with 408. Fixes #72547; supersedes #72692. Thanks @mebusw and @SymbolStar.
|
- WhatsApp: honor gateway `HTTPS_PROXY` / `HTTP_PROXY` env vars for QR-login WebSocket connections, while respecting `NO_PROXY`, so proxied networks no longer fall back to direct `mmg.whatsapp.net` connections that time out with 408. Fixes #72547; supersedes #72692. Thanks @mebusw and @SymbolStar.
|
||||||
- Bonjour: default mDNS advertisements to the system hostname when it is DNS-safe, avoiding `openclaw.local` probing conflicts and Gateway restart loops on hosts such as `Lobster` or `ubuntu`. Fixes #72355 and #72689; supersedes #72694. Thanks @mscheuerlein-bot, @gcusms, @moyuwuhen601, @pavan987, @zml-0912, @hhq365, and @SymbolStar.
|
- Bonjour: default mDNS advertisements to the system hostname when it is DNS-safe, avoiding `openclaw.local` probing conflicts and Gateway restart loops on hosts such as `Lobster` or `ubuntu`. Fixes #72355 and #72689; supersedes #72694. Thanks @mscheuerlein-bot, @gcusms, @moyuwuhen601, @pavan987, @zml-0912, @hhq365, and @SymbolStar.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/config-runtime";
|
||||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||||
import { registerMemoryCli } from "./src/cli.js";
|
import { registerMemoryCli } from "./src/cli.js";
|
||||||
import { registerDreamingCommand } from "./src/dreaming-command.js";
|
import { registerDreamingCommand } from "./src/dreaming-command.js";
|
||||||
@@ -42,7 +43,8 @@ export default definePluginEntry({
|
|||||||
api.registerTool(
|
api.registerTool(
|
||||||
(ctx) =>
|
(ctx) =>
|
||||||
createMemorySearchTool({
|
createMemorySearchTool({
|
||||||
config: ctx.config,
|
config: ctx.runtimeConfig ?? ctx.config,
|
||||||
|
getConfig: () => getRuntimeConfigSnapshot() ?? ctx.runtimeConfig ?? ctx.config,
|
||||||
agentSessionKey: ctx.sessionKey,
|
agentSessionKey: ctx.sessionKey,
|
||||||
sandboxed: ctx.sandboxed,
|
sandboxed: ctx.sandboxed,
|
||||||
}),
|
}),
|
||||||
@@ -52,7 +54,8 @@ export default definePluginEntry({
|
|||||||
api.registerTool(
|
api.registerTool(
|
||||||
(ctx) =>
|
(ctx) =>
|
||||||
createMemoryGetTool({
|
createMemoryGetTool({
|
||||||
config: ctx.config,
|
config: ctx.runtimeConfig ?? ctx.config,
|
||||||
|
getConfig: () => getRuntimeConfigSnapshot() ?? ctx.runtimeConfig ?? ctx.config,
|
||||||
agentSessionKey: ctx.sessionKey,
|
agentSessionKey: ctx.sessionKey,
|
||||||
}),
|
}),
|
||||||
{ names: ["memory_get"] },
|
{ names: ["memory_get"] },
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ const stubManager = {
|
|||||||
close: vi.fn(),
|
close: vi.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMemorySearchManagerMock = vi.fn(async () => ({ manager: stubManager }));
|
const getMemorySearchManagerMock = vi.fn(async (_params: { cfg?: unknown }) => ({
|
||||||
|
manager: stubManager,
|
||||||
|
}));
|
||||||
const readAgentMemoryFileMock = vi.fn(
|
const readAgentMemoryFileMock = vi.fn(
|
||||||
async (params: MemoryReadParams) => await readFileImpl(params),
|
async (params: MemoryReadParams) => await readFileImpl(params),
|
||||||
);
|
);
|
||||||
@@ -116,6 +118,10 @@ export function getMemorySearchManagerMockCalls(): number {
|
|||||||
return getMemorySearchManagerMock.mock.calls.length;
|
return getMemorySearchManagerMock.mock.calls.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMemorySearchManagerMockConfigs(): unknown[] {
|
||||||
|
return getMemorySearchManagerMock.mock.calls.map(([params]) => params.cfg);
|
||||||
|
}
|
||||||
|
|
||||||
export function getReadAgentMemoryFileMockCalls(): number {
|
export function getReadAgentMemoryFileMockCalls(): number {
|
||||||
return readAgentMemoryFileMock.mock.calls.length;
|
return readAgentMemoryFileMock.mock.calls.length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ type MemoryToolRuntime = typeof import("./tools.runtime.js");
|
|||||||
type MemorySearchManagerResult = Awaited<
|
type MemorySearchManagerResult = Awaited<
|
||||||
ReturnType<(typeof import("./memory/index.js"))["getMemorySearchManager"]>
|
ReturnType<(typeof import("./memory/index.js"))["getMemorySearchManager"]>
|
||||||
>;
|
>;
|
||||||
|
type MemoryToolOptions = {
|
||||||
|
config?: OpenClawConfig;
|
||||||
|
getConfig?: () => OpenClawConfig | undefined;
|
||||||
|
agentSessionKey?: string;
|
||||||
|
};
|
||||||
|
|
||||||
let memoryToolRuntimePromise: Promise<MemoryToolRuntime> | null = null;
|
let memoryToolRuntimePromise: Promise<MemoryToolRuntime> | null = null;
|
||||||
|
|
||||||
@@ -44,11 +49,8 @@ export const MemoryGetSchema = Type.Object({
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
export function resolveMemoryToolContext(options: {
|
export function resolveMemoryToolContext(options: MemoryToolOptions) {
|
||||||
config?: OpenClawConfig;
|
const cfg = options.getConfig?.() ?? options.config;
|
||||||
agentSessionKey?: string;
|
|
||||||
}) {
|
|
||||||
const cfg = options.config;
|
|
||||||
if (!cfg) {
|
if (!cfg) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -98,10 +100,7 @@ export async function getMemoryManagerContextWithPurpose(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function createMemoryTool(params: {
|
export function createMemoryTool(params: {
|
||||||
options: {
|
options: MemoryToolOptions;
|
||||||
config?: OpenClawConfig;
|
|
||||||
agentSessionKey?: string;
|
|
||||||
};
|
|
||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -117,7 +116,10 @@ export function createMemoryTool(params: {
|
|||||||
name: params.name,
|
name: params.name,
|
||||||
description: params.description,
|
description: params.description,
|
||||||
parameters: params.parameters,
|
parameters: params.parameters,
|
||||||
execute: params.execute(ctx),
|
execute: async (toolCallId, toolParams) => {
|
||||||
|
const latestCtx = resolveMemoryToolContext(params.options) ?? ctx;
|
||||||
|
return await params.execute(latestCtx)(toolCallId, toolParams);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { beforeEach, describe, expect, it } from "vitest";
|
import { beforeEach, describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
|
getMemorySearchManagerMockConfigs,
|
||||||
resetMemoryToolMockState,
|
resetMemoryToolMockState,
|
||||||
setMemoryBackend,
|
setMemoryBackend,
|
||||||
setMemorySearchImpl,
|
setMemorySearchImpl,
|
||||||
} from "./memory-tool-manager-mock.js";
|
} from "./memory-tool-manager-mock.js";
|
||||||
|
import { createMemorySearchTool } from "./tools.js";
|
||||||
import {
|
import {
|
||||||
|
asOpenClawConfig,
|
||||||
createMemorySearchToolOrThrow,
|
createMemorySearchToolOrThrow,
|
||||||
expectUnavailableMemorySearchDetails,
|
expectUnavailableMemorySearchDetails,
|
||||||
} from "./tools.test-helpers.js";
|
} from "./tools.test-helpers.js";
|
||||||
@@ -103,4 +106,48 @@ describe("memory_search unavailable payloads", () => {
|
|||||||
expect.any(Number),
|
expect.any(Number),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("re-resolves config when executing a previously created tool", async () => {
|
||||||
|
const startupConfig = asOpenClawConfig({
|
||||||
|
agents: {
|
||||||
|
defaults: {
|
||||||
|
memorySearch: {
|
||||||
|
provider: "ollama",
|
||||||
|
model: "nomic-embed-text",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
list: [{ id: "main", default: true }],
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
backend: "builtin",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const patchedConfig = asOpenClawConfig({
|
||||||
|
agents: {
|
||||||
|
defaults: {
|
||||||
|
memorySearch: {
|
||||||
|
provider: "openai",
|
||||||
|
model: "text-embedding-3-small",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
list: [{ id: "main", default: true }],
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
backend: "builtin",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let liveConfig = startupConfig;
|
||||||
|
const tool = createMemorySearchTool({
|
||||||
|
config: startupConfig,
|
||||||
|
getConfig: () => liveConfig,
|
||||||
|
});
|
||||||
|
if (!tool) {
|
||||||
|
throw new Error("tool missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
liveConfig = patchedConfig;
|
||||||
|
await tool.execute("patched-config", { query: "provider switch" });
|
||||||
|
|
||||||
|
expect(getMemorySearchManagerMockConfigs()).toEqual([patchedConfig]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ async function executeMemoryReadResult<T>(params: {
|
|||||||
|
|
||||||
export function createMemorySearchTool(options: {
|
export function createMemorySearchTool(options: {
|
||||||
config?: OpenClawConfig;
|
config?: OpenClawConfig;
|
||||||
|
getConfig?: () => OpenClawConfig | undefined;
|
||||||
agentSessionKey?: string;
|
agentSessionKey?: string;
|
||||||
sandboxed?: boolean;
|
sandboxed?: boolean;
|
||||||
}) {
|
}) {
|
||||||
@@ -344,6 +345,7 @@ export function createMemorySearchTool(options: {
|
|||||||
|
|
||||||
export function createMemoryGetTool(options: {
|
export function createMemoryGetTool(options: {
|
||||||
config?: OpenClawConfig;
|
config?: OpenClawConfig;
|
||||||
|
getConfig?: () => OpenClawConfig | undefined;
|
||||||
agentSessionKey?: string;
|
agentSessionKey?: string;
|
||||||
}) {
|
}) {
|
||||||
return createMemoryTool({
|
return createMemoryTool({
|
||||||
|
|||||||
Reference in New Issue
Block a user