mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-30 09:11:20 +00:00
refactor(sessions): add explicit merge activity policies
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { acquireSessionWriteLock } from "../../agents/session-write-lock.js";
|
||||
@@ -39,6 +38,7 @@ import {
|
||||
import { applySessionStoreMigrations } from "./store-migrations.js";
|
||||
import {
|
||||
mergeSessionEntry,
|
||||
mergeSessionEntryPreserveActivity,
|
||||
normalizeSessionRuntimeModelFields,
|
||||
type SessionEntry,
|
||||
} from "./types.js";
|
||||
@@ -738,14 +738,9 @@ export async function recordSessionMetaFromInbound(params: {
|
||||
return null;
|
||||
}
|
||||
const next = existing
|
||||
? normalizeSessionRuntimeModelFields({
|
||||
...existing,
|
||||
...patch,
|
||||
// Inbound metadata updates must not refresh activity timestamps;
|
||||
// idle reset evaluation relies on updatedAt from actual session turns.
|
||||
sessionId: existing.sessionId ?? crypto.randomUUID(),
|
||||
updatedAt: existing.updatedAt ?? Date.now(),
|
||||
})
|
||||
? // Inbound metadata updates must not refresh activity timestamps;
|
||||
// idle reset evaluation relies on updatedAt from actual session turns.
|
||||
mergeSessionEntryPreserveActivity(existing, patch)
|
||||
: mergeSessionEntry(existing, patch);
|
||||
store[resolved.normalizedKey] = next;
|
||||
for (const legacyKey of resolved.legacyKeys) {
|
||||
|
||||
@@ -225,12 +225,31 @@ export function setSessionRuntimeModel(
|
||||
return true;
|
||||
}
|
||||
|
||||
export function mergeSessionEntry(
|
||||
export type SessionEntryMergePolicy = "touch-activity" | "preserve-activity";
|
||||
|
||||
type MergeSessionEntryOptions = {
|
||||
policy?: SessionEntryMergePolicy;
|
||||
now?: number;
|
||||
};
|
||||
|
||||
function resolveMergedUpdatedAt(
|
||||
existing: SessionEntry | undefined,
|
||||
patch: Partial<SessionEntry>,
|
||||
options?: MergeSessionEntryOptions,
|
||||
): number {
|
||||
if (options?.policy === "preserve-activity" && existing) {
|
||||
return existing.updatedAt ?? patch.updatedAt ?? options.now ?? Date.now();
|
||||
}
|
||||
return Math.max(existing?.updatedAt ?? 0, patch.updatedAt ?? 0, options?.now ?? Date.now());
|
||||
}
|
||||
|
||||
export function mergeSessionEntryWithPolicy(
|
||||
existing: SessionEntry | undefined,
|
||||
patch: Partial<SessionEntry>,
|
||||
options?: MergeSessionEntryOptions,
|
||||
): SessionEntry {
|
||||
const sessionId = patch.sessionId ?? existing?.sessionId ?? crypto.randomUUID();
|
||||
const updatedAt = Math.max(existing?.updatedAt ?? 0, patch.updatedAt ?? 0, Date.now());
|
||||
const updatedAt = resolveMergedUpdatedAt(existing, patch, options);
|
||||
if (!existing) {
|
||||
return normalizeSessionRuntimeModelFields({ ...patch, sessionId, updatedAt });
|
||||
}
|
||||
@@ -248,6 +267,22 @@ export function mergeSessionEntry(
|
||||
return normalizeSessionRuntimeModelFields(next);
|
||||
}
|
||||
|
||||
export function mergeSessionEntry(
|
||||
existing: SessionEntry | undefined,
|
||||
patch: Partial<SessionEntry>,
|
||||
): SessionEntry {
|
||||
return mergeSessionEntryWithPolicy(existing, patch);
|
||||
}
|
||||
|
||||
export function mergeSessionEntryPreserveActivity(
|
||||
existing: SessionEntry | undefined,
|
||||
patch: Partial<SessionEntry>,
|
||||
): SessionEntry {
|
||||
return mergeSessionEntryWithPolicy(existing, patch, {
|
||||
policy: "preserve-activity",
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveFreshSessionTotalTokens(
|
||||
entry?: Pick<SessionEntry, "totalTokens" | "totalTokensFresh"> | null,
|
||||
): number | undefined {
|
||||
|
||||
Reference in New Issue
Block a user