runlayer-hooks-sdk 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ .vscode
2
+ .idea
3
+ .mcp.json
4
+ .worktrees
5
+ node_modules/
6
+ .pnpm-store
7
+ /test-results/
8
+ /playwright-report/
9
+ /blob-report/
10
+ /playwright/.cache/
11
+
12
+ # Environment variables
13
+ .env
14
+ .env.local
15
+
16
+ # Local development instance tracking (for multi-instance support)
17
+ .local-instance
18
+ .env.staging
19
+ .env.production
20
+ .env.*
21
+ !.env.example
22
+ !.env.local.example
23
+
24
+ # Terraform
25
+ terraform.tfstate
26
+ terraform.tfstate.*
27
+ *.tfstate
28
+ *.tfstate.*
29
+ .terraform/
30
+ .terraform.lock.hcl
31
+ terraform.tfvars
32
+ terraform.*.tfvars
33
+ tfplan
34
+
35
+ # Python
36
+ __pycache__/
37
+ *.py[cod]
38
+ *$py.class
39
+ *.pyc
40
+ *.so
41
+ .Python
42
+ build/
43
+ develop-eggs/
44
+ dist/
45
+ dist-test/
46
+ downloads/
47
+ eggs/
48
+ .eggs/
49
+ .libs/
50
+ *.libs/
51
+ *.libs/
52
+ *.dist-info/
53
+ psycopg*/
54
+ lib64/
55
+ parts/
56
+ sdist/
57
+ var/
58
+ wheels/
59
+ *.egg-info/
60
+ .installed.cfg
61
+ *.egg
62
+
63
+ .DS_Store
64
+ .worktrees/
65
+ .history/
66
+ playwright/.auth
67
+ backend/scripts/catalog_validation_results.json
68
+
69
+ # We don't want to commit cursor plans
70
+ .cursor/plans/
71
+ # More agent stuff we don't want to commit
72
+ .claude/worktrees/
73
+
74
+ # Local stuff (kept as references for agents)
75
+ mcp-manager.sh/
76
+ typescript-sdk/
77
+ vitor-plans/
78
+ .superset/attachments
79
+
80
+ # Local development tracking files (for multi-instance support)
81
+ .local-pids
82
+
83
+ # SBOM local generation output + tool cache
84
+ sbom/
85
+ .cache/sbom-tools/
86
+
87
+ # Vulnerability scan output
88
+ vuln/
89
+
90
+ # Test artifacts
91
+ backend/test_output.txt
92
+
93
+ # Local ops-console rollout notes
94
+ ops-console-deploy-checklist.local.md
@@ -0,0 +1,26 @@
1
+ .PHONY: check check-fix format format-check lint lint-fix type-check test build
2
+
3
+ check: format-check lint type-check
4
+
5
+ check-fix: format lint-fix type-check
6
+
7
+ format:
8
+ uv run ruff format .
9
+
10
+ format-check:
11
+ uv run ruff format --check .
12
+
13
+ lint:
14
+ uv run ruff check .
15
+
16
+ lint-fix:
17
+ uv run ruff check --fix .
18
+
19
+ type-check:
20
+ uv run ty check .
21
+
22
+ test:
23
+ uv run pytest
24
+
25
+ build:
26
+ uv build
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: runlayer-hooks-sdk
3
+ Version: 0.1.0
4
+ Summary: Runlayer Hooks SDK for Python agent runtimes
5
+ Project-URL: Homepage, https://runlayer.com
6
+ Project-URL: Documentation, https://docs.runlayer.com/
7
+ Author-email: Runlayer <engineering@runlayer.com>
8
+ License: Apache-2.0
9
+ Keywords: agent,llm,mcp,runlayer,security
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: httpx==0.28.1
20
+ Description-Content-Type: text/markdown
21
+
22
+ # Runlayer Hooks Python SDK
23
+
24
+ Python SDK companion to `@runlayer/hooks-sdk`.
25
+
26
+ ## Configure
27
+
28
+ ```sh
29
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
30
+ export RUNLAYER_API_KEY="rl_..."
31
+ ```
32
+
33
+ Agent account auth is also supported:
34
+
35
+ ```sh
36
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
37
+ export RUNLAYER_AGENT_CLIENT_ID="client_..."
38
+ export RUNLAYER_AGENT_CLIENT_SECRET="..."
39
+ ```
40
+
41
+ Optional OBO subject fields:
42
+
43
+ ```sh
44
+ export RUNLAYER_AGENT_SUBJECT_TOKEN="user@example.com"
45
+ export RUNLAYER_AGENT_SUBJECT_TOKEN_TYPE="urn:runlayer:token-type:user-email"
46
+ ```
47
+
48
+ Optional runtime controls:
49
+
50
+ | Variable | Purpose |
51
+ | --- | --- |
52
+ | `RUNLAYER_HOOK_TIMEOUT_MS` | Hook request timeout. Defaults to `10000`. |
53
+ | `RUNLAYER_HOOK_MAX_TOOL_OUTPUT_BYTES` | Maximum serialized tool output sent to Runlayer. Defaults to `65536`. |
54
+ | `RUNLAYER_HOOK_ENFORCEMENT_FAILURE_MODE` | Defaults to `closed`; set to `open` only if tool calls should continue when Runlayer is unreachable. |
55
+ | `RUNLAYER_ALLOW_INSECURE_TRANSPORT=1` | Allow non-HTTPS `RUNLAYER_BASE_URL` for local development. |
56
+
57
+ ## Usage
58
+
59
+ ```python
60
+ from runlayer_sdk import RunlayerClient
61
+
62
+ runlayer = RunlayerClient.from_env(client_version="my-agent/1.0.0")
63
+
64
+
65
+ def run_local_tool(tool_input: dict[str, object]) -> str:
66
+ return "tool output"
67
+
68
+
69
+ output = runlayer.run_tool(
70
+ execute=run_local_tool,
71
+ session_id="session-id",
72
+ tool_input={"command": "cat README.md"},
73
+ tool_name="Bash",
74
+ tool_type="shell",
75
+ )
76
+ ```
77
+
78
+ Use `tool_enforcement` to skip Runlayer-owned MCP tools or proxy URLs:
79
+
80
+ ```python
81
+ runlayer = RunlayerClient.from_env(
82
+ tool_enforcement={
83
+ "ignored_mcp_server_names": ["github-preview"],
84
+ "skip_runlayer_mcp_proxy_urls": True,
85
+ }
86
+ )
87
+ ```
88
+
89
+ `RunlayerClient` exposes:
90
+
91
+ - `emit_event`
92
+ - `before_tool`
93
+ - `after_tool`
94
+ - `run_tool`
95
+ - `should_enforce_tool`
96
+
97
+ The package also exports `send_runlayer_preflight`.
98
+
99
+ ## Framework tool adapters
100
+
101
+ Dependency-free adapters wrap common tool dictionary shapes:
102
+
103
+ - `with_runlayer_vercel_ai_tool`
104
+ - `with_runlayer_vercel_ai_tools`
105
+ - `with_runlayer_openai_agents_tool`
106
+ - `with_runlayer_google_adk_tool`
107
+ - `run_runlayer_adapter_tool`
108
+
109
+ ## Claude Agent SDK hooks
110
+
111
+ Use the adapter helpers when a Python agent runtime wants the same Claude Agent
112
+ SDK hook output shapes as the Hooks TypeScript SDK:
113
+
114
+ ```python
115
+ from runlayer_sdk import RunlayerClient, create_claude_agent_sdk_hooks
116
+
117
+ runlayer = RunlayerClient.from_env()
118
+ hooks = create_claude_agent_sdk_hooks(runlayer, include_stop=False)
119
+ ```
120
+
121
+ The adapter exports:
122
+
123
+ - `create_claude_agent_sdk_hooks`
124
+ - `emit_claude_agent_sdk_transcript_stop`
125
+ - `claude_agent_sdk_assistant_message_to_transcript_line`
126
+ - `tool_type_from_name`
127
+
128
+ TypeScript-style camelCase aliases are also available for SDK parity.
@@ -0,0 +1,107 @@
1
+ # Runlayer Hooks Python SDK
2
+
3
+ Python SDK companion to `@runlayer/hooks-sdk`.
4
+
5
+ ## Configure
6
+
7
+ ```sh
8
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
9
+ export RUNLAYER_API_KEY="rl_..."
10
+ ```
11
+
12
+ Agent account auth is also supported:
13
+
14
+ ```sh
15
+ export RUNLAYER_BASE_URL="https://your-runlayer-instance.com"
16
+ export RUNLAYER_AGENT_CLIENT_ID="client_..."
17
+ export RUNLAYER_AGENT_CLIENT_SECRET="..."
18
+ ```
19
+
20
+ Optional OBO subject fields:
21
+
22
+ ```sh
23
+ export RUNLAYER_AGENT_SUBJECT_TOKEN="user@example.com"
24
+ export RUNLAYER_AGENT_SUBJECT_TOKEN_TYPE="urn:runlayer:token-type:user-email"
25
+ ```
26
+
27
+ Optional runtime controls:
28
+
29
+ | Variable | Purpose |
30
+ | --- | --- |
31
+ | `RUNLAYER_HOOK_TIMEOUT_MS` | Hook request timeout. Defaults to `10000`. |
32
+ | `RUNLAYER_HOOK_MAX_TOOL_OUTPUT_BYTES` | Maximum serialized tool output sent to Runlayer. Defaults to `65536`. |
33
+ | `RUNLAYER_HOOK_ENFORCEMENT_FAILURE_MODE` | Defaults to `closed`; set to `open` only if tool calls should continue when Runlayer is unreachable. |
34
+ | `RUNLAYER_ALLOW_INSECURE_TRANSPORT=1` | Allow non-HTTPS `RUNLAYER_BASE_URL` for local development. |
35
+
36
+ ## Usage
37
+
38
+ ```python
39
+ from runlayer_sdk import RunlayerClient
40
+
41
+ runlayer = RunlayerClient.from_env(client_version="my-agent/1.0.0")
42
+
43
+
44
+ def run_local_tool(tool_input: dict[str, object]) -> str:
45
+ return "tool output"
46
+
47
+
48
+ output = runlayer.run_tool(
49
+ execute=run_local_tool,
50
+ session_id="session-id",
51
+ tool_input={"command": "cat README.md"},
52
+ tool_name="Bash",
53
+ tool_type="shell",
54
+ )
55
+ ```
56
+
57
+ Use `tool_enforcement` to skip Runlayer-owned MCP tools or proxy URLs:
58
+
59
+ ```python
60
+ runlayer = RunlayerClient.from_env(
61
+ tool_enforcement={
62
+ "ignored_mcp_server_names": ["github-preview"],
63
+ "skip_runlayer_mcp_proxy_urls": True,
64
+ }
65
+ )
66
+ ```
67
+
68
+ `RunlayerClient` exposes:
69
+
70
+ - `emit_event`
71
+ - `before_tool`
72
+ - `after_tool`
73
+ - `run_tool`
74
+ - `should_enforce_tool`
75
+
76
+ The package also exports `send_runlayer_preflight`.
77
+
78
+ ## Framework tool adapters
79
+
80
+ Dependency-free adapters wrap common tool dictionary shapes:
81
+
82
+ - `with_runlayer_vercel_ai_tool`
83
+ - `with_runlayer_vercel_ai_tools`
84
+ - `with_runlayer_openai_agents_tool`
85
+ - `with_runlayer_google_adk_tool`
86
+ - `run_runlayer_adapter_tool`
87
+
88
+ ## Claude Agent SDK hooks
89
+
90
+ Use the adapter helpers when a Python agent runtime wants the same Claude Agent
91
+ SDK hook output shapes as the Hooks TypeScript SDK:
92
+
93
+ ```python
94
+ from runlayer_sdk import RunlayerClient, create_claude_agent_sdk_hooks
95
+
96
+ runlayer = RunlayerClient.from_env()
97
+ hooks = create_claude_agent_sdk_hooks(runlayer, include_stop=False)
98
+ ```
99
+
100
+ The adapter exports:
101
+
102
+ - `create_claude_agent_sdk_hooks`
103
+ - `emit_claude_agent_sdk_transcript_stop`
104
+ - `claude_agent_sdk_assistant_message_to_transcript_line`
105
+ - `tool_type_from_name`
106
+
107
+ TypeScript-style camelCase aliases are also available for SDK parity.
@@ -0,0 +1,44 @@
1
+ [project]
2
+ name = "runlayer-hooks-sdk"
3
+ version = "0.1.0"
4
+ description = "Runlayer Hooks SDK for Python agent runtimes"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "Apache-2.0" }
8
+ authors = [{ name = "Runlayer", email = "engineering@runlayer.com" }]
9
+ keywords = ["mcp", "runlayer", "agent", "llm", "security"]
10
+ classifiers = [
11
+ "Intended Audience :: Developers",
12
+ "License :: OSI Approved :: Apache Software License",
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3.10",
15
+ "Programming Language :: Python :: 3.11",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ "Topic :: Software Development :: Libraries :: Python Modules",
19
+ ]
20
+ dependencies = [
21
+ "httpx==0.28.1",
22
+ ]
23
+
24
+ [dependency-groups]
25
+ dev = [
26
+ "anyio==4.13.0",
27
+ "pytest==9.0.3",
28
+ "ruff==0.15.10",
29
+ "ty==0.0.31",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://runlayer.com"
34
+ Documentation = "https://docs.runlayer.com/"
35
+
36
+ [tool.uv]
37
+ exclude-newer = "7 days"
38
+
39
+ [build-system]
40
+ build-backend = "hatchling.build"
41
+ requires = ["hatchling==1.27.0"]
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["runlayer_sdk"]
@@ -0,0 +1,158 @@
1
+ """Runlayer Hooks Python SDK."""
2
+
3
+ from runlayer_sdk.client import RunlayerClient, RunlayerHookClient
4
+ from runlayer_sdk.claude_agent_sdk import (
5
+ ClaudeAgentSdkHooksOptions,
6
+ ClaudeAgentSdkTranscriptStopOptions,
7
+ claudeAgentSdkAssistantMessageToTranscriptLine,
8
+ claude_agent_sdk_assistant_message_to_transcript_line,
9
+ createClaudeAgentSdkHooks,
10
+ create_claude_agent_sdk_hooks,
11
+ emitClaudeAgentSdkTranscriptStop,
12
+ emit_claude_agent_sdk_transcript_stop,
13
+ toolTypeFromName,
14
+ tool_type_from_name,
15
+ )
16
+ from runlayer_sdk.types import (
17
+ AgentAccountOptions,
18
+ AfterToolOptions,
19
+ AfterToolResult,
20
+ AgentSubjectTokenType,
21
+ BeforeToolOptions,
22
+ BeforeToolResult,
23
+ EnforceMcpSourceOptions,
24
+ FetchLike,
25
+ FetchResponse,
26
+ HookEventName,
27
+ JsonObject,
28
+ RunlayerAgentAccountOptions,
29
+ RunlayerBlockedError,
30
+ RunlayerClientEnvOptions,
31
+ RunlayerClientOptions,
32
+ RunlayerEnforcementFailureMode,
33
+ RunlayerEnforcementUnavailableError,
34
+ RunlayerToolContext,
35
+ RunlayerToolEnforcementOptions,
36
+ RunlayerToolEnforcementPredicate,
37
+ RunToolOptions,
38
+ )
39
+ from runlayer_sdk.preflight import (
40
+ PreflightOptions,
41
+ PreflightResult,
42
+ sendRunlayerPreflight,
43
+ send_runlayer_preflight,
44
+ )
45
+ from runlayer_sdk.google_adk import (
46
+ GoogleAdkFunctionToolOptions,
47
+ GoogleAdkToolContext,
48
+ RunlayerGoogleAdkToolAdapterOptions,
49
+ withRunlayerGoogleAdkTool,
50
+ with_runlayer_google_adk_tool,
51
+ )
52
+ from runlayer_sdk.openai_agents_sdk import (
53
+ OpenAIAgentsFunctionToolOptions,
54
+ OpenAIAgentsToolCallDetails,
55
+ RunlayerOpenAIAgentsToolAdapterOptions,
56
+ withRunlayerOpenAIAgentsTool,
57
+ with_runlayer_openai_agents_tool,
58
+ )
59
+ from runlayer_sdk.tool_adapter import (
60
+ RunlayerAdapterMetadataResolver,
61
+ RunlayerAdapterRunOptions,
62
+ RunlayerAdapterToolExecute,
63
+ RunlayerAdapterToolExecution,
64
+ RunlayerToolAdapterOptions,
65
+ runRunlayerAdapterToolAsync,
66
+ runRunlayerAdapterTool,
67
+ run_runlayer_adapter_tool_async,
68
+ run_runlayer_adapter_tool,
69
+ )
70
+ from runlayer_sdk.tool_enforcement import (
71
+ isRunlayerMcpProxyUrl,
72
+ is_runlayer_mcp_proxy_url,
73
+ mcpServerNameFromToolName,
74
+ mcp_server_name_from_tool_name,
75
+ shouldEnforceTool,
76
+ should_enforce_tool,
77
+ )
78
+ from runlayer_sdk.vercel_ai_sdk import (
79
+ VercelAiTool,
80
+ VercelAiToolExecutionOptions,
81
+ VercelAiToolSet,
82
+ withRunlayerVercelAiTool,
83
+ withRunlayerVercelAiTools,
84
+ with_runlayer_vercel_ai_tool,
85
+ with_runlayer_vercel_ai_tools,
86
+ )
87
+
88
+ __all__ = [
89
+ "AgentAccountOptions",
90
+ "AfterToolOptions",
91
+ "AfterToolResult",
92
+ "AgentSubjectTokenType",
93
+ "BeforeToolOptions",
94
+ "BeforeToolResult",
95
+ "ClaudeAgentSdkHooksOptions",
96
+ "ClaudeAgentSdkTranscriptStopOptions",
97
+ "EnforceMcpSourceOptions",
98
+ "FetchLike",
99
+ "FetchResponse",
100
+ "GoogleAdkFunctionToolOptions",
101
+ "GoogleAdkToolContext",
102
+ "HookEventName",
103
+ "JsonObject",
104
+ "OpenAIAgentsFunctionToolOptions",
105
+ "OpenAIAgentsToolCallDetails",
106
+ "PreflightOptions",
107
+ "PreflightResult",
108
+ "RunlayerAdapterMetadataResolver",
109
+ "RunlayerAdapterRunOptions",
110
+ "RunlayerAdapterToolExecute",
111
+ "RunlayerAdapterToolExecution",
112
+ "RunToolOptions",
113
+ "RunlayerAgentAccountOptions",
114
+ "RunlayerBlockedError",
115
+ "RunlayerClient",
116
+ "RunlayerClientEnvOptions",
117
+ "RunlayerClientOptions",
118
+ "RunlayerEnforcementFailureMode",
119
+ "RunlayerEnforcementUnavailableError",
120
+ "RunlayerGoogleAdkToolAdapterOptions",
121
+ "RunlayerHookClient",
122
+ "RunlayerOpenAIAgentsToolAdapterOptions",
123
+ "RunlayerToolAdapterOptions",
124
+ "RunlayerToolContext",
125
+ "RunlayerToolEnforcementOptions",
126
+ "RunlayerToolEnforcementPredicate",
127
+ "VercelAiTool",
128
+ "VercelAiToolExecutionOptions",
129
+ "VercelAiToolSet",
130
+ "claudeAgentSdkAssistantMessageToTranscriptLine",
131
+ "claude_agent_sdk_assistant_message_to_transcript_line",
132
+ "createClaudeAgentSdkHooks",
133
+ "create_claude_agent_sdk_hooks",
134
+ "emitClaudeAgentSdkTranscriptStop",
135
+ "emit_claude_agent_sdk_transcript_stop",
136
+ "isRunlayerMcpProxyUrl",
137
+ "is_runlayer_mcp_proxy_url",
138
+ "mcpServerNameFromToolName",
139
+ "mcp_server_name_from_tool_name",
140
+ "runRunlayerAdapterToolAsync",
141
+ "runRunlayerAdapterTool",
142
+ "run_runlayer_adapter_tool_async",
143
+ "run_runlayer_adapter_tool",
144
+ "sendRunlayerPreflight",
145
+ "send_runlayer_preflight",
146
+ "shouldEnforceTool",
147
+ "should_enforce_tool",
148
+ "toolTypeFromName",
149
+ "tool_type_from_name",
150
+ "withRunlayerGoogleAdkTool",
151
+ "withRunlayerOpenAIAgentsTool",
152
+ "withRunlayerVercelAiTool",
153
+ "withRunlayerVercelAiTools",
154
+ "with_runlayer_google_adk_tool",
155
+ "with_runlayer_openai_agents_tool",
156
+ "with_runlayer_vercel_ai_tool",
157
+ "with_runlayer_vercel_ai_tools",
158
+ ]