/** * Does the CALLING host's own LLM traffic reach this relay? * * `/dispatch` hands back an ordered ladder of lanes, and one rung kind — `relay` — assumes the * host can address a spec through this proxy as a subagent. That assumption is false in a Claude * Desktop session: the launcher pins `ANTHROPIC_BASE_URL=https://api.anthropic.com` into the * process environment, overriding both the User-scope variable and the `env` block of * `~/.claude/settings.json`. Every subagent-reroute mechanism then silently no-ops — the request * never arrives, so `routing.subagents` cannot fire and an `@relay:` directive reaches the real * Anthropic model as literal prompt text with nothing in the path to strip it. * * ⚠ **This must be evaluated in the CLI process, never in the server.** The relay cannot detect a * bypassing host at request time because there is no request — that is the entire problem. The * `llm-relay` CLI, by contrast, is a child of the session and inherits its environment. The server * was launched from `Startup` at logon, long before any session existed, so reading `process.env` * there answers a different question. The CLI computes the verdict and forwards it * (`GET /dispatch?host=…`); `buildDispatch` takes it as an argument and never sniffs for it. */ /** * `routed` — the host's traffic reaches a loopback proxy, so relay rungs work as written. * `bypassed` — it does not; anything needing the subagent-reroute path is dead for this host. * `unknown` — not a Claude harness at all, so there is no subagent mechanism to adapt to. */ export type HostRoutingState = "routed" | "bypassed" | "unknown"; export interface HostRouting { state: HostRoutingState; /** Harness name, for the MESSAGE only (`claude-desktop`). Never used to decide — see below. */ entrypoint: string | null; /** Why `state` is what it is, in the operator's terms. */ reason: string; } /** Values `host-routing` accepts as an explicit override (`llm-relay dispatch --host …`). */ export declare function parseHostRoutingState(value: string | undefined): HostRoutingState | null; /** * Classify the calling host from its environment. * * The load-bearing signal is the base URL, NOT the entrypoint name. Deciding on * `CLAUDE_CODE_ENTRYPOINT === "claude-desktop"` would miss a terminal session that dropped its * env line (equally bypassed, for a different reason) and would break the moment the vendor * renames the entrypoint. The entrypoint is carried only so the message can say *which* host. */ export declare function detectHostRouting(env?: NodeJS.ProcessEnv): HostRouting;