Emit agent_id in agent telemetry events

This commit is contained in:
Dotta committed 2026-04-10 10:23:53 -05:00
1 parent d2f40c10a4
commit bf8b5da7c9
8 files changed
+96 -11

No files matched your search

+15 -6
View File
@@ -50,9 +50,12 @@ export function trackGoalCreated(
export function trackAgentCreated(
client: TelemetryClient,
dims: { agentRole: string },
dims: { agentRole: string; agentId: string },
): void {
client.track("agent.created", { agent_role: dims.agentRole });
client.track("agent.created", {
agent_role: dims.agentRole,
agent_id: dims.agentId,
});
}
export function trackSkillImported(
@@ -67,16 +70,22 @@ export function trackSkillImported(
export function trackAgentFirstHeartbeat(
client: TelemetryClient,
dims: { agentRole: string },
dims: { agentRole: string; agentId: string },
): void {
client.track("agent.first_heartbeat", { agent_role: dims.agentRole });
client.track("agent.first_heartbeat", {
agent_role: dims.agentRole,
agent_id: dims.agentId,
});
}
export function trackAgentTaskCompleted(
client: TelemetryClient,
dims: { agentRole: string },
dims: { agentRole: string; agentId: string },
): void {
client.track("agent.task_completed", { agent_role: dims.agentRole });
client.track("agent.task_completed", {
agent_role: dims.agentRole,
agent_id: dims.agentId,
});
}
export function trackErrorHandlerCrash(
@@ -352,6 +352,7 @@ describe("agent skill routes", () => {
);
expect(mockTrackAgentCreated).toHaveBeenCalledWith(expect.anything(), {
agentRole: "engineer",
agentId: "11111111-1111-4111-8111-111111111111",
});
});
@@ -273,7 +273,7 @@ describeEmbeddedPostgres("heartbeat orphaned process recovery", () => {
});
it("tracks the first heartbeat with the agent role instead of adapter type", async () => {
const { runId } = await seedRunFixture({
const { agentId, runId } = await seedRunFixture({
agentStatus: "running",
includeIssue: false,
});
@@ -283,6 +283,7 @@ describeEmbeddedPostgres("heartbeat orphaned process recovery", () => {
expect(mockTrackAgentFirstHeartbeat).toHaveBeenCalledWith(mockTelemetryClient, {
agentRole: "engineer",
agentId,
});
});
});
@@ -118,6 +118,7 @@ describe("issue telemetry routes", () => {
await vi.waitFor(() => {
expect(mockTrackAgentTaskCompleted).toHaveBeenCalledWith(expect.anything(), {
agentRole: "engineer",
agentId: "agent-1",
});
});
}, 10_000);
@@ -0,0 +1,73 @@
import { describe, expect, it, vi } from "vitest";
import {
trackAgentCreated,
trackAgentFirstHeartbeat,
trackAgentTaskCompleted,
trackInstallCompleted,
} from "@paperclipai/shared/telemetry";
import type { TelemetryClient } from "@paperclipai/shared/telemetry";
function createClient(): TelemetryClient {
return {
track: vi.fn(),
hashPrivateRef: vi.fn((value: string) => `hashed:${value}`),
} as unknown as TelemetryClient;
}
describe("shared telemetry agent events", () => {
it("includes agent_id for agent.created", () => {
const client = createClient();
trackAgentCreated(client, {
agentRole: "engineer",
agentId: "11111111-1111-4111-8111-111111111111",
});
expect(client.track).toHaveBeenCalledWith("agent.created", {
agent_role: "engineer",
agent_id: "11111111-1111-4111-8111-111111111111",
});
});
it("includes agent_id for agent.first_heartbeat", () => {
const client = createClient();
trackAgentFirstHeartbeat(client, {
agentRole: "coder",
agentId: "22222222-2222-4222-8222-222222222222",
});
expect(client.track).toHaveBeenCalledWith("agent.first_heartbeat", {
agent_role: "coder",
agent_id: "22222222-2222-4222-8222-222222222222",
});
});
it("includes agent_id for agent.task_completed", () => {
const client = createClient();
trackAgentTaskCompleted(client, {
agentRole: "qa",
agentId: "33333333-3333-4333-8333-333333333333",
});
expect(client.track).toHaveBeenCalledWith("agent.task_completed", {
agent_role: "qa",
agent_id: "33333333-3333-4333-8333-333333333333",
});
});
it("keeps non-agent event dimensions unchanged", () => {
const client = createClient();
trackInstallCompleted(client, { adapterType: "codex_local" });
expect(client.track).toHaveBeenCalledWith("install.completed", {
adapter_type: "codex_local",
});
expect(client.track).not.toHaveBeenCalledWith(
"install.completed",
expect.objectContaining({ agent_id: expect.any(String) }),
);
});
});
+2 -2
View File
@@ -1426,7 +1426,7 @@ export function agentRoutes(db: Db) {
});
const telemetryClient = getTelemetryClient();
if (telemetryClient) {
trackAgentCreated(telemetryClient, { agentRole: agent.role });
trackAgentCreated(telemetryClient, { agentRole: agent.role, agentId: agent.id });
}
await applyDefaultAgentTaskAssignGrant(
@@ -1514,7 +1514,7 @@ export function agentRoutes(db: Db) {
});
const telemetryClient = getTelemetryClient();
if (telemetryClient) {
trackAgentCreated(telemetryClient, { agentRole: agent.role });
trackAgentCreated(telemetryClient, { agentRole: agent.role, agentId: agent.id });
}
await applyDefaultAgentTaskAssignGrant(
+1 -1
View File
@@ -1661,7 +1661,7 @@ export function issueRoutes(
if (tc && actor.agentId) {
const actorAgent = await agentsSvc.getById(actor.agentId);
if (actorAgent) {
trackAgentTaskCompleted(tc, { agentRole: actorAgent.role });
trackAgentTaskCompleted(tc, { agentRole: actorAgent.role, agentId: actorAgent.id });
}
}
}
+1 -1
View File
@@ -2300,7 +2300,7 @@ export function heartbeatService(db: Db) {
if (isFirstHeartbeat && updated) {
const tc = getTelemetryClient();
if (tc) trackAgentFirstHeartbeat(tc, { agentRole: updated.role });
if (tc) trackAgentFirstHeartbeat(tc, { agentRole: updated.role, agentId: updated.id });
}
if (updated) {