Skip to main content

upoch: Upoch Guard for Python agents

Give your Python agent a memory and an undo button.

Upoch Guard saves verifiable checkpoints of an agent's work on Robinhood Chain. If the agent crashes, gets a bad prompt or makes a bad trade, it restores the last good state, checked against the chain, or rolls back to the checkpoint before the mistake and keeps going. It also knows which of its actions already happened.

Website and debugger: https://upoch.tech. Contract (Robinhood Chain, 4663): 0x6179d9123c3c1f9e82f948101a4350cb55aa8c27

Setup

Once, in your own terminal. You need Node.js 24 or later, because the upoch command holds the keys and does the signing:

npm install -g @upoch/guard
upoch setup

upoch setup creates your keys in ~/.upoch, waits while you send the owner address a little ETH on Robinhood Chain (0.001 ETH is plenty), and registers your agent. Then:

pip install upoch                 # or: pip install "upoch[langchain]"

LangChain and LangGraph

One line: every consequential tool call (swaps, transfers, bridges, staking, lending, trades, mints, launches and approvals) is checkpointed before and after it runs. The pre-tool checkpoint is committed before the tool runs, with invoke and ainvoke.

from upoch.langchain import UpochCallbackHandler, upoch_tools

upoch = UpochCallbackHandler()

# Automatic checkpoints around consequential tool calls:
agent.invoke(inputs, config={"callbacks": [upoch]})

# Optional: let the model restore, checkpoint and roll back itself.
tools = [*your_tools, *upoch_tools(handler=upoch)]
Tool
upoch_restore Latest checkpoint, verified against the chain, and which actions completed
upoch_checkpoint Save the current state
upoch_rollback Go back to an earlier checkpoint and continue. By default, the one right before the last swap or transfer
upoch_history Recent checkpoints
upoch_complete Mark the task finished

Options:

UpochCallbackHandler(
    watch=["swap_tokens", "send_eth"],   # exact tool names, or a compiled regex (default: value-moving names)
    state=lambda: my_agent_state,        # what each checkpoint holds (default: the log of watched tool calls)
    strict=True,                         # stop the tool when its pre-tool checkpoint fails (default False)
)

Any Python agent

from upoch import Guard

with Guard() as guard:
    restored = guard.restore()            # where the last run stopped, verified against the chain
    state = restored.get("state") or {"step": 0}

    guard.record_action("swap-1", "swap", "planned", input={"sell": "WETH", "qty": 0.1})
    guard.checkpoint(state, note="before swap", kind="before_action")
    tx = do_the_swap()
    guard.record_action("swap-1", "swap", "confirmed", transaction_hash=tx)
    guard.checkpoint({**state, "step": 1}, note="after swap", kind="after_action")

    # Something went wrong? Go back to the checkpoint before it:
    guard.rollback(0, reason="the swap was the wrong size")
Method What it does On-chain
restore(sequence=None) Latest (or a given) checkpoint after verifying it: state, note, completed and unresolved actions read
checkpoint(state, note, kind) Saves the state (progress, before_action, after_action, manual) 1 transaction
record_action(...) Records an external action (planned, submitted, confirmed, failed) with its transaction hash no (goes into the next checkpoint)
rollback(sequence, reason) Goes back to an earlier checkpoint and continues from it; lists actions since then that were not undone on-chain 1 transaction
complete(state, note) Saves a final checkpoint and marks the run finished 1 transaction
history(limit) Recent checkpoints read
verify(sequence) Verifies one checkpoint without restoring it read
status() Workflow, executor funds and today's usage read

Each method returns the result as a dict. Refusals and errors raise upoch.UpochError (with a code).

A rollback restores the agent's state. It cannot reverse transactions that already happened on-chain; those are listed so the agent can account for them.

How it works

Guard starts the upoch mcp command from @upoch/guard and talks to it over stdio. That process holds the keys: it encrypts each checkpoint on your machine, stores it on IPFS, commits its fingerprint to the Upoch contract, and reads it back to verify it. Only someone with your checkpoint key can read it, and anyone can check that it has not been changed. Every checkpoint opens in the Time-Travel Debugger.

Settings live in UPOCH_HOME (default ~/.upoch); Guard(home=...) picks another one. If upoch is not on your PATH, set UPOCH_COMMAND (for example node /path/to/cli.js mcp) or pass Guard(command=[...]).

Safety

  • Each checkpoint is one transaction from the agent's executor key. That key can only submit checkpoints. There is a daily limit (100 by default, maxCheckpointsPerDay in ~/.upoch/config.json).
  • State that looks like private keys, seed phrases or API tokens is refused, because checkpoints are permanent.
  • Keys stay on your machine, in ~/.upoch/secrets.json, and never pass through Python. Back that file up.
  • The Upoch contracts have not been audited.

License

MIT

Metadata

Release files for upoch 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 upoch 0.1.0
File Size Uploaded Provenance Actions
upoch-0.1.0.tar.gz 16.0 kB Without provenance Details for upoch-0.1.0.tar.gz

Built distribution (wheel)

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

Total release size: 28.4 kB

Release files / upoch-0.1.0.tar.gz

Download URL upoch-0.1.0.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
fbf3b685c0276bdcd0b8a17210c93833f67c20fd485f76d369e57df3197359a2
BLAKE2b-256 checksum
How to use checksums
b399619f7528536d88b0a1ff090ac2b144ed95058295a96bd68b47a66fbff824
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

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

Download URL upoch-0.1.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be8791d1d3032d883115b0296064743c0d9d4efdd90da1b00a3f69dcdfea62c8
BLAKE2b-256 checksum
How to use checksums
d0753c43f36201022caa4a97dc327460bc048f78a2825a0d86a4352f73c6ced7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.2

Security for upoch 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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