feat: implement app-side telemetry sender

Add the shared telemetry sender, wire the CLI/server emit points,
and cover the config and completion behavior with tests.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-03-31 08:08:18 -05:00
parent ca5659f734
commit 34044cdfce
29 changed files with 670 additions and 5 deletions

View file

@ -25,6 +25,8 @@ import type { AdapterExecutionResult, AdapterInvocationMeta, AdapterSessionCodec
import { createLocalAgentJwt } from "../agent-auth-jwt.js";
import { parseObject, asBoolean, asNumber, appendWithCap, MAX_EXCERPT_BYTES } from "../adapters/utils.js";
import { costService } from "./costs.js";
import { trackAgentFirstHeartbeat } from "@paperclipai/shared/telemetry";
import { getTelemetryClient } from "../telemetry.js";
import { companySkillService } from "./company-skills.js";
import { budgetService, type BudgetEnforcementScope } from "./budgets.js";
import { secretService } from "./secrets.js";
@ -1807,6 +1809,8 @@ export function heartbeatService(db: Db) {
return;
}
const isFirstHeartbeat = !existing.lastHeartbeatAt;
const runningCount = await countRunningRunsForAgent(agentId);
const nextStatus =
runningCount > 0
@ -1826,6 +1830,11 @@ export function heartbeatService(db: Db) {
.returning()
.then((rows) => rows[0] ?? null);
if (isFirstHeartbeat && updated) {
const tc = getTelemetryClient();
if (tc) trackAgentFirstHeartbeat(tc, { adapterType: updated.adapterType });
}
if (updated) {
publishLiveEvent({
companyId: updated.companyId,