@essentialai/cogent-bridge
Version:
Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.
72 lines • 2.8 kB
TypeScript
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
/**
* Background heartbeat service that keeps a registered peer alive.
*
* When running, it periodically:
* 1. Sends an MCP debug-level logging notification (keeps stdio pipe active)
* 2. Calls backend.updateLastSeen() to refresh the peer's lastSeenAt timestamp
* - Local mode: writes to state file via peer-registry
* - Cloud mode: POST /api/sessions/:sessionId/heartbeat
*
* Uses a setTimeout chain (not a fixed-interval timer) so that failure delays can use
* exponential backoff. Retryable errors (network, 503, 429) trigger backoff
* and retry. Terminal errors (401, INVALID_INPUT) stop immediately.
*
* Auto-stops after MAX_FAILURES consecutive retryable errors (capped retry).
*/
export declare class HeartbeatService {
private timer;
private peerId;
private mcpServer;
private onPeerEvicted;
private consecutiveFailures;
private intervalMs;
private backoff;
private static readonly MAX_FAILURES;
/**
* Classify whether an error is terminal (should not retry) or retryable.
*
* Terminal errors:
* - INVALID_INPUT: peer ID is wrong, retrying won't help
* - Auth errors (401/Unauthorized): credentials invalid
*
* Note: PEER_NOT_FOUND is NOT classified here because it has its own
* special handling path (onPeerEvicted callback) in tick().
*/
private isTerminalError;
/**
* Schedule the next heartbeat tick after a delay.
* Every timer is .unref()'d to prevent process hang on SIGTERM.
*/
private scheduleNextTick;
/**
* Start the heartbeat for a registered peer.
* Idempotent — stops any existing heartbeat before starting a new one.
*
* @param onPeerEvicted - Optional callback invoked when the server returns
* PEER_NOT_FOUND (404), indicating the peer was evicted by stale cleanup.
* The callback should trigger re-registration.
*/
start(peerId: string, mcpServer: McpServer, onPeerEvicted?: () => void): void;
/**
* Stop the heartbeat timer. Safe to call multiple times.
*/
stop(options?: {
preservePeerInfo?: boolean;
}): void;
get isRunning(): boolean;
/**
* Restart the heartbeat using stored peerId, mcpServer, and onPeerEvicted.
* Used after automatic re-registration to resume keepalive ticks.
*/
restart(): void;
/**
* Single heartbeat tick.
* On success: schedules next tick at normal interval and resets backoff.
* On retryable error: schedules next tick at backoff delay.
* On terminal error or MAX_FAILURES: stops heartbeat.
*/
private tick;
}
export declare const heartbeat: HeartbeatService;
//# sourceMappingURL=heartbeat.d.ts.map