refactor(heartbeat): reuse scoped wake helper

This commit is contained in:
Altay
2026-03-03 12:03:34 +03:00
parent 1a6daced1d
commit 0b8c9c0894
3 changed files with 12 additions and 15 deletions

View File

@@ -6,7 +6,7 @@ import { requestHeartbeatNow } from "../infra/heartbeat-wake.js";
import { isDangerousHostEnvVarName } from "../infra/host-env-security.js";
import { findPathKey, mergePathPrepend } from "../infra/path-prepend.js";
import { enqueueSystemEvent } from "../infra/system-events.js";
import { parseAgentSessionKey } from "../routing/session-key.js";
import { scopedHeartbeatWakeOptions } from "../routing/session-key.js";
import type { ProcessSession } from "./bash-process-registry.js";
import type { ExecToolDetails } from "./bash-tools.exec-types.js";
import type { BashSandboxConfig } from "./bash-tools.shared.js";
@@ -241,9 +241,7 @@ function maybeNotifyOnExit(session: ProcessSession, status: "completed" | "faile
: `Exec ${status} (${session.id.slice(0, 8)}, ${exitLabel})`;
enqueueSystemEvent(summary, { sessionKey });
requestHeartbeatNow(
parseAgentSessionKey(sessionKey)
? { reason: `exec:${session.id}:exit`, sessionKey }
: { reason: `exec:${session.id}:exit` },
scopedHeartbeatWakeOptions(sessionKey, { reason: `exec:${session.id}:exit` }),
);
}
@@ -270,11 +268,7 @@ export function emitExecSystemEvent(
return;
}
enqueueSystemEvent(text, { sessionKey, contextKey: opts.contextKey });
requestHeartbeatNow(
parseAgentSessionKey(sessionKey)
? { reason: "exec-event", sessionKey }
: { reason: "exec-event" },
);
requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }));
}
export async function runExecProcess(opts: {

View File

@@ -10,7 +10,7 @@ import { buildOutboundSessionContext } from "../infra/outbound/session-context.j
import { resolveOutboundTarget } from "../infra/outbound/targets.js";
import { registerApnsToken } from "../infra/push-apns.js";
import { enqueueSystemEvent } from "../infra/system-events.js";
import { normalizeMainKey, parseAgentSessionKey } from "../routing/session-key.js";
import { normalizeMainKey, scopedHeartbeatWakeOptions } from "../routing/session-key.js";
import { defaultRuntime } from "../runtime.js";
import { parseMessageWithAttachments } from "./chat-attachments.js";
import { normalizeRpcAttachmentsToChatAttachments } from "./server-methods/attachment-normalize.js";
@@ -577,11 +577,7 @@ export const handleNodeEvent = async (ctx: NodeEventContext, nodeId: string, evt
// Scope wakes only for canonical agent sessions. Synthetic node-* fallback
// keys should keep legacy unscoped behavior so enabled non-main heartbeat
// agents still run when no explicit agent session is provided.
requestHeartbeatNow(
parseAgentSessionKey(sessionKey)
? { reason: "exec-event", sessionKey }
: { reason: "exec-event" },
);
requestHeartbeatNow(scopedHeartbeatWakeOptions(sessionKey, { reason: "exec-event" }));
return;
}
case "push.apns.register": {

View File

@@ -30,6 +30,13 @@ function normalizeToken(value: string | undefined | null): string {
return (value ?? "").trim().toLowerCase();
}
export function scopedHeartbeatWakeOptions<T extends object>(
sessionKey: string,
wakeOptions: T,
): T | (T & { sessionKey: string }) {
return parseAgentSessionKey(sessionKey) ? { ...wakeOptions, sessionKey } : wakeOptions;
}
export function normalizeMainKey(value: string | undefined | null): string {
const trimmed = (value ?? "").trim();
return trimmed ? trimmed.toLowerCase() : DEFAULT_MAIN_KEY;