mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-06-02 21:16:14 -04:00
131 lines
3.1 KiB
TypeScript
131 lines
3.1 KiB
TypeScript
import { eq } from "drizzle-orm";
|
|
import { db } from "../../db/db";
|
|
import { agentsTable, type Agent, type AgentCapabilities, type AgentKind } from "../../db/schema";
|
|
import { LOCAL_AGENT_CAPABILITIES, LOCAL_AGENT_ID, LOCAL_AGENT_KIND, LOCAL_AGENT_NAME } from "./constants";
|
|
|
|
type AgentConnectionRegistration = {
|
|
agentId: string;
|
|
organizationId: string | null;
|
|
agentName: string;
|
|
agentKind: AgentKind;
|
|
capabilities?: AgentCapabilities;
|
|
connectedAt?: number;
|
|
};
|
|
|
|
const listAgents = async (organizationId?: string | null) => {
|
|
if (organizationId === undefined) {
|
|
return db.query.agentsTable.findMany({ orderBy: { createdAt: "asc" } });
|
|
}
|
|
|
|
if (organizationId === null) {
|
|
return db.query.agentsTable.findMany({
|
|
where: { organizationId: { isNull: true } },
|
|
orderBy: { createdAt: "asc" },
|
|
});
|
|
}
|
|
|
|
return db.query.agentsTable.findMany({
|
|
where: { organizationId },
|
|
orderBy: { createdAt: "asc" },
|
|
});
|
|
};
|
|
|
|
const getAgent = async (agentId: string) => {
|
|
return db.query.agentsTable.findFirst({ where: { id: agentId } });
|
|
};
|
|
|
|
const ensureLocalAgent = async () => {
|
|
const existing = await getAgent(LOCAL_AGENT_ID);
|
|
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
|
|
await db.insert(agentsTable).values({
|
|
id: LOCAL_AGENT_ID,
|
|
organizationId: null,
|
|
name: LOCAL_AGENT_NAME,
|
|
kind: LOCAL_AGENT_KIND,
|
|
status: "offline",
|
|
capabilities: LOCAL_AGENT_CAPABILITIES,
|
|
updatedAt: Date.now(),
|
|
});
|
|
|
|
return getAgent(LOCAL_AGENT_ID);
|
|
};
|
|
|
|
const markAgentConnecting = async (params: AgentConnectionRegistration) => {
|
|
const { agentId, organizationId, agentName, agentKind, capabilities, connectedAt = Date.now() } = params;
|
|
|
|
await db
|
|
.insert(agentsTable)
|
|
.values({
|
|
id: agentId,
|
|
organizationId,
|
|
name: agentName,
|
|
kind: agentKind,
|
|
status: "connecting",
|
|
capabilities: capabilities ?? {},
|
|
lastSeenAt: connectedAt,
|
|
updatedAt: connectedAt,
|
|
})
|
|
.onConflictDoUpdate({
|
|
target: agentsTable.id,
|
|
set: {
|
|
organizationId,
|
|
name: agentName,
|
|
kind: agentKind,
|
|
status: "connecting",
|
|
lastSeenAt: connectedAt,
|
|
updatedAt: connectedAt,
|
|
capabilities: capabilities ?? {},
|
|
},
|
|
});
|
|
|
|
return getAgent(agentId);
|
|
};
|
|
|
|
const updateAgentRuntime = async (agentId: string, values: Partial<Agent>) => {
|
|
const [updatedAgent] = await db.update(agentsTable).set(values).where(eq(agentsTable.id, agentId)).returning();
|
|
|
|
if (!updatedAgent) {
|
|
throw new Error(`Agent ${agentId} not found`);
|
|
}
|
|
|
|
return updatedAgent;
|
|
};
|
|
|
|
const markAgentOnline = async (agentId: string, readyAt = Date.now(), metadata?: AgentCapabilities) => {
|
|
return updateAgentRuntime(agentId, {
|
|
status: "online",
|
|
capabilities: metadata,
|
|
lastSeenAt: readyAt,
|
|
lastReadyAt: readyAt,
|
|
updatedAt: readyAt,
|
|
});
|
|
};
|
|
|
|
const markAgentSeen = async (agentId: string, seenAt = Date.now()) => {
|
|
return updateAgentRuntime(agentId, {
|
|
lastSeenAt: seenAt,
|
|
updatedAt: seenAt,
|
|
});
|
|
};
|
|
|
|
const markAgentOffline = async (agentId: string, disconnectedAt = Date.now()) => {
|
|
return updateAgentRuntime(agentId, {
|
|
status: "offline",
|
|
updatedAt: disconnectedAt,
|
|
});
|
|
};
|
|
|
|
export const agentsService = {
|
|
listAgents,
|
|
getAgent,
|
|
ensureLocalAgent,
|
|
markAgentConnecting,
|
|
markAgentOnline,
|
|
markAgentSeen,
|
|
markAgentOffline,
|
|
};
|