fix: resolve deployment crashes in coordinator and API services

Coordinator: install all dependencies from pyproject.toml instead of
hardcoded subset (missing slowapi, anthropic, opentelemetry-*).

API: FederationAgentService now gracefully disables when orchestrator
URL is not configured instead of throwing and crashing the app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-10 09:41:54 -06:00
parent f3694592cc
commit ab64583951
2 changed files with 20 additions and 10 deletions

View File

@@ -44,6 +44,7 @@ export interface AgentCommandResponse {
export class FederationAgentService {
private readonly logger = new Logger(FederationAgentService.name);
private readonly orchestratorUrl: string;
private readonly enabled: boolean;
constructor(
private readonly prisma: PrismaService,
@@ -60,18 +61,28 @@ export class FederationAgentService {
const validationResult = validateUrl(url, isDevelopment);
if (!validationResult.valid) {
const errorMessage = validationResult.error ?? "Unknown validation error";
this.logger.error(`Invalid orchestrator URL: ${errorMessage}`);
// Log security event
this.logger.warn(
`Federation agent service disabled: ${errorMessage}. Set orchestrator.url to enable.`
);
this.auditService.logInvalidOrchestratorUrl(url, errorMessage);
throw new Error(errorMessage);
this.orchestratorUrl = "";
this.enabled = false;
return;
}
this.orchestratorUrl = url;
this.enabled = true;
this.logger.log(
`FederationAgentService initialized with orchestrator URL: ${this.orchestratorUrl}`
);
}
private assertEnabled(): void {
if (!this.enabled) {
throw new Error("Federation agent service is disabled: orchestrator URL not configured");
}
}
/**
* Spawn an agent on a remote federated instance
* @param workspaceId Workspace ID
@@ -84,6 +95,7 @@ export class FederationAgentService {
connectionId: string,
payload: SpawnAgentCommandPayload
): Promise<CommandMessageDetails> {
this.assertEnabled();
this.logger.log(
`Spawning agent on remote instance via connection ${connectionId} for task ${payload.taskId}`
);
@@ -126,6 +138,7 @@ export class FederationAgentService {
connectionId: string,
agentId: string
): Promise<CommandMessageDetails> {
this.assertEnabled();
this.logger.log(`Getting agent status for ${agentId} via connection ${connectionId}`);
// Validate connection exists and is active
@@ -167,6 +180,7 @@ export class FederationAgentService {
connectionId: string,
agentId: string
): Promise<CommandMessageDetails> {
this.assertEnabled();
this.logger.log(`Killing agent ${agentId} via connection ${connectionId}`);
// Validate connection exists and is active
@@ -208,6 +222,7 @@ export class FederationAgentService {
commandType: string,
payload: Record<string, unknown>
): Promise<AgentCommandResponse> {
this.assertEnabled();
this.logger.log(`Handling agent command ${commandType} from ${remoteInstanceId}`);
// Verify connection exists for remote instance

View File

@@ -15,14 +15,9 @@ COPY pyproject.toml .
# Create virtual environment and install dependencies
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY src/ ./src/
RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir hatchling && \
pip install --no-cache-dir \
fastapi>=0.109.0 \
uvicorn[standard]>=0.27.0 \
pydantic>=2.5.0 \
pydantic-settings>=2.1.0 \
python-dotenv>=1.0.0
pip install --no-cache-dir .
# Production stage
FROM python:3.11-slim