UNPKG

@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
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