Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions app/server/modules/agents/__tests__/agents.service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ test("markAgentConnecting creates and updates connection metadata", async () =>
});
});

test("markAgentOnline records ready capabilities and timestamps", async () => {
await agentsService.markAgentConnecting({
agentId: "remote-agent",
organizationId: null,
agentName: "Remote Agent",
agentKind: "remote",
connectedAt: 1_000,
});
await agentsService.markAgentOnline("remote-agent", 3_000, { platform: "linux", restic: true });

const agent = await agentsService.getAgent("remote-agent");

expect(agent).toMatchObject({
id: "remote-agent",
status: "online",
capabilities: { platform: "linux", restic: true },
lastSeenAt: 3_000,
lastReadyAt: 3_000,
updatedAt: 3_000,
});
});

test("agent runtime status moves from connecting to online, seen, and offline", async () => {
await agentsService.markAgentConnecting({
agentId: LOCAL_AGENT_ID,
Expand Down
14 changes: 9 additions & 5 deletions app/server/modules/agents/__tests__/controller-runtime.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { Effect } from "effect";
import { afterEach, expect, test, vi } from "vitest";
import waitForExpect from "wait-for-expect";
import { fromPartial } from "@total-typescript/shoehorn";
import { createAgentMessage } from "@zerobyte/contracts/agent-protocol";
import {
createAgentMessage,
AGENT_PROTOCOL_VERSION,
SUPPORTED_AGENT_PROTOCOL_MAX_VERSION,
} from "@zerobyte/contracts/agent-protocol";
import type { Volume } from "@zerobyte/contracts/volumes";
import { LOCAL_AGENT_ID, LOCAL_AGENT_KIND, LOCAL_AGENT_NAME } from "../constants";

Expand Down Expand Up @@ -55,7 +59,7 @@ const backupVolume = {

const readyPayload = {
agentId: LOCAL_AGENT_ID,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
hostname: "host",
platform: "linux",
capabilities: { backup: true },
Expand Down Expand Up @@ -205,11 +209,11 @@ test("websocket lifecycle updates agent connection status", async () => {
agentKind: LOCAL_AGENT_KIND,
});
expect(agentsServiceMocks.markAgentOnline).toHaveBeenCalledWith(LOCAL_AGENT_ID, expect.any(Number), {
platform: "linux",
backup: true,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
protocolCompatible: true,
hostname: "host",
platform: "linux",
});
expect(agentsServiceMocks.markAgentSeen).toHaveBeenCalledWith(LOCAL_AGENT_ID, expect.any(Number));
expect(agentsServiceMocks.markAgentOffline).toHaveBeenCalledWith(LOCAL_AGENT_ID);
Expand All @@ -230,7 +234,7 @@ test("websocket protocol rejection forwards the event and closes the connection"
JSON.stringify({
type: "agent.ready",
payload: {
protocolVersion: 2,
protocolVersion: SUPPORTED_AGENT_PROTOCOL_MAX_VERSION + 1,
hostname: "host",
platform: "linux",
},
Expand Down
9 changes: 5 additions & 4 deletions app/server/modules/agents/__tests__/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import waitForExpect from "wait-for-expect";
import { fromPartial } from "@total-typescript/shoehorn";
import {
createAgentMessage,
AGENT_PROTOCOL_VERSION,
SUPPORTED_AGENT_PROTOCOL_MAX_VERSION,
type AgentMessage,
} from "@zerobyte/contracts/agent-protocol";
Expand Down Expand Up @@ -141,7 +142,7 @@ test("invalid inbound messages are ignored", () => {
session.handleMessage(
createAgentMessage("agent.ready", {
agentId: LOCAL_AGENT_ID,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
hostname: "host",
platform: "linux",
capabilities: { backup: true },
Expand All @@ -166,7 +167,7 @@ test("agent.ready marks the session ready and forwards the event", () => {
session.handleMessage(
createAgentMessage("agent.ready", {
agentId: LOCAL_AGENT_ID,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
hostname: "host",
platform: "linux",
capabilities: { backup: true },
Expand All @@ -179,7 +180,7 @@ test("agent.ready marks the session ready and forwards the event", () => {
type: "agent.ready",
payload: {
agentId: LOCAL_AGENT_ID,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
hostname: "host",
platform: "linux",
capabilities: { backup: true },
Expand Down Expand Up @@ -214,7 +215,7 @@ test("backup agent messages are forwarded unchanged", () => {
session.handleMessage(
createAgentMessage("agent.ready", {
agentId: LOCAL_AGENT_ID,
protocolVersion: 1,
protocolVersion: AGENT_PROTOCOL_VERSION,
hostname: "host",
platform: "linux",
capabilities: { backup: true },
Expand Down
7 changes: 4 additions & 3 deletions app/server/modules/agents/agents.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const ensureLocalAgent = async () => {

const markAgentConnecting = async (params: AgentConnectionRegistration) => {
const { agentId, organizationId, agentName, agentKind, capabilities, connectedAt = Date.now() } = params;
const nextCapabilities = capabilities ?? LOCAL_AGENT_CAPABILITIES;

await db
.insert(agentsTable)
Expand All @@ -65,7 +66,7 @@ const markAgentConnecting = async (params: AgentConnectionRegistration) => {
name: agentName,
kind: agentKind,
status: "connecting",
capabilities: capabilities ?? {},
capabilities: nextCapabilities,
lastSeenAt: connectedAt,
updatedAt: connectedAt,
})
Expand All @@ -78,7 +79,7 @@ const markAgentConnecting = async (params: AgentConnectionRegistration) => {
status: "connecting",
lastSeenAt: connectedAt,
updatedAt: connectedAt,
capabilities: capabilities ?? {},
capabilities: nextCapabilities,
},
});

Expand All @@ -95,7 +96,7 @@ const updateAgentRuntime = async (agentId: string, values: Partial<Agent>) => {
return updatedAgent;
};

const markAgentOnline = async (agentId: string, readyAt = Date.now(), metadata?: AgentCapabilities) => {
const markAgentOnline = async (agentId: string, readyAt = Date.now(), metadata = LOCAL_AGENT_CAPABILITIES) => {
return updateAgentRuntime(agentId, {
status: "online",
capabilities: metadata,
Expand Down
Loading
Loading