test(activity): cover the owner arm and the pwsh outer observation catch

The coverage lanes flag four uncovered locations after the master merge:
the spec.owner spread in tool-bash/tool-pwsh observe, the workflow mirror's
owner spread, and tool-pwsh's outer observation catch. The covering tests
existed only on the stacked job-kill branch; give this branch its own:
an owned background run per shell asserting the fenced ownerSession row,
the owned workflow mirror run, and a throwing open() through the pwsh
outer catch. The windows-only file-reference-local gap reproduces on
master's own windows lane at the merge point and stays upstream.
This commit is contained in:
Yichen Jiang committed 2026-08-27 21:40:44 +08:00
1 parent ab75fe2bb6
commit 053979cdec
3 files changed
+111

No files matched your search

@@ -4,9 +4,11 @@ import { join } from 'node:path'
import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import { ToolCallId } from '@deepseek-ai/dsh-llm'
import { SessionId } from '@deepseek-ai/dsh-session'
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
import ToolRuntime from '@deepseek-ai/dsh-tools'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import LocalJobRegistry from '@deepseek-ai/dsh-jobs-local'
import * as ToolTasks from '@deepseek-ai/dsh-tool-jobs'
import LocalActivityRegistry from '@deepseek-ai/dsh-activity-local'
@@ -262,3 +264,28 @@ describe('background bash observation', () => {
expect(read.snapshot.status).toBe('completed')
})
})
describe('owned background observation', () => {
it('mirrors an owned background run under the owning session', async () => {
const ctx = await setup()
const owner = {
id: SessionId('observe-owner'),
session: { id: SessionId('observe-owner'), header: { cwd: process.cwd() } },
status: 'idle',
ctx,
} as unknown as Agent
ctx.agents.register(owner)
await ctx.tools.execute({
signal: testToolSignal,
callId: ToolCallId('observe-owned-1'),
name: 'bash',
arguments: { command: 'echo owned', description: 'test command', run_in_background: true },
agent: owner,
})
const job = ctx.jobs.list(owner)[0]
expect(job).toBeDefined()
const row = await until(() => ctx.activities.list(owner).find(item => item.correlation?.jobId === job!.id))
expect(row.ownerSession).toBe(owner.id)
await until(() => ctx.jobs.get(job!.id, owner).status === 'completed' ? true : undefined)
})
})
@@ -1,9 +1,11 @@
import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import { ToolCallId } from '@deepseek-ai/dsh-llm'
import { SessionId } from '@deepseek-ai/dsh-session'
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
import ToolRuntime from '@deepseek-ai/dsh-tools'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import LocalJobRegistry from '@deepseek-ai/dsh-jobs-local'
import * as ToolTasks from '@deepseek-ai/dsh-tool-jobs'
import LocalActivityRegistry from '@deepseek-ai/dsh-activity-local'
@@ -216,3 +218,62 @@ describe('background pwsh observation', () => {
expect(ctx.activities.get(row.id).outputTotal).toBe(0)
})
})
describe('owned and degraded observation (pwsh)', () => {
it('mirrors an owned background run under the owning session', async () => {
const { ctx, pwsh } = await setup()
const owner = {
id: SessionId('pwsh-observe-owner'),
session: { id: SessionId('pwsh-observe-owner'), header: { cwd: process.cwd() } },
status: 'idle',
ctx,
} as unknown as Agent
ctx.agents.register(owner)
const scripted = observableProcess()
pwsh.backgroundHandler = () => scripted.proc
await ctx.tools.execute({
signal: testToolSignal,
callId: ToolCallId('pwsh-observe-owned'),
name: 'pwsh',
arguments: { command: 'Get-Slow', description: 'test command', run_in_background: true },
agent: owner,
})
const job = ctx.jobs.list(owner)[0]
expect(job).toBeDefined()
const row = await until(() => ctx.activities.list(owner).find(item => item.correlation?.jobId === job!.id))
expect(row.ownerSession).toBe(owner.id)
scripted.finish()
await until(() => ctx.jobs.get(job!.id, owner).status === 'completed' ? true : undefined)
})
it('swallows a throwing observation registry and keeps the job alive', async () => {
// The FakePwsh composition with a synchronously throwing open(): the
// failure lands in the outer observation catch and the job runs on.
const ctx = new Context()
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
await ctx.plugin(LocalJobRegistry)
await ctx.plugin(ToolTasks)
await ctx.plugin({
name: 'broken-activities-probe',
apply(child: Context) {
child.provide('activities', { open() { throw new Error('observation boom') } })
},
})
await ctx.plugin(BashEnvPlugin)
await ctx.plugin(FakePwsh)
const warn = vi.fn()
ctx.logger.warn = warn as never
await ctx.plugin(ToolPwsh, { activityPollMs: 5 })
const pwsh = ctx.shell as FakePwsh
const scripted = observableProcess()
pwsh.backgroundHandler = () => scripted.proc
await call(ctx, { command: 'Get-Slow', description: 'test command', run_in_background: true })
expect(warn).toHaveBeenCalledWith(expect.stringContaining('activity observation unavailable'))
const job = ctx.jobs.list()[0]
expect(job?.status).toBe('running')
scripted.finish()
await until(() => ctx.jobs.get(job!.id).status === 'completed' ? true : undefined)
})
})
@@ -1,6 +1,9 @@
import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import LocalActivityRegistry from '@deepseek-ai/dsh-activity-local'
import { SessionId } from '@deepseek-ai/dsh-session'
import type { WorkflowRun, WorkflowRunId, WorkflowRunInfo } from '@deepseek-ai/dsh-workflow'
import { createWorkflowActivityMirror } from '../src/activity.ts'
@@ -45,6 +48,26 @@ describe('workflow activity mirror', () => {
expect(ctx.activities.get(row!.id).status).toBe('completed')
})
it('opens an owned run under the owning agent session', async () => {
const ctx = new Context()
await ctx.plugin(AgentRegistry)
await ctx.plugin(LocalActivityRegistry)
const owner = {
id: SessionId('workflow-owner'),
session: { id: SessionId('workflow-owner') },
status: 'idle',
ctx,
} as unknown as Agent
ctx.agents.register(owner)
const mirror = createWorkflowActivityMirror(ctx)
const { run } = runStub('run-owned')
mirror.start(run, owner)
// The owned row is fenced to its owner's view.
const row = ctx.activities.list(owner)[0]
expect(row?.ownerSession).toBe(owner.id)
mirror.finish(run.id, 'completed')
})
it('maps cancelled and error stops, and ends an abandoned run as killed', async () => {
const ctx = new Context()
await ctx.plugin(LocalActivityRegistry)