Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion integrations/openclaw/__tests__/e2e/test_sessionCapture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function resetMockImplementations(): void {

type HookHandler = (event: unknown, ctx: unknown) => Promise<unknown> | unknown;

function createApi() {
function createApi(pluginConfig: Record<string, unknown> = {}) {
const handlers = new Map<string, HookHandler[]>();
const api = {
id: "cognee-openclaw",
Expand All @@ -41,6 +41,7 @@ function createApi() {
enableSessions: true,
captureSession: true,
datasetName: "testds",
...pluginConfig,
},
runtime: {},
logger: { info: jest.fn(), warn: jest.fn(), debug: jest.fn() },
Expand Down Expand Up @@ -189,6 +190,26 @@ describe("session capture (traces + QA)", () => {
});

describe("session_end final chain", () => {
it("does not persist clean or crashed sessions when persistence is disabled", async () => {
const { emit } = createApi({ persistSessionsAfterEnd: false });

await emit("gateway_start", { port: 1 }, {});
await flush();
await emit("before_prompt_build", { prompt: "hello there" }, { agentId: "will", sessionId: "s1" });
await flush();

expect(spawnExitWatcher).toHaveBeenCalledWith(expect.objectContaining({
datasetName: undefined,
cogneeSessionId: undefined,
}));

await emit("session_end", { sessionId: "s1", messageCount: 1 }, { agentId: "will", sessionId: "s1" });
await flush(30);

expect(mockImprove).not.toHaveBeenCalled();
expect(mockUnregisterAgent).toHaveBeenCalledWith({ agentSessionName: "s1-will" });
});

it("improves before unregistering and returns without blocking", async () => {
const { emit } = createApi();

Expand Down
12 changes: 6 additions & 6 deletions integrations/openclaw/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1474,11 +1474,11 @@ const memoryCogneePlugin = {
baseUrl: cfg.baseUrl,
apiKey: resolvedApiKey || cfg.apiKey,
pidfilePath: exitWatcherPidfilePath(agentSessionName),
// On unclean gateway death, bridge this session's cache into the
// graph before unregistering. The gateway anchor watcher has no
// session and stays unregister-only.
datasetName: captureDatasetName(ctx.agentId),
cogneeSessionId: cogneeSessionId(ctx.sessionId),
// On unclean gateway death, bridge this session's cache only when
// session persistence is enabled. The gateway anchor watcher has
// no session and stays unregister-only.
datasetName: cfg.persistSessionsAfterEnd ? captureDatasetName(ctx.agentId) : undefined,
cogneeSessionId: cfg.persistSessionsAfterEnd ? cogneeSessionId(ctx.sessionId) : undefined,
logger: api.logger,
}).catch(() => {});
} catch (e: unknown) {
Expand Down Expand Up @@ -1985,7 +1985,7 @@ const memoryCogneePlugin = {
// into THIS session's agent dataset. Must complete BEFORE unregister:
// unregister can drop activeAgents to 0 and, in COGNEE_AGENT_MODE,
// shut the server down mid-pipeline.
if (cfg.improveOnSessionEnd && endSessionId) {
if (cfg.persistSessionsAfterEnd && cfg.improveOnSessionEnd && endSessionId) {
// Let this session's in-flight capture writes land first; improve
// only bridges what is already in the session cache.
await awaitPendingStores(endSessionId);
Expand Down