Skip to main content

Thin Python client for the RiskKernel reliability runtime (Surface 2).

Project description

riskkernel (Python SDK)

The Python SDK for RiskKernelSurface 2, deep control over a governed agent run.

It is a thin client over the self-hosted RiskKernel daemon. Every deterministic decision — budgets, loop/time halts, approval policy — happens in the Go core. The SDK just makes governed runs ergonomic from Python. Core install is stdlib-only (no third-party dependencies).

pip install riskkernel

Quickstart

import riskkernel as rk

rt = rk.Runtime(base_url="http://localhost:7070")  # your daemon

with rt.governed_run(name="research",
                     budget=rt.budget(dollars=1.00, loops=20, seconds=300)) as run:
    # Route your LLM client through the governing proxy so every model call is
    # metered, priced, and budget-enforced under this run:
    cfg = run.proxy_config()
    #   cfg["base_url"]  -> http://localhost:7070/v1
    #   cfg["headers"]   -> {"X-RiskKernel-Run-Id": "<run id>"}

    for _ in range(100):
        run.step()                      # raises rk.BudgetExceeded when loops/time run out
        # ... your agent reasoning + tool calls ...
        run.checkpoint("after-step", {"messages": messages})

When the governor halts the run (token / dollar / loop / time budget), the next run.step() — or a proxied model call — raises rk.BudgetExceeded.

Resume after a crash

The daemon reloads non-terminal runs on restart with the budget and usage they had already spent, so a SIGKILL'd run keeps enforcing without re-spending. Reattach to it by id with resume_run and pick your work back up from the last checkpoint:

with rt.resume_run(run_id) as run:          # attaches; never creates or cancels
    cp = run.latest_checkpoint()            # the state you saved before the crash
    start = cp["payload"]["cursor"] if cp else 0
    for i in range(start, total):           # skip the steps you already paid for
        run.step()                          # counts against the SAME budget
        # ... your work ...
        run.checkpoint("step", {"cursor": i + 1})

The run resumes against whatever budget it had left, so it can't overspend by restarting — run.step() still raises rk.BudgetExceeded at the original ceiling.

Human-in-the-loop tools

Gate side-effecting tools on human approval (the daemon's policy decides what needs it; the call blocks until a human resolves it via CLI / web / webhook):

from riskkernel import governed_tool, ApprovalGate

@governed_tool(side_effect="write")
def write_file(path, content):
    ...                                  # only runs if approved; else rk.ApprovalDenied

# or explicitly:
gate = ApprovalGate(run)
if gate.allow("mcp://shell", side_effect="exec", arguments={"cmd": cmd}):
    run_shell(cmd)

Framework adapters

Lazy-imported, so you only pay for what you use:

# LangChain / LangGraph — enforces loop/time budgets per LLM call
from riskkernel.adapters.langchain import RiskKernelCallbackHandler
llm.invoke(prompt, config={"callbacks": [RiskKernelCallbackHandler(run)]})

# Claude Agent SDK — PreToolUse approval hook
from riskkernel.adapters.claude_agent import make_pre_tool_use_hook
hook = make_pre_tool_use_hook(run, side_effect_for={"Bash": "exec", "Write": "write"})

# OpenAI Agents SDK — RunHooks (steps + tool approval)
from riskkernel.adapters.openai_agents import RiskKernelRunHooks
hooks = RiskKernelRunHooks(run, gate_tools=True)

Configuration

Runtime(base_url=..., token=...), or the env vars RISKKERNEL_BASE_URL and RISKKERNEL_API_TOKEN (used by the decorator/convenience API and default_runtime()).

License

Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

riskkernel-0.3.0.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

riskkernel-0.3.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file riskkernel-0.3.0.tar.gz.

File metadata

  • Download URL: riskkernel-0.3.0.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for riskkernel-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4af46674a22e148d7b64f6b8ef9c43369da1b7b43ba4fcb504645a9d6c769906
MD5 0b4998ad5928bb50fe2f1a514140b4b9
BLAKE2b-256 10c84e81182b2d23214c5bef08ccb19c62629dfc41730017c2ab3dc11631303e

See more details on using hashes here.

Provenance

The following attestation bundles were made for riskkernel-0.3.0.tar.gz:

Publisher: python-publish.yml on prashar32/riskkernel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file riskkernel-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: riskkernel-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for riskkernel-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a92c89b74c0df11a130af1b7d5476fc6d563b88197d891b7542d58cb74a2fc8f
MD5 70caacdc12995d844e1ab9e27e20b9fc
BLAKE2b-256 13fd1ad8fc1355f1f31592ff6700f8864bdb1fd1b6090395610b3757150771f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for riskkernel-0.3.0-py3-none-any.whl:

Publisher: python-publish.yml on prashar32/riskkernel

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page