fix(hooks): prefer reset workspace in session-memory

This commit is contained in:
Altay
2026-03-08 18:32:53 +03:00
parent b20b16965c
commit 810d614cb8
4 changed files with 68 additions and 11 deletions

View File

@@ -63,6 +63,7 @@ export async function emitResetCommandHooks(params: {
previousSessionEntry: params.previousSessionEntry,
commandSource: params.command.surface,
senderId: params.command.senderId,
workspaceDir: params.workspaceDir,
cfg: params.cfg, // Pass config for LLM slug generation
});
await triggerInternalHook(hookEvent);

View File

@@ -1138,6 +1138,9 @@ describe("handleCommands hooks", () => {
type: "command",
action: "new",
sessionKey: "agent:main:telegram:direct:123",
context: expect.objectContaining({
workspaceDir: testWorkspaceDir,
}),
}),
);
spy.mockRestore();

View File

@@ -65,15 +65,23 @@ async function runNewWithPreviousSessionEntry(params: {
previousSessionEntry: { sessionId: string; sessionFile?: string };
cfg?: OpenClawConfig;
action?: "new" | "reset";
sessionKey?: string;
workspaceDirOverride?: string;
}): Promise<{ files: string[]; memoryContent: string }> {
const event = createHookEvent("command", params.action ?? "new", "agent:main:main", {
cfg:
params.cfg ??
({
agents: { defaults: { workspace: params.tempDir } },
} satisfies OpenClawConfig),
previousSessionEntry: params.previousSessionEntry,
});
const event = createHookEvent(
"command",
params.action ?? "new",
params.sessionKey ?? "agent:main:main",
{
cfg:
params.cfg ??
({
agents: { defaults: { workspace: params.tempDir } },
} satisfies OpenClawConfig),
previousSessionEntry: params.previousSessionEntry,
...(params.workspaceDirOverride ? { workspaceDir: params.workspaceDirOverride } : {}),
},
);
await handler(event);
@@ -242,6 +250,45 @@ describe("session-memory hook", () => {
expect(memoryContent).toContain("assistant: Captured before reset");
});
it("prefers workspaceDir from hook context when sessionKey points at main", async () => {
const mainWorkspace = await createCaseWorkspace("workspace-main");
const naviWorkspace = await createCaseWorkspace("workspace-navi");
const naviSessionsDir = path.join(naviWorkspace, "sessions");
await fs.mkdir(naviSessionsDir, { recursive: true });
const sessionFile = await writeWorkspaceFile({
dir: naviSessionsDir,
name: "navi-session.jsonl",
content: createMockSessionContent([
{ role: "user", content: "Remember this under Navi" },
{ role: "assistant", content: "Stored in the bound workspace" },
]),
});
const { files, memoryContent } = await runNewWithPreviousSessionEntry({
tempDir: naviWorkspace,
cfg: {
agents: {
defaults: { workspace: mainWorkspace },
list: {
navi: { workspace: naviWorkspace },
},
},
} satisfies OpenClawConfig,
sessionKey: "agent:main:main",
workspaceDirOverride: naviWorkspace,
previousSessionEntry: {
sessionId: "navi-session",
sessionFile,
},
});
expect(files.length).toBe(1);
expect(memoryContent).toContain("user: Remember this under Navi");
expect(memoryContent).toContain("assistant: Stored in the bound workspace");
await expect(fs.access(path.join(mainWorkspace, "memory"))).rejects.toThrow();
});
it("filters out non-message entries (tool calls, system)", async () => {
// Create session with mixed entry types
const sessionContent = createMockSessionContent([

View File

@@ -182,10 +182,16 @@ const saveSessionToMemory: HookHandler = async (event) => {
const context = event.context || {};
const cfg = context.cfg as OpenClawConfig | undefined;
const contextWorkspaceDir =
typeof context.workspaceDir === "string" && context.workspaceDir.trim().length > 0
? context.workspaceDir
: undefined;
const agentId = resolveAgentIdFromSessionKey(event.sessionKey);
const workspaceDir = cfg
? resolveAgentWorkspaceDir(cfg, agentId)
: path.join(resolveStateDir(process.env, os.homedir), "workspace");
const workspaceDir =
contextWorkspaceDir ||
(cfg
? resolveAgentWorkspaceDir(cfg, agentId)
: path.join(resolveStateDir(process.env, os.homedir), "workspace"));
const memoryDir = path.join(workspaceDir, "memory");
await fs.mkdir(memoryDir, { recursive: true });