mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-01-11 19:56:44 +00:00
feat(ai-agent): Enhance AI Agent registration with name and description fields
This commit is contained in:
parent
958cb3c9fd
commit
f519520966
3 changed files with 157 additions and 27 deletions
|
|
@ -23,6 +23,12 @@ if (!process.env["AI_AGENT_KEY"]) {
|
|||
|
||||
export const AI_AGENT_KEY: string = process.env["AI_AGENT_KEY"];
|
||||
|
||||
export const AI_AGENT_NAME: string | null =
|
||||
process.env["AI_AGENT_NAME"] || null;
|
||||
|
||||
export const AI_AGENT_DESCRIPTION: string | null =
|
||||
process.env["AI_AGENT_DESCRIPTION"] || null;
|
||||
|
||||
export const HOSTNAME: string = process.env["HOSTNAME"] || "localhost";
|
||||
|
||||
export const PORT: Port = new Port(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
import { ONEUPTIME_URL, AI_AGENT_ID, AI_AGENT_KEY } from "../Config";
|
||||
import {
|
||||
ONEUPTIME_URL,
|
||||
AI_AGENT_ID,
|
||||
AI_AGENT_KEY,
|
||||
AI_AGENT_NAME,
|
||||
AI_AGENT_DESCRIPTION,
|
||||
} from "../Config";
|
||||
import HTTPResponse from "Common/Types/API/HTTPResponse";
|
||||
import URL from "Common/Types/API/URL";
|
||||
import { JSONObject } from "Common/Types/JSON";
|
||||
import Sleep from "Common/Types/Sleep";
|
||||
import API from "Common/Utils/API";
|
||||
import { HasClusterKey } from "Common/Server/EnvironmentConfig";
|
||||
import LocalCache from "Common/Server/Infrastructure/LocalCache";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import ClusterKeyAuthorization from "Common/Server/Middleware/ClusterKeyAuthorization";
|
||||
|
||||
export default class Register {
|
||||
public static async registerAIAgent(): Promise<void> {
|
||||
|
|
@ -35,36 +43,65 @@ export default class Register {
|
|||
}
|
||||
|
||||
private static async _registerAIAgent(): Promise<void> {
|
||||
// Validate AI agent by sending alive request
|
||||
if (!AI_AGENT_ID) {
|
||||
logger.error("AI_AGENT_ID should be set");
|
||||
return process.exit();
|
||||
}
|
||||
if (HasClusterKey) {
|
||||
// Clustered mode: Auto-register and get ID from server
|
||||
const aiAgentRegistrationUrl: URL = URL.fromString(
|
||||
ONEUPTIME_URL.toString(),
|
||||
).addRoute("/api/ai-agent/register");
|
||||
|
||||
const aliveUrl: URL = URL.fromString(ONEUPTIME_URL.toString()).addRoute(
|
||||
"/api/ai-agent/alive",
|
||||
);
|
||||
logger.debug("Registering AI Agent...");
|
||||
logger.debug("Sending request to: " + aiAgentRegistrationUrl.toString());
|
||||
|
||||
logger.debug("Registering AI Agent...");
|
||||
logger.debug("Sending request to: " + aliveUrl.toString());
|
||||
const result: HTTPResponse<JSONObject> = await API.post({
|
||||
url: aiAgentRegistrationUrl,
|
||||
data: {
|
||||
aiAgentKey: AI_AGENT_KEY,
|
||||
aiAgentName: AI_AGENT_NAME,
|
||||
aiAgentDescription: AI_AGENT_DESCRIPTION,
|
||||
clusterKey: ClusterKeyAuthorization.getClusterKey(),
|
||||
},
|
||||
});
|
||||
|
||||
const result: HTTPResponse<JSONObject> = await API.post({
|
||||
url: aliveUrl,
|
||||
data: {
|
||||
aiAgentKey: AI_AGENT_KEY.toString(),
|
||||
aiAgentId: AI_AGENT_ID.toString(),
|
||||
},
|
||||
});
|
||||
if (result.isSuccess()) {
|
||||
logger.debug("AI Agent Registered");
|
||||
logger.debug(result.data);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
LocalCache.setString(
|
||||
"AI_AGENT",
|
||||
"AI_AGENT_ID",
|
||||
AI_AGENT_ID.toString() as string,
|
||||
);
|
||||
logger.debug("AI Agent registered successfully");
|
||||
const aiAgentId: string = result.data["_id"] as string;
|
||||
|
||||
LocalCache.setString("AI_AGENT", "AI_AGENT_ID", aiAgentId as string);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Failed to register AI Agent: " + result.statusCode);
|
||||
// Non-clustered mode: Validate AI agent by sending alive request
|
||||
if (!AI_AGENT_ID) {
|
||||
logger.error("AI_AGENT_ID or ONEUPTIME_SECRET should be set");
|
||||
return process.exit();
|
||||
}
|
||||
|
||||
const aliveUrl: URL = URL.fromString(ONEUPTIME_URL.toString()).addRoute(
|
||||
"/api/ai-agent/alive",
|
||||
);
|
||||
|
||||
logger.debug("Registering AI Agent...");
|
||||
logger.debug("Sending request to: " + aliveUrl.toString());
|
||||
|
||||
const result: HTTPResponse<JSONObject> = await API.post({
|
||||
url: aliveUrl,
|
||||
data: {
|
||||
aiAgentKey: AI_AGENT_KEY.toString(),
|
||||
aiAgentId: AI_AGENT_ID.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
if (result.isSuccess()) {
|
||||
LocalCache.setString(
|
||||
"AI_AGENT",
|
||||
"AI_AGENT_ID",
|
||||
AI_AGENT_ID.toString() as string,
|
||||
);
|
||||
logger.debug("AI Agent registered successfully");
|
||||
} else {
|
||||
throw new Error("Failed to register AI Agent: " + result.statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import UserMiddleware from "../Middleware/UserAuthorization";
|
||||
import ClusterKeyAuthorization from "../Middleware/ClusterKeyAuthorization";
|
||||
import AIAgentService, {
|
||||
Service as AIAgentServiceType,
|
||||
} from "../Services/AIAgentService";
|
||||
|
|
@ -11,15 +12,101 @@ import Response from "../Utils/Response";
|
|||
import BaseAPI from "./BaseAPI";
|
||||
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
||||
import PositiveNumber from "../../Types/PositiveNumber";
|
||||
import AIAgent from "../../Models/DatabaseModels/AIAgent";
|
||||
import AIAgent, {
|
||||
AIAgentConnectionStatus,
|
||||
} from "../../Models/DatabaseModels/AIAgent";
|
||||
import BadDataException from "../../Types/Exception/BadDataException";
|
||||
import { JSONObject } from "../../Types/JSON";
|
||||
import ObjectID from "../../Types/ObjectID";
|
||||
import OneUptimeDate from "../../Types/Date";
|
||||
import Version from "../../Types/Version";
|
||||
|
||||
export default class AIAgentAPI extends BaseAPI<AIAgent, AIAgentServiceType> {
|
||||
public constructor() {
|
||||
super(AIAgent, AIAgentService);
|
||||
|
||||
// Register Global AI Agent. Custom AI Agent can be registered via dashboard.
|
||||
this.router.post(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/register`,
|
||||
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
|
||||
async (
|
||||
req: ExpressRequest,
|
||||
res: ExpressResponse,
|
||||
next: NextFunction,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
const data: JSONObject = req.body;
|
||||
|
||||
if (!data["aiAgentKey"]) {
|
||||
return Response.sendErrorResponse(
|
||||
req,
|
||||
res,
|
||||
new BadDataException("aiAgentKey is missing"),
|
||||
);
|
||||
}
|
||||
|
||||
const aiAgentKey: string = data["aiAgentKey"] as string;
|
||||
|
||||
const aiAgent: AIAgent | null = await AIAgentService.findOneBy({
|
||||
query: {
|
||||
key: aiAgentKey,
|
||||
isGlobalAIAgent: true,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (aiAgent) {
|
||||
await AIAgentService.updateOneById({
|
||||
id: aiAgent.id!,
|
||||
data: {
|
||||
name: (data["aiAgentName"] as string) || "Global AI Agent",
|
||||
description: data["aiAgentDescription"] as string,
|
||||
lastAlive: OneUptimeDate.getCurrentDate(),
|
||||
connectionStatus: AIAgentConnectionStatus.Connected,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
_id: aiAgent._id?.toString(),
|
||||
message: "AI Agent already registered",
|
||||
});
|
||||
}
|
||||
|
||||
let newAIAgent: AIAgent = new AIAgent();
|
||||
newAIAgent.isGlobalAIAgent = true;
|
||||
newAIAgent.key = aiAgentKey;
|
||||
newAIAgent.name =
|
||||
(data["aiAgentName"] as string) || "Global AI Agent";
|
||||
newAIAgent.description = data["aiAgentDescription"] as string;
|
||||
newAIAgent.lastAlive = OneUptimeDate.getCurrentDate();
|
||||
newAIAgent.connectionStatus = AIAgentConnectionStatus.Connected;
|
||||
newAIAgent.aiAgentVersion = new Version("1.0.0");
|
||||
|
||||
newAIAgent = await AIAgentService.create({
|
||||
data: newAIAgent,
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
return Response.sendJsonObjectResponse(req, res, {
|
||||
_id: newAIAgent._id?.toString(),
|
||||
message: "AI Agent registered successfully",
|
||||
});
|
||||
} catch (err) {
|
||||
return next(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Alive endpoint for AI Agent heartbeat
|
||||
this.router.post(
|
||||
`${new this.entityType().getCrudApiPath()?.toString()}/alive`,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue