Runlayer Hooks Python SDK
Python SDK companion to @runlayer/hooks-sdk.
Configure
export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
export RUNLAYER_API_KEY="rl_..."
For cloud installations that authenticate with a shared organization API key
(rl_org_...), also name the Runlayer user the deployment runs as so sessions
and enforcement are attributed to it:
export RUNLAYER_API_KEY="rl_org_..."
export RUNLAYER_USER_EMAIL="svc-my-agent@your-company.com"
The identity can be a service user provisioned just for the deployment; events
sent before that user exists in the workspace are buffered and replayed once it
does. The organization key must carry the AI Watch scan role. user_email is
also available as a RunlayerClient constructor option; it applies only to API
key auth (agent accounts express the acting user via subject_token).
Agent account auth is also supported:
export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
export RUNLAYER_AGENT_CLIENT_ID="client_..."
export RUNLAYER_AGENT_CLIENT_SECRET="..."
Optional OBO subject fields:
export RUNLAYER_AGENT_SUBJECT_TOKEN="user@example.com"
export RUNLAYER_AGENT_SUBJECT_TOKEN_TYPE="urn:runlayer:token-type:user-email"
The SDK mints an agent token with client_credentials and, when an OBO subject
is configured, exchanges it via RFC 8693 token exchange
(urn:ietf:params:oauth:grant-type:token-exchange); both tokens are cached and
refreshed internally.
Optional runtime controls:
| Variable | Purpose |
|---|---|
RUNLAYER_HOOK_TIMEOUT_MS |
Hook request timeout. Defaults to 10000. |
RUNLAYER_HOOK_MAX_TOOL_OUTPUT_BYTES |
Maximum serialized tool output sent to Runlayer. Defaults to 65536. |
RUNLAYER_HOOK_ENFORCEMENT_FAILURE_MODE |
Defaults to closed; set to open only if tool calls should continue when Runlayer is unreachable. |
RUNLAYER_ALLOW_INSECURE_TRANSPORT=1 |
Allow non-HTTPS RUNLAYER_BASE_URL for local development. |
Usage
from runlayer_sdk import RunlayerClient
runlayer = RunlayerClient.from_env(client_version="my-agent/1.0.0")
def run_local_tool(tool_input: dict[str, object]) -> str:
return "tool output"
output = runlayer.run_tool(
execute=run_local_tool,
session_id="session-id",
tool_input={"command": "cat README.md"},
tool_name="Bash",
tool_type="shell",
)
Use tool_enforcement to skip Runlayer-owned MCP tools or proxy URLs:
runlayer = RunlayerClient.from_env(
tool_enforcement={
"ignored_mcp_server_names": ["github-preview"],
"skip_runlayer_mcp_proxy_urls": True,
}
)
RunlayerClient exposes:
emit_eventbefore_toolafter_toolrun_toolshould_enforce_tool
The package also exports send_runlayer_preflight.
Troubleshooting: sessions not appearing
Lifecycle hooks send events best-effort and do not raise on their own. If the
server accepts an event but does not record it, it responds with
status: "ignored" and a reason. The client logs a one-time warning to stderr
for the actionable reasons so a misconfiguration is not silent:
client_not_enabled— the SDK session-monitoring client is off for this workspace. Enable the client (and any required SDK toggle) in Runlayer settings. This is a separate switch from tool enforcement, so both must be on to get full session + tool telemetry.sessions_disabled— the applicable MDM configuration disables session reporting. Ask a Runlayer administrator to enable Sessions in that MDM configuration.actor_unresolved— the request authenticated but Runlayer could not map it to a user/agent. With an organization API key, setRUNLAYER_USER_EMAIL(or theuser_emailclient option) to the Runlayer user the deployment runs as; events are buffered until that user exists in the workspace. Otherwise use a personal API key (RUNLAYER_API_KEY) or agent-account credentials (RUNLAYER_AGENT_CLIENT_ID/RUNLAYER_AGENT_CLIENT_SECRET).
Set RUNLAYER_HOOK_DEBUG=1 to also log transient ignore reasons and network
failures. Run send_runlayer_preflight() for an explicit check.
Framework tool adapters
Dependency-free adapters wrap common tool dictionary shapes:
with_runlayer_vercel_ai_toolwith_runlayer_vercel_ai_toolswith_runlayer_openai_agents_toolwith_runlayer_google_adk_toolrun_runlayer_adapter_tool
Claude Agent SDK hooks
Use the adapter helpers when a Python agent runtime wants the same Claude Agent SDK hook output shapes as the Hooks TypeScript SDK:
from runlayer_sdk import RunlayerClient, create_claude_agent_sdk_hooks
runlayer = RunlayerClient.from_env()
hooks = create_claude_agent_sdk_hooks(runlayer, include_stop=False)
The adapter exports:
create_claude_agent_sdk_hooksemit_claude_agent_sdk_transcript_stopclaude_agent_sdk_assistant_message_to_transcript_linetool_type_from_name
TypeScript-style camelCase aliases are also available for SDK parity.
Each query() call starts a new Claude Agent SDK session with a fresh
session_id, and Runlayer records each session id as a separate session. To
keep a multi-prompt conversation in a single Runlayer session, resume the
previous session on follow-up calls (leave fork_session unset so the session
id is preserved), then emit the transcript Stop per run as usual:
options = ClaudeAgentOptions(
hooks=create_claude_agent_sdk_hooks(runlayer, include_stop=False),
resume=session_id, # session_id captured from the previous run's init message
)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file runlayer_hooks_sdk-0.2.1.tar.gz.
File metadata
- Download URL: runlayer_hooks_sdk-0.2.1.tar.gz
- Upload date:
- Size: 48.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b74d6ecb118b5a3ef1fce0ebb18972d8a50445d1aed5aa07c316254de0fe3b9
|
|
| MD5 |
17d3fea6eee576f89222dbc597434358
|
|
| BLAKE2b-256 |
ec3c19a3f8d10b71c9d4674dc977a16e2af5772e7762a41d7eaebdcb19d4edae
|
File details
Details for the file runlayer_hooks_sdk-0.2.1-py3-none-any.whl.
File metadata
- Download URL: runlayer_hooks_sdk-0.2.1-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
000781682ce89deb6087986e753cfc71fe047189b68a4250492cc6b30977e531
|
|
| MD5 |
627054f7868be671bbb6277f9d2a1b44
|
|
| BLAKE2b-256 |
d50f669095d5c647235170cf99c2640d31b2c7bfef9534702a74f1fd8f85dd90
|