Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions src/__tests__/subagentAutoBackground.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* item 12: 子代理自动后台化阈值解析单测 (CC 2.1.198/232)
*/
import { describe, expect, it } from "bun:test";
import { getSubagentAutoBackgroundMs } from "../tools/AgentTool/autoBackground.js";

describe("getSubagentAutoBackgroundMs", () => {
const orig = process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS;

it("未设 → 0 (default off, byte-identical 旧行为)", () => {
delete process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS;
expect(getSubagentAutoBackgroundMs()).toBe(0);
});

it("空串 → 0", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "";
expect(getSubagentAutoBackgroundMs()).toBe(0);
});

it("正值 60000 → 60000", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "60000";
expect(getSubagentAutoBackgroundMs()).toBe(60000);
});

it("120000 (对齐 CC 默认) → 120000", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "120000";
expect(getSubagentAutoBackgroundMs()).toBe(120000);
});

it("0 → 0 (显式 off)", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "0";
expect(getSubagentAutoBackgroundMs()).toBe(0);
});

it("负数 → 0 (fail-off)", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "-5";
expect(getSubagentAutoBackgroundMs()).toBe(0);
});

it("非数 → 0 (fail-off)", () => {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = "abc";
expect(getSubagentAutoBackgroundMs()).toBe(0);
});

// 还原
if (orig === undefined) {
delete process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS;
} else {
process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS = orig;
}
});
9 changes: 9 additions & 0 deletions src/tools/AgentTool/AgentTool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ import {
isForkSubagentEnabled,
isInForkChild,
} from "./forkSubagent.js";
import { getSubagentAutoBackgroundMs } from "./autoBackground.js";
import type { AgentDefinition } from "./loadAgentsDir.js";
import {
filterAgentsByMcpRequirements,
Expand Down Expand Up @@ -159,6 +160,14 @@ const isBackgroundTasksDisabled =
// Auto-background agent tasks after this many ms (0 = disabled)
// Enabled by env var OR GrowthBook gate (checked lazily since GB may not be ready at module load)
function getAutoBackgroundMs(): number {
// item 12: FUSION_SUBAGENT_AUTO_BACKGROUND_MS 显式阈值 (并行 item 4
// FUSION_MCP_AUTO_BACKGROUND_MS)。default 0=off, byte-identical 旧行为。
// 设正值 → subagent 运行该毫秒后转后台, 复用 registerAgentForeground
// 定时器→backgroundSignal→mid-run 后台化解阻塞 turn。
const fusionMs = getSubagentAutoBackgroundMs();
if (fusionMs > 0) {
return fusionMs;
}
if (
isEnvTruthy(process.env.CLAUDE_AUTO_BACKGROUND_TASKS) ||
getFeatureValue_CACHED_MAY_BE_STALE("tengu_auto_background_agents", false)
Expand Down
16 changes: 16 additions & 0 deletions src/tools/AgentTool/autoBackground.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// item 12 (CC 2.1.198/232): 子代理自动后台化阈值解析。
// 并行 item 4 FUSION_MCP_AUTO_BACKGROUND_MS (src/services/mcp/client.ts)。
// FUSION_SUBAGENT_AUTO_BACKGROUND_MS 设正值 → subagent 运行该毫秒后转后台,
// 复用 registerAgentForeground 定时器→backgroundSignal→mid-run 后台化解阻塞 turn。
// default 0=off, byte-identical 旧行为。
export function getSubagentAutoBackgroundMs(): number {
const raw = process.env.FUSION_SUBAGENT_AUTO_BACKGROUND_MS;
if (raw === undefined || raw === "") {
return 0;
}
const parsed = parseInt(raw, 10);
if (!Number.isFinite(parsed) || parsed <= 0) {
return 0;
}
return parsed;
}
Loading