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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user