

























@@ -1885,7 +1885,7 @@ describe("task-registry", () => {
18851885});
18861886});
188718871888-it("does not mark codex-native subagent tasks lost when they have no OpenClaw child session", async () => {
1888+it("keeps fresh childless codex-native subagent tasks live", async () => {
18891889await withTaskRegistryTempDir(async (root) => {
18901890process.env.OPENCLAW_STATE_DIR = root;
18911891resetTaskRegistryForTests();
@@ -1914,14 +1914,85 @@ describe("task-registry", () => {
19141914cleanupStamped: 0,
19151915pruned: 0,
19161916});
1917-expect(getTaskById(task.taskId)).toEqual({
1918- ...task,
1919-createdAt: now - 10 * 60_000,
1917+expectRecordFields(requireTaskById(task.taskId), {
1918+status: "running",
19201919lastEventAt: now - 10 * 60_000,
19211920});
19221921});
19231922});
192419231924+it("marks stale childless codex-native subagent tasks lost", async () => {
1925+await withTaskRegistryTempDir(async (root) => {
1926+process.env.OPENCLAW_STATE_DIR = root;
1927+resetTaskRegistryForTests();
1928+const now = Date.now();
1929+1930+const task = createTaskRecord({
1931+runtime: "subagent",
1932+taskKind: "codex-native",
1933+ownerKey: "agent:main:main",
1934+scopeKind: "session",
1935+sourceId: "codex-thread:child-thread",
1936+runId: "codex-thread:child-thread",
1937+task: "Codex native child",
1938+status: "running",
1939+deliveryStatus: "not_applicable",
1940+notifyPolicy: "silent",
1941+});
1942+setTaskTimingById({
1943+taskId: task.taskId,
1944+lastEventAt: now - 31 * 60_000,
1945+});
1946+1947+expect(await runTaskRegistryMaintenance()).toEqual({
1948+reconciled: 1,
1949+recovered: 0,
1950+cleanupStamped: 0,
1951+pruned: 0,
1952+});
1953+expectRecordFields(requireTaskById(task.taskId), {
1954+status: "lost",
1955+error: "Codex native subagent stopped reporting progress",
1956+});
1957+});
1958+});
1959+1960+it("does not mark unrelated childless subagent tasks lost", async () => {
1961+await withTaskRegistryTempDir(async (root) => {
1962+process.env.OPENCLAW_STATE_DIR = root;
1963+resetTaskRegistryForTests();
1964+const now = Date.now();
1965+1966+const task = createTaskRecord({
1967+runtime: "subagent",
1968+taskKind: "codex-native",
1969+ownerKey: "agent:main:main",
1970+scopeKind: "session",
1971+sourceId: "other-runtime:child-thread",
1972+runId: "other-runtime:child-thread",
1973+task: "Non-Codex childless row",
1974+status: "running",
1975+deliveryStatus: "not_applicable",
1976+notifyPolicy: "silent",
1977+});
1978+setTaskTimingById({
1979+taskId: task.taskId,
1980+lastEventAt: now - 31 * 60_000,
1981+});
1982+1983+expect(await runTaskRegistryMaintenance()).toEqual({
1984+reconciled: 0,
1985+recovered: 0,
1986+cleanupStamped: 0,
1987+pruned: 0,
1988+});
1989+expectRecordFields(requireTaskById(task.taskId), {
1990+status: "running",
1991+lastEventAt: now - 31 * 60_000,
1992+});
1993+});
1994+});
1995+19251996it("closes terminal parent-owned one-shot ACP sessions during maintenance", async () => {
19261997await withTaskRegistryTempDir(async (root) => {
19271998process.env.OPENCLAW_STATE_DIR = root;
@@ -3168,7 +3239,7 @@ describe("task-registry", () => {
31683239});
31693240});
317032413171-it("does not route codex-native task cancellation through OpenClaw subagent sessions", async () => {
3242+it("cancels childless codex-native tasks without routing through OpenClaw subagent sessions", async () => {
31723243await withTaskRegistryTempDir(async (root) => {
31733244process.env.OPENCLAW_STATE_DIR = root;
31743245resetTaskRegistryForTests();
@@ -3190,6 +3261,44 @@ describe("task-registry", () => {
31903261taskId: task.taskId,
31913262});
319232633264+expectRecordFields(result, {
3265+found: true,
3266+cancelled: true,
3267+});
3268+expectRecordFields(result.task, {
3269+taskId: task.taskId,
3270+status: "cancelled",
3271+endedAt: expect.any(Number),
3272+lastEventAt: expect.any(Number),
3273+cleanupAfter: expect.any(Number),
3274+error: "Cancelled by operator.",
3275+});
3276+expect(hoisted.killSubagentRunAdminMock).not.toHaveBeenCalled();
3277+});
3278+});
3279+3280+it("does not cancel unrelated childless subagent tasks", async () => {
3281+await withTaskRegistryTempDir(async (root) => {
3282+process.env.OPENCLAW_STATE_DIR = root;
3283+resetTaskRegistryForTests();
3284+const task = createTaskRecord({
3285+runtime: "subagent",
3286+taskKind: "codex-native",
3287+ownerKey: "agent:main:main",
3288+scopeKind: "session",
3289+sourceId: "other-runtime:child-thread",
3290+runId: "other-runtime:child-thread",
3291+task: "Non-Codex childless row",
3292+status: "running",
3293+deliveryStatus: "not_applicable",
3294+notifyPolicy: "silent",
3295+});
3296+3297+const result = await cancelTaskById({
3298+cfg: {} as never,
3299+taskId: task.taskId,
3300+});
3301+31933302expect(result).toEqual({
31943303found: true,
31953304cancelled: false,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。