@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.
181 lines • 10 kB
JavaScript
// ---------------------------------------------------------------------------
// PEER PRESENCE — what state this agent is in on its channel, why, and getting
// it back to `online` without anyone being told to restart something.
//
// ── THE VOCABULARY, taken from what this codebase already says ──────────────
// "local" COGENT_LOCAL / no relay. Presence is not a concept here.
// "deferred" EXISTING TERM (backend-provider.ts): cloud-CONFIGURED but never joined —
// there are no stored credentials for this working directory. Nothing to
// restore; the agent must join a channel first.
// "offline" Stored credentials name a peer for this working directory, but this
// process has not registered it. The bridge is running; the AGENT IS NOT
// IN THE CHANNEL. Other peers see it as absent and cannot address it.
// "online" Registered. The channel lists this agent and messages reach it.
//
// ── HOW AN AGENT ENDS UP `offline` — the mechanism, stated plainly ──────────
// Registration is an explicit act: something must call `cogent_register_peer`. The
// bridge starting does NOT register — it only publishes the tools. So every time an
// agent session starts, the bridge comes up holding valid credentials while the agent
// is absent from its own channel, and stays that way until the agent calls the tool.
// If the agent never calls it — it forgot, it crashed first, the session was resumed
// from a transcript that had already registered — the peer is never (re-)created, and
// the relay's stale sweep eventually deletes the entry left over from last time.
//
// That state used to be both SILENT and SELF-PERPETUATING, because every repair in
// this client sat behind a successful registration:
// - announceBridge() (auto-relay) — written at register time
// - reapStaleBridges() (auto-relay) — "only after a peer is genuinely registered"
// - triggerReRegistration()(startup) — reads in-memory state, null in a fresh process
// So when registration was the thing that did not happen, nothing recovered and nothing
// cleaned up. Measured 2026-09-14 on one checkout: 18 live bridges at 3.23.9, last
// successful register five days earlier, the peer absent from a healthy Team channel
// whose two other agents were present and waiting on it.
//
// ── WHY RESTORING IT IS SAFE ────────────────────────────────────────────────
// - Credentials are keyed PER WORKING DIRECTORY
// (~/.cogent/credentials/<sha256(cwd)[..16]>.json, commit f758d8ee). Reading this
// directory's own file cannot inherit another project's session — that was the
// LEGACY GLOBAL file, which is only ever `fs.access`'d for a warning and never read.
// - The agent-session id need not be correct here: auto-relay re-resolves it on every
// wake (auto-relay.ts, "Only adopt a resolved id") and register-peer itself falls
// back to the channel session id on an unresolved resolution.
// - `peerId` in the credential is the CONSENT SIGNAL. create/join write credentials
// without one, and deregister clears it, so a deliberate departure is never undone.
//
// ── WHY WE DO NOT JUST ANNOUNCE ─────────────────────────────────────────────
// Reap signal 4 skips any ANNOUNCED pid, reasoning that an announced bridge is 3.23.4+
// and stands down by itself. Announcing WITHOUT registering would make every leftover
// immortal: exempt from reaping, yet never superseding itself (supersession is only
// consulted on a wake, which a bridge with no peer never gets). The invariant is "a live
// bridge either REGISTERS — and so announces and can stand down — or it stays reapable."
// Restoring presence registers, so the announce it performs is correct.
// ---------------------------------------------------------------------------
import { logger } from "../logger.js";
/**
* Automatic presence restore. ON by default — a default-off self-heal heals nobody.
* Opt out with COGENT_AUTO_PRESENCE=false to observe the state without acting on it.
*/
export function autoPresenceEnabled(env = process.env) {
const v = env.COGENT_AUTO_PRESENCE;
if (v === undefined || v === "")
return true;
return !/^(0|false|no|off)$/i.test(v.trim());
}
/**
* Determine this agent's presence and, when it is `offline` with a peer it owns,
* bring it back `online`.
*
* NEVER THROWS. Runs fire-and-forget after the MCP transport connects — the
* `initialize` handshake must never wait on I/O (scripts/startup-nonblocking-test.mjs).
*/
export async function restorePresence(deps) {
try {
if (!deps.isCloudConfigured()) {
return { state: "local", restored: false, detail: "local mode — presence does not apply" };
}
if (deps.alreadyRegisteredInProcess()) {
return { state: "online", restored: false, detail: "registered by this process" };
}
const creds = await deps.loadCredentials();
if (!creds || !creds.endpoint || !creds.sessionId || !creds.token) {
return {
state: "deferred",
restored: false,
detail: "no stored channel credentials for this working directory — join a channel first",
};
}
if (!creds.peerId) {
// Credentials WITHOUT a peerId: created by join/create, or cleared by a deliberate
// deregister. Either way this agent is not meant to be in the channel right now.
return {
state: "deferred",
restored: false,
detail: "channel credentials exist but name no peer — nothing was registered here",
};
}
const peerId = creds.peerId;
// Someone live is already this peer. Registering again would take the identity from them.
if (deps.peerAlreadyServed(peerId)) {
return {
state: "online",
restored: false,
detail: `peer '${peerId}' is already served by a live bridge for this working directory`,
};
}
if (!autoPresenceEnabled(deps.env ?? process.env)) {
// Report the state, take no action. This is the "observe, do not act" mode.
return {
state: "offline",
restored: false,
detail: `peer '${peerId}' is not registered and COGENT_AUTO_PRESENCE is off — this agent is absent from its channel`,
};
}
await deps.goOnline({
peerId,
endpoint: creds.endpoint,
sessionId: creds.sessionId,
token: creds.token,
cwd: deps.cwd(),
// 🔴 THE PEER'S DISPLAY LABEL IS NOT PERSISTED ANYWHERE — only the CHANNEL's is,
// in credentials.label (create-session.ts writes `label: data.label`; join-session
// writes the resolved channel label). Using that would label the agent after the
// channel: a restore once put "paymentorchestrator" beside a sibling called "POFE".
// peerId is the one identifier we hold that genuinely names this agent. The
// operator's chosen label returns on the next cogent_register_peer, which carries it.
label: peerId,
// 🔴 WITHOUT THIS THE RESTORE CANNOT RECLAIM ITS OWN PEER. A re-join issues a NEW
// token, and AUD-003 ownership is proven by the token that CREATED the peer or by
// the secret issued with it. Omitting it means an entry owned by an earlier token
// answers PEER_NOT_YOURS and the agent stays offline — precisely the state this
// module exists to leave. The secret is in the credential file; send it.
peerSecret: creds.peerSecret,
});
return {
state: "online",
restored: true,
peerId,
// Says what THIS process did. Whether the relay now lists the peer is the relay's
// state, and asserting it from here would be a success nobody measured.
detail: `re-registered peer '${peerId}' from stored credentials`,
};
}
catch (err) {
const reason = err instanceof Error ? err.message : String(err);
return {
state: "offline",
restored: false,
detail: `presence restore failed: ${reason}`,
};
}
}
/**
* Last evaluated presence, so cogent_health_check can report the agent's own state
* without re-probing the relay.
*
* It lives HERE, in the leaf module, and not in startup.ts: a tool importing startup.ts
* creates an import cycle (tools -> startup -> tools) and the imported binding reads back
* `undefined` at call time. That cost 26 health-check tests once; do not move it.
*/
let lastPresence = null;
/** Record the evaluated presence. Called by startup after each evaluation. */
export function setPresence(outcome) {
lastPresence = outcome;
}
/** The agent's own view of its channel presence. Null until first evaluated. */
export function getPresence() {
return lastPresence;
}
/** Report the outcome once, at a level that matches how much it matters. */
export function logPresence(outcome) {
if (outcome.state === "online" && outcome.restored) {
logger.info(`Presence: offline -> online — ${outcome.detail}. This agent is addressable on its ` +
`channel again, and leftover bridges for this checkout are now reapable.`);
}
else if (outcome.state === "offline") {
logger.warn(`Presence: OFFLINE — ${outcome.detail}.`);
}
else {
logger.debug(`Presence: ${outcome.state} — ${outcome.detail}.`);
}
}
//# sourceMappingURL=peer-presence.js.map