Skip to main content

langchain-emilia

Before your LangChain agent does anything irreversible, a named human approves that exact action on their own device. Face ID / Touch ID / passkey. Fail-closed. Every approval mints a Trust Receipt that verifies offline — years later, with no account and no EMILIA server.

pip install langchain-emilia
export EP_API_KEY=ep_live_...  EP_ORG_ID=your-org
from langchain_emilia import EmiliaGuard, guard_tools

guard = EmiliaGuard()                                   # enforce mode
tools = guard_tools([transfer_funds, send_email, calculator], guard)
# hand `tools` to your agent exactly as before — nothing else changes

When the agent calls transfer_funds(amount=82000, beneficiary="Northwind"):

  1. Gate — the call is held pre-execution; EP policy returns allow, require_signoff, or deny.
  2. Signoff — on require_signoff, a named human approves on their own device. The approval is cryptographically bound to the exact action parameters — change one digit and it is invalid.
  3. Consume — the exact receipt is atomically consumed before the tool body; an already-consumed receipt cannot authorize another executor.
  4. Attest — after the tool returns, the adapter reports executor-observed invocation fields re-derived from the detached arguments actually handed to the tool; it does not reuse the approved plan as its own observation. This is attributable execution evidence, not proof of real-world effects. If the evidence write cannot be confirmed, the result is INDETERMINATE and the adapter says DO NOT RETRY.

Denials and pending holds are returned to the model as the tool's output ("EMILIA — BLOCKED … transfer_funds was NOT executed."), so the agent loop explains itself instead of crashing. The tool body never runs unless the gate allows it.

Why this is an executor-side precondition, not an "approval tool"

Approval tools the model calls have three failure modes: the model forgets to call them, approves action A then executes action B, or barrels past an error. langchain-emilia instead wraps the tool itself: the action digest is computed from the actual arguments at execution time and the gate runs before the tool body, unconditionally. The model-facing schema is unchanged; only the executor gains the gate.

Zero-setup dry run (observe mode)

No account, no network, nothing blocked — see what enforcement would cover:

guard = EmiliaGuard(mode="observe")
tools = guard_tools(my_tools, guard)
# ... run your agent, then:
for r in guard.records:
    print(r["tool"], r["digest"][:16], r["note"])

Configuration

Option Default Meaning
mode "enforce" "observe" = log-only local dry run, keyless
match money/external-action regex Callable[[str], bool] — which tool names are gated
action_types auto map tool name → EP action_type (see ACTION_TYPES)
wait_for_approval True block (≤ timeout) while the human approves; False = surface the signoff URL immediately
return_errors True denials become tool output for the model; False = raise EmiliaDenied / EmiliaApprovalPending
on_event None callback for observed/allowed/executed/denied/pending/unreachable/indeterminate events (SIEM hook)

EmiliaGateClient(api_key, org_id, base_url, signoff_timeout_s=280, poll_interval_s=3) reads EP_API_KEY / EP_ORG_ID / EP_BASE_URL from the environment by default.

Fail-closed semantics

Situation What happens
Policy denies Tool not executed; model told why
Human rejects on device Tool not executed; receipt records the rejection
Signoff window times out Tool not executed; signoff URL surfaced for retry
EMILIA unreachable / network error Tool not executed — never fail open
Consume is not confirmed Tool not executed — never fail open
Tool returns but execution attestation fails Tool may have executed; INDETERMINATE, do not retry
Tool name doesn't match match Runs ungated (scope your match deliberately)

Verify the evidence

Every allowed action carries a receipt_id. Anyone can verify it with zero trust in us or in you:

Try the human side yourself (no signup): https://www.emiliaprotocol.ai/try

Development

cd integrations/langchain-emilia
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/pytest -q

Apache-2.0. The digest layer is pinned byte-for-byte to the JS verifier by cross-language vectors in tests/test_digest.py.

Building with LangChain.js instead? The JS sibling is @emilia-protocol/langchain — a thin gate Proxy for .invoke()-style tools on npm.

Download files

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

Source Distribution

langchain_emilia-0.2.0.tar.gz (17.1 kB view details)

Uploaded Source

Built Distribution

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

langchain_emilia-0.2.0-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file langchain_emilia-0.2.0.tar.gz.

File metadata

  • Download URL: langchain_emilia-0.2.0.tar.gz
  • Upload date:
  • Size: 17.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for langchain_emilia-0.2.0.tar.gz
Algorithm Hash digest
SHA256 136a014683e4b72c762c7f6b41295d3b11a22605f5100a77ed7da67ccfdf08ed
MD5 20221ee85b0a2fcc25321ea7fcc7c058
BLAKE2b-256 cfad5af40c3cfa47493a1ceaef22059e4c6388a36058ffcedc40d9051f6d1358

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_emilia-0.2.0.tar.gz:

Publisher: publish-langchain-python.yml on emiliaprotocol/emilia-protocol

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

File details

Details for the file langchain_emilia-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for langchain_emilia-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fb6802b29b3a8b485ea20e8292bea79ed962b6c5806073ad6244340f1a6a8e00
MD5 93709084b51ad591a757f44bfb150bc3
BLAKE2b-256 1a6eecc71ceeb8e646796b67460f4eb2104681010d12395c456bd5fc1f046a63

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_emilia-0.2.0-py3-none-any.whl:

Publisher: publish-langchain-python.yml on emiliaprotocol/emilia-protocol

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 Sentry Error logging StatusPage Status page