mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(bash): classify signal-terminated background processes
This commit is contained in:
@@ -175,10 +175,12 @@ export class LocalBashExecutor extends BashExecutor {
|
||||
exitCode: null,
|
||||
signal: null,
|
||||
done: running.done.then((outcome) => {
|
||||
// Abort-killed processes report as killed, not completed. Background
|
||||
// runs forward only the upstream signal (no timeout), so its aborted
|
||||
// state is the authoritative "was this cancelled" signal.
|
||||
if (proc.status === 'running') proc.status = spec.signal?.aborted === true ? 'killed' : 'completed'
|
||||
// Caller-aborted and signal-terminated processes report as killed, not
|
||||
// completed. The signal check also covers commands that terminate
|
||||
// themselves without aborting the upstream signal.
|
||||
if (proc.status === 'running') {
|
||||
proc.status = spec.signal?.aborted === true || outcome.signal !== null ? 'killed' : 'completed'
|
||||
}
|
||||
proc.exitCode = outcome.exitCode
|
||||
proc.signal = outcome.signal
|
||||
this.live.delete(proc)
|
||||
|
||||
@@ -249,6 +249,15 @@ describe('LocalBashExecutor.start (background process handles)', () => {
|
||||
expect(proc.signal).toBe('SIGTERM')
|
||||
})
|
||||
|
||||
it('a self-signal exit settles the handle as killed, not completed', async () => {
|
||||
const { bash } = await setup()
|
||||
const proc = bash.start(bash.resolve({ command: 'kill -TERM $$' }))
|
||||
await proc.done
|
||||
expect(proc.status).toBe('killed')
|
||||
expect(proc.exitCode).toBeNull()
|
||||
expect(proc.signal).toBe('SIGTERM')
|
||||
})
|
||||
|
||||
it('a background spawn failure settles as killed with the error readable on stderr', async () => {
|
||||
const { bash } = await setup()
|
||||
const proc = bash.start(bash.resolve({ command: 'true', workdir: '/nonexistent-dsh' }))
|
||||
|
||||
@@ -288,6 +288,14 @@ describe('background execution through the task runtime', () => {
|
||||
expect(text(final)).toContain('[status: killed, signal: SIGTERM]')
|
||||
})
|
||||
|
||||
it('a self-signal background exit is reported as killed through the REAL task_output tool', async () => {
|
||||
const ctx = await setupWithTasks()
|
||||
await call(ctx, 'bash', { command: 'kill -TERM $$', description: 'test command', run_in_background: true })
|
||||
|
||||
const final = await call(ctx, 'task_output', { task_id: 'bash-1', wait: true })
|
||||
expect(text(final)).toContain('[status: killed, signal: SIGTERM]')
|
||||
})
|
||||
|
||||
it('a background task started by an agent is registered with that agent as owner', async () => {
|
||||
// The fence SEMANTICS are pinned in dsh-tasks; this only pins that
|
||||
// tool-bash forwards exec.agent as the registration's owner.
|
||||
|
||||
Reference in New Issue
Block a user