Gateway: prefer newest session entries in merge (#1823)

This commit is contained in:
Shadow
2026-01-25 22:40:00 -06:00
parent 49ef62255e
commit 34ce004151
2 changed files with 38 additions and 11 deletions

View File

@@ -18,6 +18,7 @@ Status: unreleased.
- Docs: credit both contributors for Control UI refresh. (#1852) Thanks @EnzeD.
- Onboarding: add Venice API key to non-interactive flow. (#1893) Thanks @jonisjongithub.
- Tlon: format thread reply IDs as @ud. (#1837) Thanks @wca4a.
- Gateway: prefer newest session metadata when combining stores. (#1823) Thanks @emanuelst.
- CI: increase Node heap size for macOS checks. (#1890) Thanks @realZachi.
- macOS: avoid crash when rendering code blocks by bumping Textual to 0.3.1. (#2033) Thanks @garricn.
- Browser: fall back to URL matching for extension relay target resolution. (#1999) Thanks @jonit-dev.

View File

@@ -381,6 +381,31 @@ export function resolveGatewaySessionStoreTarget(params: { cfg: ClawdbotConfig;
};
}
// Merge with existing entry based on latest timestamp to ensure data consistency and avoid overwriting with less complete data.
function mergeSessionEntryIntoCombined(params: {
combined: Record<string, SessionEntry>;
entry: SessionEntry;
agentId: string;
canonicalKey: string;
}) {
const { combined, entry, agentId, canonicalKey } = params;
const existing = combined[canonicalKey];
if (existing && (existing.updatedAt ?? 0) > (entry.updatedAt ?? 0)) {
combined[canonicalKey] = {
...entry,
...existing,
spawnedBy: canonicalizeSpawnedByForAgent(agentId, existing.spawnedBy ?? entry.spawnedBy),
};
} else {
combined[canonicalKey] = {
...existing,
...entry,
spawnedBy: canonicalizeSpawnedByForAgent(agentId, entry.spawnedBy ?? existing?.spawnedBy),
};
}
}
export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): {
storePath: string;
store: Record<string, SessionEntry>;
@@ -393,10 +418,12 @@ export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): {
const combined: Record<string, SessionEntry> = {};
for (const [key, entry] of Object.entries(store)) {
const canonicalKey = canonicalizeSessionKeyForAgent(defaultAgentId, key);
combined[canonicalKey] = {
...entry,
spawnedBy: canonicalizeSpawnedByForAgent(defaultAgentId, entry.spawnedBy),
};
mergeSessionEntryIntoCombined({
combined,
entry,
agentId: defaultAgentId,
canonicalKey,
});
}
return { storePath, store: combined };
}
@@ -408,13 +435,12 @@ export function loadCombinedSessionStoreForGateway(cfg: ClawdbotConfig): {
const store = loadSessionStore(storePath);
for (const [key, entry] of Object.entries(store)) {
const canonicalKey = canonicalizeSessionKeyForAgent(agentId, key);
// Merge with existing entry if present (avoid overwriting with less complete data)
const existing = combined[canonicalKey];
combined[canonicalKey] = {
...existing,
...entry,
spawnedBy: canonicalizeSpawnedByForAgent(agentId, entry.spawnedBy ?? existing?.spawnedBy),
};
mergeSessionEntryIntoCombined({
combined,
entry,
agentId,
canonicalKey,
});
}
}