feat(FN-4394): complete Step 3 — add heartbeat scope resolver helpers
Fusion-Task-Id: FN-4394 Fusion-Task-Lineage: 1e7ad660-2cd2-40ba-b7b8-7ef552c6fa13
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type { Agent, ProjectSettings } from "@fusion/core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveHeartbeatScopeDisciplineMode, selectHeartbeatProcedure } from "../heartbeat-procedure-resolver.js";
|
||||
|
||||
const project = (mode?: ProjectSettings["heartbeatScopeDiscipline"]) => ({ heartbeatScopeDiscipline: mode });
|
||||
const agent = (mode?: unknown) => ({ runtimeConfig: mode === undefined ? {} : { heartbeatScopeDiscipline: mode } }) as Pick<Agent, "runtimeConfig">;
|
||||
|
||||
describe("resolveHeartbeatScopeDisciplineMode", () => {
|
||||
it.each(["strict", "lite", "off"] as const)("prefers agent override: %s", (mode) => {
|
||||
expect(resolveHeartbeatScopeDisciplineMode(project("strict"), agent(mode))).toBe(mode);
|
||||
});
|
||||
|
||||
it.each(["strict", "lite", "off"] as const)("uses project mode when agent unset: %s", (mode) => {
|
||||
expect(resolveHeartbeatScopeDisciplineMode(project(mode), agent(undefined))).toBe(mode);
|
||||
});
|
||||
|
||||
it("falls through invalid agent mode to project mode", () => {
|
||||
expect(resolveHeartbeatScopeDisciplineMode(project("lite"), agent("invalid"))).toBe("lite");
|
||||
});
|
||||
|
||||
it("falls through invalid project mode to strict default", () => {
|
||||
expect(resolveHeartbeatScopeDisciplineMode(project("invalid" as never), agent(undefined))).toBe("strict");
|
||||
});
|
||||
|
||||
it("defaults to strict when unset", () => {
|
||||
expect(resolveHeartbeatScopeDisciplineMode(undefined, undefined)).toBe("strict");
|
||||
});
|
||||
});
|
||||
|
||||
describe("selectHeartbeatProcedure", () => {
|
||||
const procedures = {
|
||||
task: { strict: "task-strict", lite: "task-lite", off: "task-off" },
|
||||
noTask: { strict: "no-task-strict", lite: "no-task-lite", off: "no-task-off" },
|
||||
} as const;
|
||||
|
||||
it.each([
|
||||
["strict", false, "task-strict"],
|
||||
["lite", false, "task-lite"],
|
||||
["off", false, "task-off"],
|
||||
["strict", true, "no-task-strict"],
|
||||
["lite", true, "no-task-lite"],
|
||||
["off", true, "no-task-off"],
|
||||
] as const)("maps mode=%s isNoTask=%s", (mode, isNoTaskRun, expected) => {
|
||||
expect(selectHeartbeatProcedure(mode, isNoTaskRun, procedures)).toBe(expected);
|
||||
});
|
||||
});
|
||||
36
packages/engine/src/heartbeat-procedure-resolver.ts
Normal file
36
packages/engine/src/heartbeat-procedure-resolver.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { Agent, HeartbeatScopeDisciplineMode, ProjectSettings } from "@fusion/core";
|
||||
|
||||
const VALID_MODES: readonly HeartbeatScopeDisciplineMode[] = ["strict", "lite", "off"] as const;
|
||||
|
||||
function isHeartbeatScopeDisciplineMode(value: unknown): value is HeartbeatScopeDisciplineMode {
|
||||
return typeof value === "string" && (VALID_MODES as readonly string[]).includes(value);
|
||||
}
|
||||
|
||||
export function resolveHeartbeatScopeDisciplineMode(
|
||||
projectSettings: Pick<ProjectSettings, "heartbeatScopeDiscipline"> | undefined,
|
||||
agent: Pick<Agent, "runtimeConfig"> | undefined,
|
||||
): HeartbeatScopeDisciplineMode {
|
||||
const runtimeConfig = agent?.runtimeConfig as Record<string, unknown> | undefined;
|
||||
const agentMode = runtimeConfig?.heartbeatScopeDiscipline;
|
||||
if (isHeartbeatScopeDisciplineMode(agentMode)) {
|
||||
return agentMode;
|
||||
}
|
||||
|
||||
const projectMode = projectSettings?.heartbeatScopeDiscipline;
|
||||
if (isHeartbeatScopeDisciplineMode(projectMode)) {
|
||||
return projectMode;
|
||||
}
|
||||
|
||||
return "strict";
|
||||
}
|
||||
|
||||
export function selectHeartbeatProcedure<T>(
|
||||
mode: HeartbeatScopeDisciplineMode,
|
||||
isNoTaskRun: boolean,
|
||||
procedures: {
|
||||
task: Record<HeartbeatScopeDisciplineMode, T>;
|
||||
noTask: Record<HeartbeatScopeDisciplineMode, T>;
|
||||
},
|
||||
): T {
|
||||
return isNoTaskRun ? procedures.noTask[mode] : procedures.task[mode];
|
||||
}
|
||||
Reference in New Issue
Block a user