Files
paperclip/ui/src/api/heartbeats.ts
Forgotten 45c4df7b8a feat: add billing type tracking and cost enhancements
Add AdapterBillingType (api/subscription/unknown) to adapter execution results
so the system can distinguish API-billed vs subscription-billed runs. Enhance
cost service to aggregate subscription vs API run counts and token breakdowns.
Add limit param to heartbeat runs list API and client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 21:35:44 -06:00

48 lines
1.8 KiB
TypeScript

import type { HeartbeatRun, HeartbeatRunEvent } from "@paperclip/shared";
import { api } from "./client";
export interface ActiveRunForIssue extends HeartbeatRun {
agentId: string;
agentName: string;
adapterType: string;
}
export interface LiveRunForIssue {
id: string;
status: string;
invocationSource: string;
triggerDetail: string | null;
startedAt: string | null;
finishedAt: string | null;
createdAt: string;
agentId: string;
agentName: string;
adapterType: string;
issueId?: string | null;
}
export const heartbeatsApi = {
list: (companyId: string, agentId?: string, limit?: number) => {
const searchParams = new URLSearchParams();
if (agentId) searchParams.set("agentId", agentId);
if (limit) searchParams.set("limit", String(limit));
const qs = searchParams.toString();
return api.get<HeartbeatRun[]>(`/companies/${companyId}/heartbeat-runs${qs ? `?${qs}` : ""}`);
},
events: (runId: string, afterSeq = 0, limit = 200) =>
api.get<HeartbeatRunEvent[]>(
`/heartbeat-runs/${runId}/events?afterSeq=${encodeURIComponent(String(afterSeq))}&limit=${encodeURIComponent(String(limit))}`,
),
log: (runId: string, offset = 0, limitBytes = 256000) =>
api.get<{ runId: string; store: string; logRef: string; content: string; nextOffset?: number }>(
`/heartbeat-runs/${runId}/log?offset=${encodeURIComponent(String(offset))}&limitBytes=${encodeURIComponent(String(limitBytes))}`,
),
cancel: (runId: string) => api.post<void>(`/heartbeat-runs/${runId}/cancel`, {}),
liveRunsForIssue: (issueId: string) =>
api.get<LiveRunForIssue[]>(`/issues/${issueId}/live-runs`),
activeRunForIssue: (issueId: string) =>
api.get<ActiveRunForIssue | null>(`/issues/${issueId}/active-run`),
liveRunsForCompany: (companyId: string) =>
api.get<LiveRunForIssue[]>(`/companies/${companyId}/live-runs`),
};