Model or dataset
Arcadia-1/virtuoso-bridge-lite avatar
Arcadia-1/virtuoso-bridge-lite

virtuoso-bridge-lite puts Virtuoso behind a CLI, then splits the GUI host from the daemon host

Bridge between LLM-Agent and Cadence Virtuoso. A new infrastructure for Agentic Analog and Mixed-Signal Design.

780 stars173 forksPythonMIT

At a glance

What is it?
A Python bridge that lets a coding agent drive Cadence Virtuoso over SSH and run Spectre from netlists. Its configuration comes from three places that do not agree on precedence: a discovered .env, CIW process variables, and role variables for a two host installation.
Who is it for?
This suits an agent driven analog design flow where the agent needs schematic, layout, Maestro and Spectre steps in one place and the EDA tools already sit on a licensed server. Three things to settle before wiring it in.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Env discovery walks up parent directories and loads with override

Python entry points look for the nearest parent `.env` that contains a bridge host role, which means `VB_REMOTE_HOST`, `VB_GUI_HOST`, `VB_DAEMON_HOST` and the related roles, or a `VB_LOCAL_PORT` value. That file is then loaded with `override=True`. Two consequences follow, and both are stated in the documentation rather than left to be discovered. First, the file that wins is whichever qualifying `.env` sits nearest, not one you named, so a stray file in a working directory can take precedence over the one you wrote. Second, because the load overrides, a long-lived process can change from local to remote mode without being restarted. When embedding the bridge in your own code, pin the intended file before constructing a client:

python
from virtuoso_bridge.env import set_runtime_env_file

set_runtime_env_file("/path/to/virtuoso-bridge.env")

Calling that first turns directory discovery off, which is the difference between a deterministic client and one whose mode depends on where it was launched from.

Two RB settings belong to the Virtuoso process, not the bridge env

Daemon IPC logging is off by default. Turning it on means setting `RB_LOG_ENABLED=1` in the environment that launches the Virtuoso process, with `RB_LOG_PATH` optionally choosing the file. When that path is unset or empty, the log is written as `ramic-bridge.log` in Virtuoso's own working directory. The file name is worth pausing on, since it does not match the project name anywhere else in this repository, where the distribution is called virtuoso-bridge.

The category of these two variables is the part that trips people up. They are CIW process variables, not bridge `.env` settings, and changing them has no effect on a Virtuoso process that is already running. The monitoring interface has its own logging toggle, and that one behaves differently again: it uses the configured path and restarts only the bridge daemon. So the same word logging covers an operation that needs Virtuoso relaunched and an operation that only bounces the daemon.

The nonce cache refuses new work rather than dropping replay marks

The daemon keeps signed request nonces in memory so it can reject replays, and its default capacity is 4096. What happens when that fills is the design decision worth knowing: the daemon rejects new requests rather than discarding live replay marks. That is the safe direction to fail, since evicting a live mark would weaken replay protection, but it also means a burst above the default produces refused work instead of degraded protection.

Raising the ceiling means setting a positive integer such as `RB_NONCE_CACHE_MAX=8192` in the environment that launches Virtuoso, then restarting both Virtuoso and the bridge daemon. The documentation is explicit that this is a daemon side setting and not a client bridge `.env` setting, which is the same distinction as the logging variables above. The cost is stated too: a larger value uses more memory. There is no configuration path described for lowering it below the default, and no per client control, since the marks live where the requests are verified rather than where the requests are sent.

Two host roles, four variables, and a scratch path that is often wrong

`VB_REMOTE_HOST` is the simple one host setting. Where Virtuoso runs on a GUI or login host but `ipcBeginProcess()` launches the daemon on a compute host, the roles are set explicitly:

dotenv
VB_GUI_HOST=gui-host-a
VB_DEPLOY_HOST=gui-host-a
VB_DAEMON_HOST=compute-host-b
VB_SPECTRE_HOST=compute-host-b
VB_REMOTE_USER=user
VB_JUMP_HOST=gui-host-a

# Must be readable from the CIW and daemon host; /tmp is often isolated.
VB_REMOTE_SCRATCH_ROOT=/home/user/.virtuoso-bridge

The defaults put deployment on the GUI host and Spectre on the legacy or daemon host, and the shared jump host is suppressed automatically when the target is itself the jump host, so a single host setup needs no jump variable at all. The comment on the scratch root carries the operational warning: it must be readable from both the CIW host and the daemon host, and /tmp is often isolated between them. The `status` command reads a daemon identity file written from the CIW banner, which lets it diagnose a daemon and tunnel host mismatch even when the TCP endpoint points somewhere wrong.

Five setup paths, and only some of them need Virtuoso running

The setup table pairs each goal with what it costs. Driving Virtuoso on a remote EDA server needs SSH access, a running Virtuoso and a `load(...)` call in the CIW. Driving it on the same machine needs a running Virtuoso and `VB_REMOTE_HOST=localhost`. Running Spectre from netlists needs `spectre` on PATH, or `VB_CADENCE_CSHRC` pointing at a cshrc. Reproducible IC optimization workflows need a Spectre and OCEAN setup plus requirement files, delivered as an optimizer skill with an optional external workflow CLI. Letting a coding agent operate Cadence needs `skills/` linked into your agent's skill directory.

The two halves of the tool are separable, and that is worth stating plainly: Virtuoso SKILL execution and Spectre simulation are independent. You can run Spectre without the SKILL bridge, and you can use the SKILL bridge without Spectre. So a team that only wants netlist simulation does not need a Virtuoso licence in the loop, and a team driving the GUI does not need Spectre on PATH. Inside the GUI side, control spans Schematic, Layout, Maestro and Spectre, with four design domains underneath that.

