AI Agents SDE Task Viewer
      • Pr description
  1. Home
  2. AgentSDE
  3. agent-core
  4. gh-440
  5. changes
  6. pr_description.md
pr_description.md(1.8 KB)· Apr 12, 2026· 1 min read

AW-4: Refactor ClaudeInvocationService — enqueue to BullMQ instead of spawning#

Problem

ClaudeInvocationService.invoke() was tightly coupled to the NestJS process via child_process.spawn(), blocking the event loop and preventing distributed execution of Claude invocations.

Task / Link

Closes #440

Changes

  • Create InvocationResultListener — @Processor('phase-result') BullMQ worker that resolves pending promises by jobId; handles unmatched jobIds (warn + return) and timeouts (reject with message)
  • Refactor ClaudeInvocationService.invoke() — remove all spawn/stream logic; enqueue job to phase-invoke with full payload (jobId, taskId, phase, skill, env, cwd, timeout, args); await result via waitForResult(jobId, timeoutMs); parse signal from {TASK_DIR}/meta/ai-output.jsonl written by the worker
  • Update InvokeModule — register BullModule.forRootAsync() (inline stub, removable after AW-3 #439 merges), phase-invoke and phase-result queues, and InvocationResultListener provider
  • Update claude-invocation.service.spec.ts — replace child_process spawn mocks with BullMQ queue mocks; add tests for timeout propagation and missing ai-output.jsonl; 28 tests all green

Notes

⚠️ BullModule.forRootAsync() is registered inline in InvokeModule as a stub (marked with TODO comment). Once AW-3 (#439) merges and BullModule is registered in AppModule, remove the stub from InvokeModule.

⚠️ This PR installs @nestjs/bullmq, bullmq, and ioredis into package.json — those will also be added by AW-3, so a dedup/cleanup will be needed when both land.

Testing

  • Unit tests: 793 passing (48 suites), including 28 new/updated tests in claude-invocation.service.spec.ts
  • Lint: zero warnings/errors
PrdAgent-runner