Production-ready Python client for the Faramesh Execution Governor API.
For AI governance and AI execution control architecture details, see:
pip install faramesh-sdkOr install from source:
git clone https://github.com/faramesh/faramesh-python-sdk.git
cd faramesh-python-sdk
pip install -e .from faramesh import configure, submit_action, approve_action
# Configure SDK (optional - defaults to http://127.0.0.1:8000)
configure(
base_url="http://localhost:8000",
token="your-token", # Optional, can also use FARAMESH_TOKEN env var
)
# Submit an action
action = submit_action(
agent_id="my-agent",
tool="http",
operation="get",
params={"url": "https://example.com"}
)
print(f"Action {action.id} status: {action.status}")
# If action requires approval
if action.status == "pending_approval":
approved = approve_action(
action.id,
action.approval_token,
reason="Looks safe"
)
print(f"Action approved: {approved.status}")- Simple API: Easy-to-use functions for all API operations
- Batch Operations: Submit multiple actions at once
- Submit and Wait: Automatically wait for action completion
- Policy Building: Build policies in Python code
- Deterministic Hashing: Client-side request_hash computation
- Gate Endpoint: Pre-check decisions without creating actions
- Replay Helpers: Verify decision determinism
- Error Handling: Typed exceptions for all error cases
Use this when you want explicit pre-execution governance for LangChain/LangGraph tool calls directly in agent code.
from faramesh.adapters.langchain import install_langchain_interceptor
install_langchain_interceptor(
policy="policy.fpl",
agent_id="support-agent",
fail_open=False,
include_langgraph=True,
)
# Build and run your LangChain/LangGraph agent normally.What it intercepts before execution:
- LangChain
BaseTool.invoke - LangChain
BaseTool.ainvoke - LangChain
BaseTool.run - LangChain
BaseTool.arun - LangGraph
ToolNode._execute_tool_sync(primary) - LangGraph
ToolNode._execute_tool_async(primary) - LangGraph
ToolNode._run_one(fallback for older ToolNode versions) - LangGraph
ToolNode._arun_one(fallback for older ToolNode versions)
Use this when your agent is assembled via deepagents.create_deep_agent(...)
and you want the same Faramesh governance guarantees.
from faramesh.adapters.deepagents import install_deepagents_interceptor
install_deepagents_interceptor(
policy="policy.fpl",
agent_id="research-supervisor",
fail_open=False,
include_langgraph=True,
)
# Build and run your DeepAgents graph normally.DeepAgents adapter guarantees:
- Patches DeepAgents
create_deep_agententrypoint - Reuses LangChain/LangGraph execution-layer interception
- Preserves Faramesh fail-closed behavior (
PERMIT|DENY|DEFER) - Keeps tool IDs compatible with operation-aware FPL matching
Use the bundled harness to validate production-style governance with
OpenRouter qwen/qwen3.6-plus:free.
# 1) Activate your SDK/deepagents environment
source /tmp/faramesh-deepagents-venv313/bin/activate
# 2) Start daemon with strict policy for this harness
cd /Users/xquark_home/Faramesh-Nexus/faramesh-core
go run ./cmd/faramesh serve \
--socket /tmp/faramesh.sock \
--data-dir /tmp/faramesh-data \
--policy sdk/python/examples/policies/deepagents_openrouter_qwen_production.fpl
# 3) In another shell, run the harness under Faramesh runtime wiring
cd /Users/xquark_home/Faramesh-Nexus/faramesh-core
OPENROUTER_API_KEY=<your_key> \
go run ./cmd/faramesh run \
--daemon-socket /tmp/faramesh.sock \
--agent-id deepagents-openrouter-qwen-prod \
--policy sdk/python/examples/policies/deepagents_openrouter_qwen_production.fpl \
-- python sdk/python/examples/deepagents_openrouter_qwen_production.py
# 4) Export DPR evidence for the run
go run ./cmd/faramesh audit export \
/tmp/faramesh-data/faramesh.db \
--agent deepagents-openrouter-qwen-prod \
--format jsonHarness path: sdk/python/examples/deepagents_openrouter_qwen_production.py
Policy path: sdk/python/examples/policies/deepagents_openrouter_qwen_production.fpl
For custom LangChain/LangGraph projects, use the daemon + runtime wrapper path:
# 1) Start governance daemon (strict preflight recommended)
faramesh serve --policy policies/agent.fpl --strict-preflight
# 2) Run any Python agent under governance
faramesh run --broker --agent-id my-agent -- python your_agent.py
# Module form also works
faramesh run --broker --agent-id my-agent -- python -m your_package.agentHow this works with one command:
faramesh runinjectsFARAMESH_AUTOLOAD=1so startup hooks activate.- Python
sitecustomize.pyloads Faramesh autopatch at interpreter startup. - Autopatch intercepts LangChain/LangGraph tool dispatch points before execution.
- Every tool call is gated through daemon socket governance (
PERMIT|DENY|DEFER). faramesh runalso wiresFARAMESH_SOCKETandFARAMESH_AGENT_IDinto child env (with explicit--agent-idoverride, otherwise inferred from command).
This makes interception resilient across many custom agent layouts without editing agent source.
Goal: keep raw secrets out of LLM/agent process memory whenever possible.
Recommended boundary model:
- Use
faramesh run --brokerso ambient API keys are stripped from child env. - Keep high-risk tools default-deny, and require explicit permit/defer policy rules.
- Use brokered credentials (Vault/AWS/GCP/Azure) on daemon side.
- Prefer out-of-process credentialed executors (proxy/MCP sidecar/service wrapper) so the agent sends intent/parameters, not secrets.
- Verify evidence chain after runs (
faramesh audit verify ...).
Concrete key-intake workflow:
# Provision local Vault and securely prompt for key value
faramesh credential vault up
faramesh credential vault put stripe/refund
# Start daemon with Vault backend, then run agent with stripped ambient keys
source ~/.faramesh/local-vault/vault.env
faramesh serve --policy policies/agent.fpl --vault-addr "$FARAMESH_CREDENTIAL_VAULT_ADDR" --vault-token "$FARAMESH_CREDENTIAL_VAULT_TOKEN" --vault-mount secret
faramesh run --broker --agent-id my-agent -- python your_agent.pyImportant limitation (applies to any framework):
- If a tool executes inside the same Python process and needs a raw API key, that key is in-process by definition.
- For strict separation and anti-hijack posture, move secret-using calls to controlled runtime boundaries outside agent process.
Run the focused verification matrix for policy/FPL effect handling and LangChain/LangGraph interception behavior:
python -m unittest \
tests.test_langchain_policy_fpl_harness \
tests.test_deepagents_policy_fpl_harness \
tests.test_deepagents_adapter \
tests.test_langchain_adapter \
tests.test_langchain_live_integrationFor a full SDK pass:
python -m unittest discover -s testsFor full daemon-backed end-to-end policy verification with real FPL assets, run:
bash tests/langchain_single_agent_real_stack_fpl.shThis harness validates PERMIT, DENY, and DEFER flows against durable records.
Use this checklist in CI/CD for production-grade LangChain/LangGraph governance:
- Run deterministic policy/FPL harness tests on every pull request.
- Run live integration tests (real langchain-core/langgraph) on mainline merges.
- Keep
fail_open=Falsein production unless you explicitly accept fail-open risk. - Pin and review framework versions whenever upgrading LangChain/LangGraph.
- Run daemon-backed FPL verification before release cutovers.
- Store test artifacts (logs and DPR records) for incident forensics.
For DeepAgents workloads, apply the same checklist plus DeepAgents adapter
coverage tests (tests.test_deepagents_adapter,
tests.test_deepagents_policy_fpl_harness).
Note: Python 3.14 currently emits a LangChain core Pydantic v1 compatibility warning in test output; test execution still completes successfully.
The SDK provides helpers for deterministic decision verification:
from faramesh import compute_request_hash
payload = {
"agent_id": "my-agent",
"tool": "http",
"operation": "get",
"params": {"url": "https://example.com"},
"context": {}
}
# Compute hash locally (matches server's request_hash)
hash_value = compute_request_hash(payload)
print(f"Request hash: {hash_value}")from faramesh import gate_decide
# Get decision without creating an action
decision = gate_decide(
agent_id="my-agent",
tool="http",
operation="get",
params={"url": "https://example.com"}
)
if decision.outcome == "EXECUTE":
print("Action would be allowed")
elif decision.outcome == "HALT":
print(f"Action would be denied: {decision.reason_code}")
else: # ABSTAIN
print("Action requires approval")from faramesh import execute_if_allowed
def my_executor(tool, operation, params, context):
# Your actual execution logic
return {"status": "done"}
result = execute_if_allowed(
agent_id="my-agent",
tool="http",
operation="get",
params={"url": "https://example.com"},
executor=my_executor
)
if result["executed"]:
print("Action executed:", result["execution_result"])
else:
print("Action blocked:", result["reason_code"])from faramesh import replay_decision
# Verify decision is deterministic
result = replay_decision(action_id="abc123")
if result.success:
print("Decision replay passed!")
else:
print("Mismatches:", result.mismatches)Full documentation is available at: https://github.com/faramesh/faramesh-docs
See docs/SDK-Python.md for detailed API reference.
Source: https://github.com/faramesh/faramesh-python-sdk
Elastic License 2.0