diff --git a/apps/desktop-host/src/update-tasks.ts b/apps/desktop-host/src/update-tasks.ts index 106869532f..2b2bbf4a33 100644 --- a/apps/desktop-host/src/update-tasks.ts +++ b/apps/desktop-host/src/update-tasks.ts @@ -45,7 +45,7 @@ export function installDesktopUpdateTaskControl(ctx: Context): (action: 'inspect const liveAgents = agents.list() return liveAgents.some(agent => agent.status === 'running' || agent.inbox.nextTurn.length > 0 || agent.inbox.nextStep.length > 0) - || [undefined, ...liveAgents].some(agent => jobs.list(agent) + || [undefined, ...liveAgents].some(agent => jobs.list(agent?.id) .some(job => job.status === 'running' || job.status === 'stopping')) } } diff --git a/apps/desktop/tests/host-update-tasks.spec.ts b/apps/desktop/tests/host-update-tasks.spec.ts index 0b2a1cd050..b7f8aa3340 100644 --- a/apps/desktop/tests/host-update-tasks.spec.ts +++ b/apps/desktop/tests/host-update-tasks.spec.ts @@ -1,16 +1,17 @@ import { Context } from '@deepseek-ai/cordis' +import { SessionId } from '@deepseek-ai/dsh-session/types' import { Readable } from 'node:stream' import type { IncomingMessage, ServerResponse } from 'node:http' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { installDesktopUpdateTaskControl } from '../../desktop-host/src/update-tasks.ts' -type AgentState = { status: 'idle' | 'running'; inbox: { nextTurn: object[]; nextStep: object[] } } +type AgentState = { id: SessionId; status: 'idle' | 'running'; inbox: { nextTurn: object[]; nextStep: object[] } } type JobState = { status: 'running' | 'stopping' | 'finished' } let ctx: Context let inspect: ReturnType const agents: AgentState[] = [] -const jobs = new Map() +const jobs = new Map() beforeEach(() => { agents.length = 0 @@ -18,13 +19,13 @@ beforeEach(() => { ctx = new Context() // Narrow service doubles exercise the inspector against a real Cordis event lifecycle. ctx.provide('agents', { list: () => agents } as unknown as Context['agents']) - ctx.provide('jobs', { list: (agent?: AgentState) => jobs.get(agent) ?? [] } as unknown as Context['jobs']) + ctx.provide('jobs', { list: (sessionId?: SessionId) => jobs.get(sessionId) ?? [] } as unknown as Context['jobs']) inspect = installDesktopUpdateTaskControl(ctx) }) afterEach(async () => { await ctx.fiber.dispose() }) -function idleAgent(): AgentState { return { status: 'idle', inbox: { nextTurn: [], nextStep: [] } } } +function idleAgent(): AgentState { return { id: SessionId('update-task-owner'), status: 'idle', inbox: { nextTurn: [], nextStep: [] } } } function request(next: () => Promise) { const incoming = Readable.from([]) as unknown as IncomingMessage @@ -48,7 +49,7 @@ describe('Desktop Host update task protection', () => { it.each(['running', 'stopping'] as const)('counts global and agent-owned %s jobs', async (status) => { const agent = idleAgent() agents.push(agent) - for (const owner of [undefined, agent]) { + for (const owner of [undefined, agent.id]) { jobs.set(owner, [{ status }]) expect(await inspect('inspect')).toBe(true) jobs.set(owner, [{ status: 'finished' }])