Skip to main content

agent-junction

Failover and credential-routing for AI agent stacks. When one of your AI coding agents dies — quota exhausted, key rate-limited, service down — the junction detects it with a real probe, switches your work to a healthy standby, and fails back when the primary recovers. The decision to switch can be delegated to a zero-token classifier that holds on transient blips and switches on real collapse.

   priority 0 (primary)          priority 1 (standby)
  ┌────────────────┐  collapse  ┌────────────────┐
  │  agent "hermes"│ ─────────► │ agent "opencode"│
  │  probe: tcp+proc│ ◄───────── │  probe: command │
  └────────────────┘  recovered └────────────────┘
              ▲                         ▲
              └───── junction tick ─────┘
              (cron every N minutes; no daemon required)

Why

Anyone running two or more agent systems (OpenCode, Claude Code, Codex, Gemini CLI, custom agents) eventually hits the same failure: an API key runs out mid-task and work silently stops until a human notices. The junction is the layer that notices for you — and it is agent-agnostic: it doesn't care what your agents are, only how to prove they're alive.

Capability Naive alternative agent-junction
Health check --version ping (proves nothing) live model round-trip, TCP probe, process scan
Failover decision flip on first missed ping optional zero-token gate classifies transient vs fatal
Safety router failure = no failover gate can delay a switch, never block one (streak bypass + fail-safe)
Forensics "why did it switch?" JSONL diagnostics + switch counter + calibrated decision trail
Ops model another daemon to babysit one bounded cron tick; no process to keep alive

Install

pip install agent-junction            # from PyPI (once published)
pip install "agent-junction[psutil]" # with process-probe support

# or straight from the repo:
pip install "git+https://github.com/hypnoticproductions/agent-junction.git"

Quick start

  1. Write a config (see junction.example.json):
{
  "agents": [
    { "name": "hermes", "priority": 0, "tcp": "127.0.0.1:9119" },
    { "name": "opencode", "priority": 1,
      "command": ["opencode", "run", "--format", "json", "--model", "your/model", "Reply with the single word OK."],
      "expect": "OK" }
  ],
  "fail_streak_limit": 3,
  "state_file": "junction-state.json"
}
  1. Probe and inspect:
junction --config junction.json status
junction --config junction.json doctor
  1. Schedule the bounded tick (cron, Task Scheduler, systemd timer):
*/5 * * * *  junction --config /etc/junction/junction.json tick
*/5 * * * *  junction --config /etc/junction/junction.json failback

The tick is a single pass: probe active → maybe switch. No daemon, no event loop, nothing to keep running between passes. Crashes are free.

The decision gate

By default every failure switches immediately (ImmediateSwitchGate). If you run a System One / Laya escalation head, the junction will consult it first:

"decision_gate": { "type": "laya", "module_path": "C:/path/to/chain", "escalate_threshold": 0.85 }

Two invariants hold no matter what the gate says:

  1. A gate can delay, never veto. If the gate holds but the agent keeps failing, the streak counter force-switches after fail_streak_limit consecutive failures (~15 min at a 5-minute cadence).
  2. Gate failure = switch. Any exception, missing chain, or placeholder decision resolves to switch. The decision layer is an optimization, not a dependency.

Probes

Probe Config key Proves
TCP "tcp": "host:port" a service is listening
Process "process": {"name": "...", "exe_contains": "..."} the daemon is running
Command "command": ["...", ...], "expect": "OK" end-to-end: binary, credentials, backing API

Stack probes on one agent for cheap-to-expensive checking: the first listed is primary; the rest are fallbacks tried only when the primary fails.

Credentials

The junction never stores or logs credentials. Command probes inherit your environment; load keys from your secret store in the cron wrapper, or point command at a wrapper script that injects them. No key ever appears in state, diagnostics, or the repo.

Development

pip install -e ".[test,psutil]"
pytest

Releasing

CI runs the test matrix (3 OSes × 4 Pythons) on every push. To publish a release to PyPI:

  1. Register the pending publisher once at pypi.org/manage/account/publishing — owner hypnoticproductions, repo agent-junction, workflow publish.yml (trusted publishing, no tokens stored anywhere).
  2. Bump version in pyproject.toml, commit, then tag and push: git tag v0.1.0 && git push origin v0.1.0
  3. The publish workflow runs tests, builds, checks, and publishes. Users then pip install agent-junction.

Until PyPI publishing is registered, users can install directly:

pip install "git+https://github.com/hypnoticproductions/agent-junction.git"

License

MIT

Metadata

Release files for agent-junction 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-junction 0.1.0
File Size Uploaded
agent_junction-0.1.0.tar.gz 17.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-junction 0.1.0
File Interpreter ABI Platform
agent_junction-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.2 kB

Release files / agent_junction-0.1.0.tar.gz

Download URL agent_junction-0.1.0.tar.gz
Size 17.6 kB
Tags Source
SHA-256 checksum
How to use checksums
75b53d7e12025a090f0cc70e82bfe00da68ebf8985abed72f738ba5df22adcc6
BLAKE2b-256 checksum
How to use checksums
afdd68b5fbd754d698ff38674fbe00263d05e017cd5931d71e0b5891fe8702fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / agent_junction-0.1.0-py3-none-any.whl

Download URL agent_junction-0.1.0-py3-none-any.whl
Size 14.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3d1bdcc682272a39eb62be4c514ca836488d8966e9a92bce3448dfcb50f16bcd
BLAKE2b-256 checksum
How to use checksums
82cfddbc7f396e3ced7a5c37ad11c9c959d208e7269f2b1aeb369c1d6fd5aae9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page