mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 02:20:38 +09:00
Merge pull request #2065 from edimuj/fix/heartbeat-session-reuse
fix: preserve session continuity for timer/heartbeat wakes
This commit is contained in:
commit
9f1bb350fe
2 changed files with 61 additions and 2 deletions
|
|
@ -607,6 +607,14 @@ function parseIssueAssigneeAdapterOverrides(
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthetic task key for timer/heartbeat wakes that have no issue context.
|
||||
* This allows timer wakes to participate in the `agentTaskSessions` system
|
||||
* and benefit from robust session resume, instead of relying solely on the
|
||||
* simpler `agentRuntimeState.sessionId` fallback.
|
||||
*/
|
||||
const HEARTBEAT_TASK_KEY = "__heartbeat__";
|
||||
|
||||
function deriveTaskKey(
|
||||
contextSnapshot: Record<string, unknown> | null | undefined,
|
||||
payload: Record<string, unknown> | null | undefined,
|
||||
|
|
@ -622,6 +630,28 @@ function deriveTaskKey(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended task key derivation that falls back to a stable synthetic key
|
||||
* for timer/heartbeat wakes. This ensures timer wakes can resume their
|
||||
* previous session via `agentTaskSessions` instead of starting fresh.
|
||||
*
|
||||
* The synthetic key is only used when:
|
||||
* - No explicit task/issue key exists in the context
|
||||
* - The wake source is "timer" (scheduled heartbeat)
|
||||
*/
|
||||
export function deriveTaskKeyWithHeartbeatFallback(
|
||||
contextSnapshot: Record<string, unknown> | null | undefined,
|
||||
payload: Record<string, unknown> | null | undefined,
|
||||
) {
|
||||
const explicit = deriveTaskKey(contextSnapshot, payload);
|
||||
if (explicit) return explicit;
|
||||
|
||||
const wakeSource = readNonEmptyString(contextSnapshot?.wakeSource);
|
||||
if (wakeSource === "timer") return HEARTBEAT_TASK_KEY;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function shouldResetTaskSessionForWake(
|
||||
contextSnapshot: Record<string, unknown> | null | undefined,
|
||||
) {
|
||||
|
|
@ -1595,7 +1625,7 @@ export function heartbeatService(db: Db) {
|
|||
) {
|
||||
const contextSnapshot = parseObject(run.contextSnapshot);
|
||||
const issueId = readNonEmptyString(contextSnapshot.issueId);
|
||||
const taskKey = deriveTaskKey(contextSnapshot, null);
|
||||
const taskKey = deriveTaskKeyWithHeartbeatFallback(contextSnapshot, null);
|
||||
const sessionBefore = await resolveSessionBeforeForWakeup(agent, taskKey);
|
||||
const retryContextSnapshot = {
|
||||
...contextSnapshot,
|
||||
|
|
@ -2050,7 +2080,7 @@ export function heartbeatService(db: Db) {
|
|||
|
||||
const runtime = await ensureRuntimeState(agent);
|
||||
const context = parseObject(run.contextSnapshot);
|
||||
const taskKey = deriveTaskKey(context, null);
|
||||
const taskKey = deriveTaskKeyWithHeartbeatFallback(context, null);
|
||||
const sessionCodec = getAdapterSessionCodec(agent.adapterType);
|
||||
const issueId = readNonEmptyString(context.issueId);
|
||||
const issueContext = issueId
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue