feat(M6): Set up orchestrator service foundation
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Add NestJS-based orchestrator service structure for M6-AgentOrchestration. Changes: - Migrate from Express to NestJS architecture - Add health check endpoint module - Add placeholder modules: coordinator, git, killswitch, monitor, queue, spawner, valkey - Update configuration for NestJS - Update lockfile for new dependencies This is foundational work for M6-AgentOrchestration milestone. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
20
apps/orchestrator/src/api/health/health.controller.ts
Normal file
20
apps/orchestrator/src/api/health/health.controller.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
@Controller("health")
|
||||
export class HealthController {
|
||||
@Get()
|
||||
check() {
|
||||
return {
|
||||
status: "ok",
|
||||
service: "orchestrator",
|
||||
version: "0.0.6",
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
@Get("ready")
|
||||
ready() {
|
||||
// TODO: Check Valkey connection, Docker daemon
|
||||
return { ready: true };
|
||||
}
|
||||
}
|
||||
7
apps/orchestrator/src/api/health/health.module.ts
Normal file
7
apps/orchestrator/src/api/health/health.module.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { HealthController } from "./health.controller";
|
||||
|
||||
@Module({
|
||||
controllers: [HealthController],
|
||||
})
|
||||
export class HealthModule {}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
|
||||
export const healthRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
fastify.get('/health', async () => {
|
||||
return {
|
||||
status: 'ok',
|
||||
service: 'orchestrator',
|
||||
version: '0.0.6',
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
});
|
||||
|
||||
fastify.get('/health/ready', async () => {
|
||||
// TODO: Check Valkey connection, Docker daemon
|
||||
return { ready: true };
|
||||
});
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
import Fastify from 'fastify';
|
||||
import { healthRoutes } from './routes/health.routes.js';
|
||||
|
||||
export async function createServer() {
|
||||
const fastify = Fastify({
|
||||
logger: true,
|
||||
});
|
||||
|
||||
// Health check routes
|
||||
await fastify.register(healthRoutes);
|
||||
|
||||
return fastify;
|
||||
}
|
||||
22
apps/orchestrator/src/app.module.ts
Normal file
22
apps/orchestrator/src/app.module.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
import { BullModule } from "@nestjs/bullmq";
|
||||
import { HealthModule } from "./api/health/health.module";
|
||||
import { orchestratorConfig } from "./config/orchestrator.config";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [orchestratorConfig],
|
||||
}),
|
||||
BullModule.forRoot({
|
||||
connection: {
|
||||
host: process.env.VALKEY_HOST ?? "localhost",
|
||||
port: parseInt(process.env.VALKEY_PORT ?? "6379"),
|
||||
},
|
||||
}),
|
||||
HealthModule,
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
26
apps/orchestrator/src/config/orchestrator.config.ts
Normal file
26
apps/orchestrator/src/config/orchestrator.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { registerAs } from "@nestjs/config";
|
||||
|
||||
export const orchestratorConfig = registerAs("orchestrator", () => ({
|
||||
port: parseInt(process.env.ORCHESTRATOR_PORT ?? "3001", 10),
|
||||
valkey: {
|
||||
host: process.env.VALKEY_HOST ?? "localhost",
|
||||
port: parseInt(process.env.VALKEY_PORT ?? "6379", 10),
|
||||
url: process.env.VALKEY_URL ?? "redis://localhost:6379",
|
||||
},
|
||||
claude: {
|
||||
apiKey: process.env.CLAUDE_API_KEY,
|
||||
},
|
||||
docker: {
|
||||
socketPath: process.env.DOCKER_SOCKET ?? "/var/run/docker.sock",
|
||||
},
|
||||
git: {
|
||||
userName: process.env.GIT_USER_NAME ?? "Mosaic Orchestrator",
|
||||
userEmail: process.env.GIT_USER_EMAIL ?? "orchestrator@mosaicstack.dev",
|
||||
},
|
||||
killswitch: {
|
||||
enabled: process.env.KILLSWITCH_ENABLED === "true",
|
||||
},
|
||||
sandbox: {
|
||||
enabled: process.env.SANDBOX_ENABLED === "true",
|
||||
},
|
||||
}));
|
||||
4
apps/orchestrator/src/coordinator/coordinator.module.ts
Normal file
4
apps/orchestrator/src/coordinator/coordinator.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class CoordinatorModule {}
|
||||
4
apps/orchestrator/src/git/git.module.ts
Normal file
4
apps/orchestrator/src/git/git.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class GitModule {}
|
||||
4
apps/orchestrator/src/killswitch/killswitch.module.ts
Normal file
4
apps/orchestrator/src/killswitch/killswitch.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class KillswitchModule {}
|
||||
@@ -1,28 +1,19 @@
|
||||
/**
|
||||
* Mosaic Orchestrator - Agent Orchestration Service
|
||||
*
|
||||
* Execution plane for Mosaic Stack agent coordination.
|
||||
* Spawns, monitors, and manages Claude agents for autonomous work.
|
||||
*/
|
||||
import { NestFactory } from "@nestjs/core";
|
||||
import { AppModule } from "./app.module";
|
||||
import { Logger } from "@nestjs/common";
|
||||
|
||||
import { createServer } from './api/server.js';
|
||||
|
||||
const PORT = process.env.ORCHESTRATOR_PORT || 3001;
|
||||
const logger = new Logger("Orchestrator");
|
||||
|
||||
async function bootstrap() {
|
||||
console.log('🚀 Starting Mosaic Orchestrator...');
|
||||
|
||||
const server = await createServer();
|
||||
|
||||
await server.listen({
|
||||
port: Number(PORT),
|
||||
host: '0.0.0.0'
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
logger: ["error", "warn", "log", "debug", "verbose"],
|
||||
});
|
||||
|
||||
console.log(`✅ Orchestrator running on http://0.0.0.0:${PORT}`);
|
||||
const port = process.env.ORCHESTRATOR_PORT ?? 3001;
|
||||
|
||||
await app.listen(Number(port), "0.0.0.0");
|
||||
|
||||
logger.log(`🚀 Orchestrator running on http://0.0.0.0:${String(port)}`);
|
||||
}
|
||||
|
||||
bootstrap().catch((error) => {
|
||||
console.error('Failed to start orchestrator:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
void bootstrap();
|
||||
|
||||
4
apps/orchestrator/src/monitor/monitor.module.ts
Normal file
4
apps/orchestrator/src/monitor/monitor.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class MonitorModule {}
|
||||
4
apps/orchestrator/src/queue/queue.module.ts
Normal file
4
apps/orchestrator/src/queue/queue.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class QueueModule {}
|
||||
4
apps/orchestrator/src/spawner/spawner.module.ts
Normal file
4
apps/orchestrator/src/spawner/spawner.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class SpawnerModule {}
|
||||
4
apps/orchestrator/src/valkey/valkey.module.ts
Normal file
4
apps/orchestrator/src/valkey/valkey.module.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
@Module({})
|
||||
export class ValkeyModule {}
|
||||
Reference in New Issue
Block a user