Python.

The reference implementation. A local OpenAI-compatible proxy you launch in front of the upstream you already call, plus the controller itself.

Install from PyPI

gubernaut-sdk
pip install gubernaut-sdk

Adoption

one line
client = OpenAI(base_url="http://localhost:8000/v1")

This is the only line that changes in your code. The proxy has to be running first.

Free and Apache-2.0, version 1.0.1, running entirely on your machine. View on PyPI Read the source

01 · Quickstart

How do I use it once it is installed?

Point your existing client at the local proxy and change nothing else. Every turn then passes the controller, which reads intensity, valence, repetition and holds a posture. A saturating loop is hard-stopped at turn 4.

main.py
from openai import OpenAI
from gubernaut_sdk import launch_proxy

# 1. start the governor in front of your upstream
launch_proxy(upstream="https://api.openai.com", port=8000)

# 2. one line of adoption
client = OpenAI(base_url="http://localhost:8000/v1")

# 3. nothing else changes. every turn now passes the controller.
resp = client.chat.completions.with_raw_response.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "hello"}],
)
print(resp.http_response.headers.get("x-gcc-posture"))  # DEFAULT | INHIBIT | REGROUND

02 · Notes

Python specifics

Which attribute do I set?

Set base_url on the client, as client = OpenAI(base_url="http://localhost:8000/v1"). The pre-v1 openai.api_base attribute is ignored silently by current OpenAI SDKs, so a request configured that way goes straight to the upstream ungoverned and nothing errors to tell you. The proxy listens on port 8000 by default.

Why does the module-level openai.base_url return 404?

The module-level attribute needs a trailing slash and the client argument does not. Measured against openai 2.52.1: openai.base_url = "http://localhost:8000/v1/" returns 200, while the same string without the trailing slash builds a request to /v1chat/completions and returns 404. Setting base_url on the client object works either way, which is why every worked example in the repository uses that form.

Does it work with LangChain and LlamaIndex?

Yes. Both accept a base URL on their OpenAI client, so pointing that at the proxy is the whole integration. Worked demos for LangChain, LlamaIndex and AutoGen ship in the repository under wrappers.

What runs in-process versus over the wire?

The controller decision is in-process and allocation-light. The proxy hop is a local HTTP call. If you only want the decision and not the proxy, gubernaut-core exposes the controller on its own in Rust and @gubernaut/core does the same in JavaScript, both with no network involved.

03 · Why bother

What does the governor actually save?

On a saturating loop the governed arm cut upstream spend by up to 95.9%. That ceiling is one measured run: gpt-5.6-sol at $0.1669 ungoverned, down to $0.0068 governed. Over seven measured configurations across four model families the reduction ranged 79.8% to 95.9%. Both arms made the same number of attempts, so the delta is the measurement.

Source: Pre-registered receipts benchmark, 2026-07-19. Scored output of harness/report.py.

04 · Other runtimes

Other languages

The same controller ships for three runtimes. They share the deciding core, so a posture decision is identical whichever one you run.

Last reviewed 2026-08-07 · paper arXiv 2607.24339, DOI 10.5281/zenodo.21303518