Windows OpenSSH ControlMaster is why Paramiko is an extra

OpenSSH `ControlMaster` is not usable with every Windows SSH build, which is the stated reason a second transport exists. For real multi session multiplexing inside one bridge process, the Paramiko backend has to be installed and selected explicitly, and it lives in an optional dependency group:

code
ssh = ["paramiko>=3.5", "PySocks>=1.7.1"]

Selecting it explicitly is the part that is not automatic. The stated benefit is avoiding Windows OpenSSH ControlMaster limitations while keeping local mode lightweight, so a developer on a working ControlMaster setup can stay on OpenSSH and only switch when multiplexing actually fails.

The optional groups also draw a boundary around a second integration. The Visio export drives Microsoft Visio through COM and is Windows only, gated on pywin32 with a sys platform marker, while the model layer underneath it in `virtuoso/visio.py` has no extra dependencies and stays importable everywhere. A third group, dev, pulls pytest along with the same Paramiko and PySocks pair, so the transport suite is exercised in a complete test environment.

Bootstrap refuses any window it cannot identify as a CIW

If the daemon has not been loaded yet, a manual `load(...)` in the CIW remains valid and is still the normal path. The opt in alternative is an X11 bootstrap, and it is deliberately narrow. You select a window explicitly rather than having the tool pick one:

bash
virtuoso-bridge list-windows --top-level --json
virtuoso-bridge bootstrap --window 0x3000012

Two refusals define the shape of it. The command refuses windows that are not identified as a CIW, and it does not accept arbitrary SKILL text, meaning it injects only the setup command it generated. That is the difference between a convenience launcher and an arbitrary code path into a running EDA session, and the option list above it, `--top-level` and `--json`, is what you use to find a candidate window first. Elsewhere the same narrowness applies to schematic work, where SOS cellview control comes with explicit status, checkout, cancel checkout, checkin and initial registration, a dry run, post state verification, and an unknown result safety path.

The install path is a clone, a uv virtual environment, and three commands

Setup is four steps and none of them is a published package index step:

bash
# 0. Get the source
git clone https://github.com/Arcadia-1/virtuoso-bridge-lite.git
cd virtuoso-bridge-lite

# 1. Install in a virtual environment
uv venv .venv
source .venv/bin/activate
uv pip install -e .

# 2. Create ~/.virtuoso-bridge/.env
virtuoso-bridge init user@host [-J user@jump-host]
# Or: virtuoso-bridge init      # empty template; edit VB_REMOTE_HOST yourself

# 3. Start and verify
virtuoso-bridge start          # starts tunnel and prints the CIW load(...) line
virtuoso-bridge status         # tunnel + Virtuoso daemon + Spectre availability

Two details in there are load bearing. `start` prints the `load(...)` line rather than running it, so the injection stays a manual step you can paste, and `status` covers three separate things: the tunnel, the Virtuoso daemon, and whether Spectre is available. On Windows PowerShell the activation line becomes `.\.venv\Scripts\Activate.ps1`. The package itself declares Python 3.9 as its floor, with an eval type backport dependency applied only below 3.10, and the console entry point is a single command, virtuoso-bridge, wired to the CLI main function.

Editorial conclusion

This suits an agent driven analog design flow where the agent needs schematic, layout, Maestro and Spectre steps in one place and the EDA tools already sit on a licensed server. Three things to settle before wiring it in. Decide early whether you are running the one host setup or the split GUI and compute host one, because the discovery mechanism will happily switch a long-lived client from local to remote mode on its own. Keep the three configuration locations separate in your head: bridge roles come from .env, and the logging and nonce settings belong to the Virtuoso process and need a restart to take effect. And if your Windows SSH build is unreliable with ControlMaster, install the ssh extra before you try to run parallel sessions.

Frequently asked questions

How do I pin which .env file virtuoso-bridge uses?

Call set_runtime_env_file from virtuoso_bridge.env with the intended path before constructing a client, since entry points otherwise discover the nearest parent .env holding a bridge host role and load it with override enabled.

Where do the RB_LOG_ENABLED and RB_NONCE_CACHE_MAX settings go?

Both belong to the environment that launches the Virtuoso process rather than to the bridge .env, and changing them does not affect an already running Virtuoso process, so the daemon nonce cache needs both Virtuoso and the bridge daemon restarted.

What does virtuoso-bridge status actually check?

Three things, the tunnel, the Virtuoso daemon and Spectre availability, and it reads a daemon identity file written from the CIW banner so it can diagnose a daemon and tunnel host mismatch even when the TCP endpoint is wrong.

Does running Spectre through virtuoso-bridge require Cadence Virtuoso?

No. SKILL execution and Spectre simulation are independent, so Spectre can run from netlists without the SKILL bridge, with spectre on PATH or with VB_CADENCE_CSHRC set.

Why would I install the ssh extra for virtuoso-bridge?

Because OpenSSH ControlMaster is not usable with every Windows SSH build, and the ssh extra brings in Paramiko and PySocks for real multi session multiplexing inside one bridge process, selected explicitly rather than by default.

Official sources

  1. Arcadia-1/virtuoso-bridge-lite on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/arcadia-1-virtuoso-bridge-lite.svg)](https://hysenlabs.com/projects/arcadia-1-virtuoso-bridge-lite)