Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 45 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,39 @@ RiskKernel is a **self-hosted agent reliability runtime** — the deterministic,

It is **not** another gateway (LiteLLM/Portkey own routing), **not** another observability dashboard (Langfuse/Phoenix own traces), and **not** a content-guardrails engine (Guardrails AI/NeMo own PII/jailbreak). It interoperates with all of those and competes on the one thing nobody ships in a single self-hosted binary: **deterministic run controls** — the agent SRE layer.

## See it work first

If you only try one thing, run the no-key Docker demo. It starts a mock LLM, sends
a deliberately runaway "agent" through RiskKernel, and stops at the hard loop
budget with HTTP 402. No provider key, no local Go/Python setup:

```bash
cd examples/quickstart-compose
docker compose up
```

Expected shape:

```text
call 1 -> 200 OK
call 2 -> 200 OK
call 3 -> 200 OK
call 4 -> 200 OK
call 5 -> 200 OK
call 6 -> HTTP 402 RiskKernel HALTED the run:
{"code":"loop_budget_exceeded", ...}
```

The second proof is crash recovery: kill the daemon halfway through a run, restart
it, and the agent resumes at step 6 with the governor still counting the 5 steps
already spent.

<div align="center">
<img src="examples/kill-9-resume/resume.gif" alt="RiskKernel crash-resume demo: a run does 5 steps, the daemon is killed, the run resumes at step 6, and the final loop counter is 10 instead of 15" width="820">
<br/>
<sub><b>A crashed run resumes without re-spending.</b> The daemon is killed after step 5; restart reloads the run, resumes at step 6, and the final loop counter is 10, not 15. (<a href="examples/kill-9-resume">runnable example</a>)</sub>
</div>

## What it does

| Capability | What it means |
Expand All @@ -49,6 +82,18 @@ It is **not** another gateway (LiteLLM/Portkey own routing), **not** another obs
2. **SDK (deep control).** `pip install riskkernel` (Python) or `npm install @riskkernel/sdk` (TypeScript), then governed runs, per-step loop/time budgets, checkpoints, and approval gates. Framework adapters for the Claude Agent SDK, OpenAI Agents SDK, LangChain, LlamaIndex, CrewAI, AutoGen, and PydanticAI (Python), and the Vercel AI SDK (TypeScript).
3. **OpenTelemetry (universal).** RiskKernel is an OTLP endpoint *and* emitter — ingest GenAI spans (`POST /v1/traces`) to meter apps already instrumented with OpenLLMetry / the OpenAI Agents SDK / the Vercel AI SDK, and export cost/halt/tool spans to the backend you already run.

## Pick a demo

| You want to see | Run this | What it proves |
|---|---|---|
| **A runaway agent stopped** | [`examples/quickstart-compose`](examples/quickstart-compose) | A hard loop budget halts a runaway app with no API key. |
| **Crash recovery** | [`examples/kill-9-resume`](examples/kill-9-resume) | `kill -9` cannot reset the meter or make completed work run twice. |
| **A real agent loop halted** | [`examples/codebase-qa`](examples/codebase-qa) | A codebase QA agent loops until RiskKernel stops it on budget. |
| **Wrap an existing Python loop** | [`examples/wrap-your-agent`](examples/wrap-your-agent) | The SDK caps plain Python control flow in two minutes. |
| **LangChain integration** | [`examples/langchain`](examples/langchain) | A LangChain callback binds steps to a governed run. |
| **MCP tool governance** | [`examples/mcp`](examples/mcp) | Tool allowlists, approval gates, and audit trails work before the tool executes. |
| **Observability dashboards** | [`examples/otel`](examples/otel) | Cost, budget, halt, and tool spans land in your OTel backend. |

## Quickstart (60 seconds)

> **No key, one command?** [`examples/quickstart-compose`](examples/quickstart-compose)
Expand Down Expand Up @@ -128,25 +173,6 @@ npm install @riskkernel/sdk # TypeScript → sdks/typescript
See [`sdks/python`](sdks/python) and [`sdks/typescript`](sdks/typescript). Trace
every run in your own backend: [`examples/otel`](examples/otel).

Want to *see* the headline feature? [`examples/codebase-qa`](examples/codebase-qa)
is a runnable agent that loops over a codebase until the governor kills it on its
loop/dollar budget — the deterministic kill, end to end, with a real model.

And the moat: [`examples/kill-9-resume`](examples/kill-9-resume) `kill -9`s the
daemon mid-run and resumes without re-spending — `./demo.sh` scripts the whole
crash-and-recover and proves the counter doesn't double, key-free.

