feat(FN-2115): add heartbeat multiplier and agent interval controls

- Add heartbeatIntervalMultiplier to shared settings schema/types with settings parity coverage
- Apply heartbeat multiplier in engine scheduling logic while preserving explicit per-agent interval behavior
- Add Settings modal and Agents view controls for heartbeat multiplier and per-agent interval overrides, including new styling
- Expand dashboard and engine test coverage for multiplier/heartbeat controls and document the new setting
This commit is contained in:
Fusion
2026-04-19 06:40:03 -07:00
committed by gsxdsm
parent a70ff39e31
commit a4ce10a1c5
12 changed files with 559 additions and 43 deletions

View File

@@ -49,9 +49,14 @@ describe("settings key parity", () => {
expect(isGlobalSettingsKey("themeMode")).toBe(true);
expect(isGlobalSettingsKey("maxConcurrent")).toBe(false);
expect(isProjectSettingsKey("maxConcurrent")).toBe(true);
expect(isProjectSettingsKey("heartbeatMultiplier")).toBe(true);
expect(isProjectSettingsKey("themeMode")).toBe(false);
});
it("includes heartbeatMultiplier in project defaults", () => {
expect(DEFAULT_PROJECT_SETTINGS.heartbeatMultiplier).toBe(1);
});
it("No key appears in both GLOBAL_SETTINGS_KEYS and PROJECT_SETTINGS_KEYS", () => {
const projectKeySet = new Set(PROJECT_SETTINGS_KEYS as readonly string[]);
const overlap = (GLOBAL_SETTINGS_KEYS as readonly string[]).filter((key) => projectKeySet.has(key));

View File

@@ -59,6 +59,7 @@ export const DEFAULT_PROJECT_SETTINGS = {
globalMaxConcurrent: 4,
maxWorktrees: 4,
pollIntervalMs: 15000,
heartbeatMultiplier: 1,
groupOverlappingFiles: true,
autoMerge: true,
mergeStrategy: "direct",

View File

@@ -1033,6 +1033,10 @@ export interface ProjectSettings {
globalMaxConcurrent?: number;
maxWorktrees: number;
pollIntervalMs: number;
/** Global multiplier applied to all agent heartbeat intervals.
* For example, 0.5 halves the interval (faster checks), 2.0 doubles it (slower checks).
* Must be > 0. Default: 1 (no change). */
heartbeatMultiplier?: number;
groupOverlappingFiles: boolean;
autoMerge: boolean;
/** How completed in-review tasks should be finalized when autoMerge is enabled.