Full execution sequence: trigger fires → eligible agents selected → adapter.invoke() called → status polled → result written to heartbeat_runs → cost_event recorded → activity logged.
Follow the heartbeat source code from the cron trigger through the adapter call to the database write, understanding each layer's responsibility.
packages/server/src/lib/heartbeat/
├── scheduler.ts ← registers the cron
├── runner.ts ← orchestrates one tick
├── dispatcher.ts ← assigns issues to agents
└── recorder.ts ← writes runs and cost events
export async function startHeartbeatScheduler() {
const companies = await db.companies.findAll({ where: { paused: false } });
for (const company of companies) {
const expr = company.heartbeat_cron ?? DEFAULT_CRON;
cron.schedule(expr, () => runHeartbeatTick(company.id));
}
}
Runs once at server startup; schedules one cron job per active company.
export async function runHeartbeatTick(companyId: string) {
// 1. Create the run record
const run = await db.heartbeat_runs.create({
company_id: companyId,
status: 'running',
started_at: new Date(),
});
try {
// 2. Check company state
const company = await db.companies.findOneOrFail(companyId);
if (company.paused) {
await recorder.skip(run.id, 'company_paused');
return;
}
// 3. Dispatch
const stats = await dispatcher.dispatchAll(companyId, run.id);
// 4. Record completion
await recorder.complete(run.id, stats);
} catch (err) {
await recorder.fail(run.id, err);
}
}
export async function dispatchAll(companyId: string, runId: string) {
const agents = await db.agents.findAll({
where: { company_id: companyId, status: 'active' },
});
const results = await Promise.allSettled(
agents.map(agent => dispatchOne(agent, companyId, runId))
);
return aggregateStats(results);
}
async function dispatchOne(agent, companyId, runId) {
// Atomic checkout
const issue = await claimNextIssue(agent.id, companyId);
if (!issue) return { claimed: 0, resolved: 0, cost: 0 };
// Assemble prompt and invoke
const adapter = createAdapter(agent);
const task = assembleTask(agent, issue);
const result = await adapter.invoke(task);
// Write outcome
await resolveIssue(issue.id, result);
await recorder.recordCost(agent.id, companyId, runId, result.cost);
return { claimed: 1, resolved: 1, cost: result.cost?.costUsd ?? 0 };
}
export async function recordCost(agentId, companyId, runId, cost) {
if (!cost) return;
await db.cost_events.create({
agent_id: agentId,
company_id: companyId,
heartbeat_run_id: runId,
model: cost.model,
input_tokens: cost.inputTokens,
output_tokens: cost.outputTokens,
cost_usd: cost.costUsd,
});
}
Promise.allSettled — agents run in parallel. If one agent's adapter throws, the others still complete. The run records partial failures.
No global transaction — each issue claim and resolution is its own transaction. This prevents one slow adapter from holding a lock on the entire company.
Idempotent run ID — the run ID is created before any work starts, so partial failures can be resumed or replayed.
Promise.allSettled is used instead of Promise.all