Brand new to the SDK? [`examples/wrap-your-agent`](examples/wrap-your-agent) is the
no-key, two-minute version — a generic Python loop the governor caps at a loop
budget, the deterministic kill with nothing running but the daemon.

On LangChain? [`examples/langchain`](examples/langchain) wraps a LangChain loop
with the callback handler and caps it at a loop budget — also key-free.

Governing tools over MCP? [`examples/mcp`](examples/mcp) puts the MCP gateway in
front of a stub server and shows a tool blocked by the allowlist, a side-effecting
tool held for approval, and the audit trail — key-free.

Hit a snag? `riskkernel doctor` diagnoses most setups, and the
[troubleshooting guide](docs/TROUBLESHOOTING.md) maps the common errors —
missing key, port in use, the expected 402 budget halt — to fixes.
Expand Down
29 changes: 29 additions & 0 deletions examples/kill-9-resume/resume.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{"version":3,"term":{"cols":80,"rows":24,"type":"dumb"},"timestamp":1781988638,"command":"env PYTHONPATH=../../sdks/python RK_WORK_SECONDS=0.05 RISKKERNEL_BIN=../../riskkernel ./demo.sh","env":{"SHELL":"/bin/zsh"}}
[0.024, "o", "── 1. start the daemon ────────────────────────────────────────────────\r\n"]
[0.289, "o", " up (pid 93623)\r\n\r\n── 2. agent does 5 of 10 steps, checkpointing each ────────────────────\r\n"]
[0.152, "o", "▶ FRESH run 087cd4c2-3a96-4496-9184-4c2547c4b7d0 (budget: loops=50)\r\n\r\n"]
[0.057, "o", " step 1/10 done (checkpointed cursor=1)\r\n"]
[0.054, "o", " step 2/10 done (checkpointed cursor=2)\r\n"]
[0.057, "o", " step 3/10 done (checkpointed cursor=3)\r\n"]
[0.054, "o", " step 4/10 done (checkpointed cursor=4)\r\n"]
[0.058, "o", " step 5/10 done (checkpointed cursor=5)\r\n\r\n⏸ did 5 steps, then stopping (the demo crashes the daemon here).\r\n"]
[0.009, "o", "\r\n"]
[0.000, "o", "── 3. kill -9 the daemon (a hard crash — no graceful shutdown) ───────\r\n"]
[0.507, "o", "./demo.sh: line 44: 93623 Killed: 9 RISKKERNEL_DATA_DIR=\"${DATA}\" RISKKERNEL_PORT=\"${PORT}\" \"${BIN}\" serve >> \"${DATA}/serve.log\" 2>&1\r\n"]
[0.000, "o", " daemon killed. restarting it…\r\n"]
[0.290, "o", " ✓ time=2026-06-21T02:20:40.200+05:30 level=INFO msg=\"resumed runs from store\" count=1\r\n"]
[0.000, "o", "\r\n"]
[0.000, "o", "── 4. re-run the agent: it RESUMES and finishes ───────────────────────\r\n"]
[0.064, "o", "↻ RESUMING run 087cd4c2-3a96-4496-9184-4c2547c4b7d0\r\n the governor already counts 5 spent steps — resuming at cursor 5, not redoing them.\r\n\r\n"]
[0.055, "o", " step 6/10 done (checkpointed cursor=6)\r\n"]
[0.055, "o", " step 7/10 done (checkpointed cursor=7)\r\n"]
[0.054, "o", " step 8/10 done (checkpointed cursor=8)\r\n"]
[0.057, "o", " step 9/10 done (checkpointed cursor=9)\r\n"]
[0.057, "o", " step 10/10 done (checkpointed cursor=10)\r\n"]
[0.001, "o", "\r\n✅ completed all 10 steps. governor loop counter = 10 — exactly one per step of work. The steps finished before the crash were neither redone nor re-paid.\r\n"]
[0.009, "o", "\r\n"]
[0.000, "o", "── 5. proof — the run did 10 steps total across the crash, not 15 ─────\r\n"]
[0.012, "o", "ID NAME STATUS TOKENS DOLLARS LOOPS HALT CREATED\r\n087cd4c2-3a96-4496-9184-4c2547c4b7d0 kill-9-resume running 0 0.0000 10 - 2026-06-20 20:50:39\r\n"]
[0.001, "o", "\r\n"]
[0.000, "o", " loops = 10 (one per step of work). Re-running from zero would read 15.\r\n"]
[0.005, "x", "0"]
Binary file added examples/kill-9-resume/resume.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading