fix(#338): Add max concurrent agents limit

- Add MAX_CONCURRENT_AGENTS configuration (default: 20)
- Check current agent count before spawning
- Reject spawn requests with 429 Too Many Requests when limit reached
- Add comprehensive tests for limit enforcement

Refs #338
This commit is contained in:
Jason Woltje
2026-02-05 18:30:42 -06:00
parent ce7fb27c46
commit 3b80e9c396
4 changed files with 211 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
import { Injectable, Logger } from "@nestjs/common";
import { Injectable, Logger, HttpException, HttpStatus } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import Anthropic from "@anthropic-ai/sdk";
import { randomUUID } from "crypto";
@@ -17,6 +17,7 @@ export class AgentSpawnerService {
private readonly logger = new Logger(AgentSpawnerService.name);
private readonly anthropic: Anthropic;
private readonly sessions = new Map<string, AgentSession>();
private readonly maxConcurrentAgents: number;
constructor(private readonly configService: ConfigService) {
const apiKey = this.configService.get<string>("orchestrator.claude.apiKey");
@@ -29,7 +30,13 @@ export class AgentSpawnerService {
apiKey,
});
this.logger.log("AgentSpawnerService initialized with Claude SDK");
// Default to 20 if not configured
this.maxConcurrentAgents =
this.configService.get<number>("orchestrator.spawner.maxConcurrentAgents") ?? 20;
this.logger.log(
`AgentSpawnerService initialized with Claude SDK (max concurrent agents: ${String(this.maxConcurrentAgents)})`
);
}
/**
@@ -40,6 +47,9 @@ export class AgentSpawnerService {
spawnAgent(request: SpawnAgentRequest): SpawnAgentResponse {
this.logger.log(`Spawning agent for task: ${request.taskId}`);
// Check concurrent agent limit before proceeding
this.checkConcurrentAgentLimit();
// Validate request
this.validateSpawnRequest(request);
@@ -90,6 +100,27 @@ export class AgentSpawnerService {
return Array.from(this.sessions.values());
}
/**
* Check if the concurrent agent limit has been reached
* @throws HttpException with 429 Too Many Requests if limit reached
*/
private checkConcurrentAgentLimit(): void {
const currentCount = this.sessions.size;
if (currentCount >= this.maxConcurrentAgents) {
this.logger.warn(
`Maximum concurrent agents limit reached: ${String(currentCount)}/${String(this.maxConcurrentAgents)}`
);
throw new HttpException(
{
message: `Maximum concurrent agents limit reached (${String(this.maxConcurrentAgents)}). Please wait for existing agents to complete.`,
currentCount,
maxLimit: this.maxConcurrentAgents,
},
HttpStatus.TOO_MANY_REQUESTS
);
}
}
/**
* Validate spawn agent request
* @param request Spawn request to validate