mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 17:50:20 +00:00
Gateway: harden custom session-store discovery (#44176)
Merged via squash.
Prepared head SHA: 52ebbf5188
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
committed by
GitHub
parent
dc3bb1890b
commit
46f0bfc55b
69
src/acp/runtime/session-meta.test.ts
Normal file
69
src/acp/runtime/session-meta.test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
const hoisted = vi.hoisted(() => {
|
||||
const resolveAllAgentSessionStoreTargetsMock = vi.fn();
|
||||
const loadSessionStoreMock = vi.fn();
|
||||
return {
|
||||
resolveAllAgentSessionStoreTargetsMock,
|
||||
loadSessionStoreMock,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../config/sessions.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../config/sessions.js")>(
|
||||
"../../config/sessions.js",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
resolveAllAgentSessionStoreTargets: (cfg: OpenClawConfig, opts: unknown) =>
|
||||
hoisted.resolveAllAgentSessionStoreTargetsMock(cfg, opts),
|
||||
loadSessionStore: (storePath: string) => hoisted.loadSessionStoreMock(storePath),
|
||||
};
|
||||
});
|
||||
|
||||
const { listAcpSessionEntries } = await import("./session-meta.js");
|
||||
|
||||
describe("listAcpSessionEntries", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("reads ACP sessions from resolved configured store targets", async () => {
|
||||
const cfg = {
|
||||
session: {
|
||||
store: "/custom/sessions/{agentId}.json",
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
hoisted.resolveAllAgentSessionStoreTargetsMock.mockResolvedValue([
|
||||
{
|
||||
agentId: "ops",
|
||||
storePath: "/custom/sessions/ops.json",
|
||||
},
|
||||
]);
|
||||
hoisted.loadSessionStoreMock.mockReturnValue({
|
||||
"agent:ops:acp:s1": {
|
||||
updatedAt: 123,
|
||||
acp: {
|
||||
backend: "acpx",
|
||||
agent: "ops",
|
||||
mode: "persistent",
|
||||
state: "idle",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const entries = await listAcpSessionEntries({ cfg });
|
||||
|
||||
expect(hoisted.resolveAllAgentSessionStoreTargetsMock).toHaveBeenCalledWith(cfg, undefined);
|
||||
expect(hoisted.loadSessionStoreMock).toHaveBeenCalledWith("/custom/sessions/ops.json");
|
||||
expect(entries).toEqual([
|
||||
expect.objectContaining({
|
||||
cfg,
|
||||
storePath: "/custom/sessions/ops.json",
|
||||
sessionKey: "agent:ops:acp:s1",
|
||||
storeSessionKey: "agent:ops:acp:s1",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -1,9 +1,11 @@
|
||||
import path from "node:path";
|
||||
import { resolveAgentSessionDirs } from "../../agents/session-dirs.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import { resolveStateDir } from "../../config/paths.js";
|
||||
import { loadSessionStore, resolveStorePath, updateSessionStore } from "../../config/sessions.js";
|
||||
import {
|
||||
loadSessionStore,
|
||||
resolveAllAgentSessionStoreTargets,
|
||||
resolveStorePath,
|
||||
updateSessionStore,
|
||||
} from "../../config/sessions.js";
|
||||
import {
|
||||
mergeSessionEntry,
|
||||
type SessionAcpMeta,
|
||||
@@ -88,14 +90,17 @@ export function readAcpSessionEntry(params: {
|
||||
|
||||
export async function listAcpSessionEntries(params: {
|
||||
cfg?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<AcpSessionStoreEntry[]> {
|
||||
const cfg = params.cfg ?? loadConfig();
|
||||
const stateDir = resolveStateDir(process.env);
|
||||
const sessionDirs = await resolveAgentSessionDirs(stateDir);
|
||||
const storeTargets = await resolveAllAgentSessionStoreTargets(
|
||||
cfg,
|
||||
params.env ? { env: params.env } : undefined,
|
||||
);
|
||||
const entries: AcpSessionStoreEntry[] = [];
|
||||
|
||||
for (const sessionsDir of sessionDirs) {
|
||||
const storePath = path.join(sessionsDir, "sessions.json");
|
||||
for (const target of storeTargets) {
|
||||
const storePath = target.storePath;
|
||||
let store: Record<string, SessionEntry>;
|
||||
try {
|
||||
store = loadSessionStore(storePath);
|
||||
|
||||
Reference in New Issue
Block a user