UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

110 lines (109 loc) • 4.18 kB
import { type Computer } from "./computer-identity.js"; import { type HookPeer } from "./peers.js"; import { type Json } from "./protocol.js"; import type { SetName } from "./conductor-role.js"; /** * Linked computer sets (docs/conductor-sets.md). A link runs both ways when * each computer's hooks.yaml lists the other; a set is the computers joined by * such links. This Hook sees its set from itself and one hop: each peer * answers `GET /v1/conductor` with its live conductor, its own peers, whether * it lists the caller back and the set name it holds. A set has one conductor. */ type Ask = (peer: HookPeer, route: string, data?: Json, timeout?: number) => Promise<Json>; /** What this computer tells a peer about itself, so the peer can say whether it links back. */ export interface Caller { name: string; hostKey?: string; } export declare function localCaller(): Promise<Caller>; export declare function callerQuery(caller: Caller): string; /** One peer's answer to `GET /v1/conductor`, or why it gave none. */ export type PeerAnswer = { peer: HookPeer; } & ({ ok: true; id?: string; names: string[]; conductor?: Json; /** Its hooks.yaml names; absent from a Hook older than sets. */ peers?: string[]; /** Whether it lists this computer back; absent when its Hook cannot say. */ knowsCaller?: boolean; set?: SetName; } | { ok: false; error: string; code?: string; /** Its conductor module is off, so it cannot run a conductor. */ disabled?: boolean; }); export declare function askPeers(peers: readonly HookPeer[], caller: Caller, ask?: Ask): Promise<PeerAnswer[]>; export interface GroupConductor { /** A live conductor on a member of this computer's set. */ found?: { computer: string; target?: Json; }; /** Members that could not say, so a conductor there cannot be ruled out. */ unchecked: { computer: string; error: string; code?: string; }[]; } /** The names members report that are neither this computer nor one of its * peers: computers in the set that this Hook cannot ask directly. */ export declare function indirectMembers(answers: readonly PeerAnswer[], localNames: readonly string[]): string[]; export declare const linkHint: (name: string) => string; export declare const oneWayHint: (name: string) => string; /** One conductor per set: a live conductor on any member, and the members that could not say. */ export declare function setConductor(answers: readonly PeerAnswer[], localNames: readonly string[]): GroupConductor; export declare function groupConductor(peers: readonly HookPeer[], localNames: readonly string[], ask?: Ask, caller?: Caller): Promise<GroupConductor>; export interface SetComputer { name: string; id?: string; local?: true; /** Whether its Hook answered just now; absent when this Hook cannot ask it. */ reachable?: boolean; link: "self" | "two-way" | "one-way" | "indirect" | "unknown"; conductor?: Json; error?: string; code?: string; hint?: string; } export interface ComputerSet { id: string; name?: string; namedAt?: string; /** This computer's own set. */ local: boolean; computers: SetComputer[]; /** The set's conductor; with `conductors` above 1, the first of several. */ conductor?: { computer: string; target?: Json; }; conductors: number; } /** * Every set this Hook can see: its own (itself, its two-way and not yet known * peers, and computers they link that this Hook does not), then one set per * one-way peer. `unlinked` are computers the store knows with no link here. */ export declare function buildSets(input: { local: { name: string; id?: string; conductor?: Json; set?: SetName; names: readonly string[]; }; answers: readonly PeerAnswer[]; computers: readonly Computer[]; /** Identity rows from peers, used only to recognize names in their set reports. */ reportedComputers?: readonly Pick<Computer, "id" | "name" | "aliases">[]; }): { sets: ComputerSet[]; unlinked: Computer[]; }; export {};