feat(orchestrator): MS23-P3-001 OpenClawProvider
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
94
apps/orchestrator/src/api/providers/providers.module.ts
Normal file
94
apps/orchestrator/src/api/providers/providers.module.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { HttpModule } from "@nestjs/axios";
|
||||
import { Logger, Module, OnModuleInit } from "@nestjs/common";
|
||||
import type { AgentProviderConfig } from "@prisma/client";
|
||||
import { PrismaModule } from "../../prisma/prisma.module";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
import { EncryptionService } from "../../security/encryption.service";
|
||||
import { AgentProviderRegistry } from "../agents/agent-provider.registry";
|
||||
import { AgentsModule } from "../agents/agents.module";
|
||||
import { OpenClawProviderFactory } from "./openclaw/openclaw.provider-factory";
|
||||
|
||||
const OPENCLAW_PROVIDER_TYPE = "openclaw";
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
AgentsModule,
|
||||
PrismaModule,
|
||||
HttpModule.register({
|
||||
timeout: 10000,
|
||||
maxRedirects: 5,
|
||||
}),
|
||||
],
|
||||
providers: [EncryptionService, OpenClawProviderFactory],
|
||||
})
|
||||
export class ProvidersModule implements OnModuleInit {
|
||||
private readonly logger = new Logger(ProvidersModule.name);
|
||||
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly registry: AgentProviderRegistry,
|
||||
private readonly openClawProviderFactory: OpenClawProviderFactory
|
||||
) {}
|
||||
|
||||
async onModuleInit(): Promise<void> {
|
||||
const configs = await this.prisma.agentProviderConfig.findMany({
|
||||
where: {
|
||||
provider: OPENCLAW_PROVIDER_TYPE,
|
||||
isActive: true,
|
||||
},
|
||||
orderBy: [{ createdAt: "asc" }, { id: "asc" }],
|
||||
});
|
||||
|
||||
for (const config of configs) {
|
||||
await this.registerProvider(config);
|
||||
}
|
||||
}
|
||||
|
||||
private async registerProvider(config: AgentProviderConfig): Promise<void> {
|
||||
const provider = this.openClawProviderFactory.createProvider(config);
|
||||
|
||||
try {
|
||||
provider.validateBaseUrl();
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`Skipping OpenClaw provider ${config.name}: invalid configuration (${this.toErrorMessage(error)})`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
provider.validateToken();
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Skipping OpenClaw provider ${config.name}: token decryption failed (${this.toErrorMessage(error)})`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const available = await provider.isAvailable();
|
||||
if (!available) {
|
||||
this.logger.warn(
|
||||
`Skipping OpenClaw provider ${config.name}: gateway ${config.gatewayUrl} is unreachable`
|
||||
);
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`Skipping OpenClaw provider ${config.name}: gateway ${config.gatewayUrl} is unreachable (${this.toErrorMessage(error)})`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.registry.registerProvider(provider);
|
||||
this.logger.log(`Registered OpenClaw provider ${provider.providerId}`);
|
||||
}
|
||||
|
||||
private toErrorMessage(error: unknown): string {
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
}
|
||||
|
||||
return String(error);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user