codeshield-runtime 0.1.0__py3-none-any.whl

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.
codeshield/schemas.py ADDED
@@ -0,0 +1,120 @@
1
+ """Pydantic models for the execution engine."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
9
+
10
+
11
+ class CodeExecutionRequest(BaseModel):
12
+ """Request to execute a piece of Python code safely."""
13
+
14
+ model_config = ConfigDict(frozen=True, extra="forbid")
15
+
16
+ code: str = Field(..., min_length=1, description="Python source code to execute.")
17
+ timeout_seconds: float = Field(
18
+ default=60.0,
19
+ gt=0.0,
20
+ le=3600.0,
21
+ description="Maximum execution time in seconds.",
22
+ )
23
+ requirements: list[str] = Field(
24
+ default_factory=list,
25
+ description="Optional list of PyPI packages to install in the sandbox.",
26
+ )
27
+ file_name: str | None = Field(
28
+ default=None,
29
+ description="Optional file name used when persisting code in the sandbox.",
30
+ )
31
+
32
+ @field_validator("code")
33
+ @classmethod
34
+ def _code_must_be_non_empty(cls, value: str) -> str:
35
+ if not value.strip():
36
+ raise ValueError("Code must contain non-whitespace characters.")
37
+ return value
38
+
39
+
40
+ class ExecutionResult(BaseModel):
41
+ """Result of an isolated code execution."""
42
+
43
+ model_config = ConfigDict(frozen=True, extra="forbid")
44
+
45
+ stdout: str = Field(default="", description="Captured standard output.")
46
+ stderr: str = Field(default="", description="Captured standard error.")
47
+ exit_code: int | None = Field(
48
+ default=None,
49
+ description="Process exit code; None if the process did not terminate normally.",
50
+ )
51
+ duration_seconds: float = Field(
52
+ default=0.0,
53
+ ge=0.0,
54
+ description="Total wall-clock execution time in seconds.",
55
+ )
56
+ silent_failure_detected: bool = Field(
57
+ default=False,
58
+ description="True when exit_code is 0 but suspicious patterns were detected in output.",
59
+ )
60
+ timed_out: bool = Field(
61
+ default=False,
62
+ description="True when the process was terminated due to timeout.",
63
+ )
64
+
65
+
66
+ class ErrorDiagnosis(BaseModel):
67
+ """Structured diagnosis extracted from a runtime traceback."""
68
+
69
+ model_config = ConfigDict(frozen=True, extra="forbid")
70
+
71
+ error_type: str = Field(..., description="Exception class name, e.g. NameError.")
72
+ root_cause_line: int | None = Field(
73
+ default=None,
74
+ description="Line number in the original source where the failure originated.",
75
+ )
76
+ message: str = Field(default="", description="Exception message or human-readable summary.")
77
+ context: list[str] = Field(
78
+ default_factory=list,
79
+ description="Surrounding source lines for the failing line, if available.",
80
+ )
81
+
82
+
83
+ class PatchProposal(BaseModel):
84
+ """A validated patch proposal ready to be applied to a source file."""
85
+
86
+ model_config = ConfigDict(frozen=True, extra="forbid")
87
+
88
+ file_path: Path = Field(..., description="Target source file in the sandbox.")
89
+ patched_code: str = Field(..., description="Proposed replacement source code.")
90
+ is_syntax_valid: bool = Field(
91
+ default=False,
92
+ description="True when the patched code passed AST validation.",
93
+ )
94
+ diagnosis: ErrorDiagnosis | None = Field(
95
+ default=None,
96
+ description="Diagnosis that motivated the patch.",
97
+ )
98
+
99
+
100
+ class ValidationReport(BaseModel):
101
+ """Report produced by static AST validation."""
102
+
103
+ model_config = ConfigDict(frozen=True, extra="forbid", arbitrary_types_allowed=True)
104
+
105
+ is_valid: bool = Field(..., description="True when no syntax or safety violations were found.")
106
+ violations: list[str] = Field(
107
+ default_factory=list,
108
+ description="Human-readable list of syntax and safety violations.",
109
+ )
110
+ exception: SyntaxError | None = Field(
111
+ default=None,
112
+ description="Original SyntaxError instance, if any.",
113
+ )
114
+
115
+ def model_post_init(self, __context: Any) -> None: # noqa: N807
116
+ """Ensure is_valid remains consistent with the violations list."""
117
+ if self.is_valid and self.violations:
118
+ object.__setattr__(self, "is_valid", False)
119
+ elif not self.is_valid and not self.violations and self.exception is None:
120
+ object.__setattr__(self, "is_valid", True)
codeshield/tools.py ADDED
@@ -0,0 +1,76 @@
1
+ """Universal agent tool wrapper for CodeShield.
2
+
3
+ The function returned by ``create_code_execution_tool`` can be registered as a
4
+ tool in any agent framework (LangChain, CrewAI, Google Gen AI, etc.). It runs
5
+ the provided Python source inside a self-healing sandbox and returns either the
6
+ stdout or a structured error report.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from collections.abc import Callable
12
+
13
+ from codeshield.environment import SandboxError
14
+ from codeshield.loop import SelfHealingEngine, SelfHealingError
15
+ from codeshield.runner import SubprocessRunnerError
16
+
17
+
18
+ def create_code_execution_tool(
19
+ engine: SelfHealingEngine | None = None,
20
+ ) -> Callable[[str], str]:
21
+ """Return a drop-in ``execute_python_code(code: str) -> str`` tool.
22
+
23
+ Args:
24
+ engine: Optional ``SelfHealingEngine`` instance. When ``None``, a fresh
25
+ engine is created for each tool call.
26
+
27
+ Returns:
28
+ A callable ready to be registered as an agent tool.
29
+ """
30
+
31
+ def execute_python_code(code: str) -> str:
32
+ """Execute Python code in an isolated, self-healing sandbox.
33
+
34
+ Use this tool to run numerical, statistical or data-processing
35
+ computations that cannot be done directly in the conversation.
36
+
37
+ Args:
38
+ code: A valid Python script as a string.
39
+
40
+ Returns:
41
+ The stdout of the script if execution succeeds, or a structured
42
+ error report if it fails after all self-healing attempts.
43
+ """
44
+ _engine = engine or SelfHealingEngine()
45
+ with _engine:
46
+ try:
47
+ result, diagnosis = _engine.run(code)
48
+ except SelfHealingError as exc:
49
+ return f"error_type: SelfHealingError\nmessage: {exc}"
50
+ except (SandboxError, SubprocessRunnerError) as exc:
51
+ return f"error_type: {type(exc).__name__}\nmessage: {exc}"
52
+
53
+ if (
54
+ result.exit_code == 0
55
+ and not result.silent_failure_detected
56
+ and not result.timed_out
57
+ ):
58
+ return result.stdout.strip()
59
+
60
+ report: list[str] = ["The Python script did not execute successfully."]
61
+ if diagnosis is not None:
62
+ report.append(f"error_type: {diagnosis.error_type}")
63
+ if diagnosis.root_cause_line is not None:
64
+ report.append(f"root_cause_line: {diagnosis.root_cause_line}")
65
+ if diagnosis.message:
66
+ report.append(f"message: {diagnosis.message}")
67
+ if result.stderr.strip():
68
+ report.append(f"stderr: {result.stderr.strip()}")
69
+ if result.timed_out:
70
+ report.append("timed_out: true")
71
+ if result.silent_failure_detected:
72
+ report.append("silent_failure_detected: true")
73
+
74
+ return "\n".join(report)
75
+
76
+ return execute_python_code
@@ -0,0 +1,277 @@
1
+ Metadata-Version: 2.5
2
+ Name: codeshield-runtime
3
+ Version: 0.1.0
4
+ Summary: A secure, isolated, and self-healing Python code execution engine powered by uv and AST analysis.
5
+ Project-URL: Homepage, https://github.com/AlgorithmicMind/codeshield
6
+ Project-URL: Repository, https://github.com/AlgorithmicMind/codeshield
7
+ Project-URL: Issues, https://github.com/AlgorithmicMind/codeshield/issues
8
+ Author: Senior Python Core Engineer
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ast,code,execution,sandbox,self-healing,uv
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: pydantic>=2.0
23
+ Requires-Dist: tenacity>=8.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: build>=1.0.0; extra == 'dev'
26
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
27
+ Provides-Extra: lint
28
+ Requires-Dist: ruff>=0.5.0; extra == 'lint'
29
+ Provides-Extra: llm
30
+ Requires-Dist: google-genai>=0.1.0; extra == 'llm'
31
+ Requires-Dist: python-dotenv>=1.0.0; extra == 'llm'
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest-cov>=4.0; extra == 'test'
34
+ Requires-Dist: pytest>=7.0; extra == 'test'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # CodeShield: Autonomous Code Execution Engine
38
+
39
+ [![CI](https://img.shields.io/github/actions/workflow/status/AlgorithmicMind/codeshield/ci.yml?branch=main&label=CI)](https://github.com/AlgorithmicMind/codeshield/actions)
40
+ [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue)](https://www.python.org/)
41
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
42
+ [![Code Style: Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
43
+
44
+ > Deterministic, Isolated, and Self-Healing Python Execution Runtime for AI Agents.
45
+
46
+ This open-source engine executes Python code generated by LLMs inside a disposable, isolated sandbox, validates it statically with the Python `ast` module, and recovers from runtime errors through a deterministic self-healing loop backed by local heuristics and plug-and-play LLM-guided patch generation (OpenAI, Anthropic Claude, DeepSeek, Ollama, Google Gemini).
47
+
48
+ ## Comparison
49
+
50
+ | Feature | Vanilla `subprocess` | Docker Container | CodeShield (This Engine) |
51
+ | :--- | :--- | :--- | :--- |
52
+ | **Startup Overhead** | ~5 – 10 ms | ~1,500 – 3,000 ms | **Sub-second (~30–250 ms via `uv`)** |
53
+ | **Isolation Mechanism** | None (Host Process) | Container Namespaces / cgroups | **Ephemeral Virtualenv (`tempfile` + `uv`)** |
54
+ | **AST Security Gate** | ❌ None | ❌ None | **✅ Static AST inspection (`os.system`, `eval`)** |
55
+ | **Silent Failure Detection** | ❌ None | ❌ None | **✅ Regex scanning for empty DataFrames/NaNs** |
56
+ | **Self-Healing Loop** | ❌ None | ❌ None | **✅ 3-Tier Traceback Diagnosis + LLM Patch (Any Provider)** |
57
+
58
+ ---
59
+
60
+ ## Architecture
61
+
62
+ ```text
63
+ [LLM Generated Code]
64
+
65
+
66
+ [AST Static Gate] ──(Syntax/Security Violation)──► [Validation Error Report]
67
+ │ (Passed)
68
+
69
+ [uv Isolated Sandbox] ──(Runtime Error/Silent Failure)──► [Traceback Classifier]
70
+ │ │
71
+ │ (Clean Execution: exit 0) ▼
72
+ ▼ [LLM Self-Healing (Any Provider) / Local Heuristic]
73
+ [Verified Output (JSON)] ◄──(AST Validated Patch)─────────────────┘
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Key Features
79
+
80
+ ### 1. Ephemeral Sandboxing with Dual-Mode Backend
81
+
82
+ - **Primary**: `uv venv` for ultra-fast environment creation and package installation.
83
+ - **Fallback**: native `python -m venv` + `pip` when `uv` is unavailable, so the engine works out of the box on any machine.
84
+ - Each execution lands in its own temporary workspace that is destroyed after use.
85
+
86
+ ### 2. Deterministic AST Security Gates
87
+
88
+ The engine parses every snippet with the standard `ast` module and rejects:
89
+
90
+ - `SyntaxError`s before execution.
91
+ - Bare `except:` / `except Exception:` / `except BaseException:` handlers.
92
+ - Calls to dangerous parametrizable functions: `eval()`, `exec()`, `compile()`.
93
+ - Calls to system/subprocess primitives: `os.system()`, `subprocess.call()`, `subprocess.run()`, `subprocess.Popen()`.
94
+
95
+ ### 3. Silent Failure Detection
96
+
97
+ Even when a process exits with `0`, the engine flags suspicious output patterns such as:
98
+
99
+ - `empty DataFrame`
100
+ - `all NaN`
101
+ - `Traceback`
102
+ - `Pipeline failed`
103
+ - `Fatal Error`
104
+
105
+ ### 4. Model-Agnostic Self-Healing Loop
106
+
107
+ ```text
108
+ AST Validation ──► Sandbox Execution ──► Traceback Classification ──► Patch ──► Re-run
109
+ (3 attempts max)
110
+ ```
111
+
112
+ - **Local heuristic fallback**: handles `NameError`, `ImportError`, `ModuleNotFoundError` by injecting safe imports or placeholder definitions.
113
+ - **LLM-guided healing**: when an LLM is configured (built-in Gemini Flash by default, or any custom provider via `patch_generator`), it asks the model for a corrected version of the code, validates it with the AST gate, and re-executes the patched snippet.
114
+
115
+ ---
116
+
117
+ ## Quickstart
118
+
119
+ ### Installation
120
+
121
+ ```bash
122
+ # Install from PyPI
123
+ pip install codeshield-runtime
124
+
125
+ # Install with all extras (LLM + Dev tools)
126
+ pip install "codeshield-runtime[llm,dev]"
127
+
128
+ # Or clone for development
129
+ git clone https://github.com/AlgorithmicMind/codeshield.git
130
+ cd codeshield
131
+
132
+ # With uv (recommended)
133
+ uv venv
134
+ uv pip install -e ".[test,lint,llm,dev]"
135
+
136
+ # Or with pip
137
+ python -m venv .venv
138
+ .venv\Scripts\activate # Windows
139
+ pip install -e ".[test,lint,llm,dev]"
140
+ ```
141
+
142
+ ### Offline Usage (No API Key)
143
+
144
+ ```python
145
+ from codeshield.loop import SelfHealingEngine
146
+
147
+ engine = SelfHealingEngine(use_llm=False)
148
+ with engine:
149
+ result, diagnosis = engine.run("print('hello world')")
150
+ print(result.stdout)
151
+ ```
152
+
153
+ ### Model-Agnostic Self-Healing (Plug-and-Play)
154
+
155
+ CodeShield is not locked into a single LLM. Pass any Python callable as the `patch_generator` to use OpenAI, Anthropic Claude, DeepSeek, Ollama, LiteLLM or your own service:
156
+
157
+ ```python
158
+ from codeshield.loop import SelfHealingEngine
159
+
160
+
161
+ def custom_openai_patcher(code: str, diagnosis) -> str:
162
+ # Any LLM call (OpenAI, Anthropic, DeepSeek, Ollama, LiteLLM)
163
+ response = client.chat.completions.create(
164
+ model="gpt-4o-mini",
165
+ messages=[
166
+ {
167
+ "role": "user",
168
+ "content": f"Fix this code:\n{code}\nError: {diagnosis.message}",
169
+ }
170
+ ],
171
+ )
172
+ return response.choices[0].message.content
173
+
174
+
175
+ engine = SelfHealingEngine(patch_generator=custom_openai_patcher)
176
+ ```
177
+
178
+ ### Zero-Config Self-Healing with Gemini Flash
179
+
180
+ For the built-in zero-config experience, create a `.env` file from `.env.example`:
181
+
182
+ ```text
183
+ GEMINI_API_KEY=your_key_here
184
+ GEMINI_MODEL=gemini-3.7-flash
185
+ ```
186
+
187
+ ```python
188
+ from dotenv import load_dotenv
189
+ from codeshield.loop import SelfHealingEngine
190
+
191
+ load_dotenv()
192
+
193
+ engine = SelfHealingEngine()
194
+ with engine:
195
+ result, diagnosis = engine.run('print("Result: " + 42)')
196
+ print(result.stdout) # Result: 42
197
+ ```
198
+
199
+ Run the included demo:
200
+
201
+ ```bash
202
+ python demo.py
203
+ ```
204
+
205
+ ### CLI Usage
206
+
207
+ Execute any Python file directly from the terminal with the built-in CLI:
208
+
209
+ ```bash
210
+ python -m codeshield run script.py
211
+ python -m codeshield run script.py --timeout 30
212
+ python -m codeshield run script.py --llm # try LLM self-healing if configured
213
+ python -m codeshield run script.py --no-llm # force local fallback
214
+ ```
215
+
216
+ ## 🤖 Agent Tool Integration (LangChain, CrewAI, OpenAI, Gen AI)
217
+
218
+ ```python
219
+ from codeshield import create_code_execution_tool
220
+
221
+ # Pass the tool directly to your agent
222
+ tools = [create_code_execution_tool()]
223
+ ```
224
+
225
+ `create_code_execution_tool()` returns a ready-to-register `execute_python_code(code: str) -> str` function. It runs the provided Python in a self-healing sandbox and returns either the stdout or a structured error report with `error_type` and `stderr`.
226
+
227
+ ---
228
+
229
+ ## Verified Examples
230
+
231
+ The `examples/` folder contains ready-to-run recipes that have been executed and verified:
232
+
233
+ - `01_basic_sandboxing.py`: isolated execution with timing measurements.
234
+ - `02_security_gatekeeper.py`: AST rejection of unsafe code.
235
+ - `03_llm_healing_workflow.py`: self-healing workflow with an LLM or local fallback.
236
+ - `04_agent_tool_dropin.py`: end-to-end agentic tool-calling workflow with dynamic code generation.
237
+
238
+ ```bash
239
+ python examples/01_basic_sandboxing.py
240
+ python examples/02_security_gatekeeper.py
241
+ python examples/03_llm_healing_workflow.py
242
+ python examples/04_agent_tool_dropin.py
243
+ ```
244
+
245
+ ## Running Tests & Lint
246
+
247
+ The suite currently has **50 tests** with **>82% code coverage** on `src/codeshield`.
248
+
249
+ ```bash
250
+ ruff check src tests examples
251
+ pytest tests -v --cov=src/codeshield
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Enterprise Architecture & Custom Deployments
257
+
258
+ This repository ships the **core execution and healing engine**. For production multi-tenant deployments, the enterprise extension adds:
259
+
260
+ - **Multi-tenant orchestrator** with queue-based job scheduling.
261
+ - **PostgreSQL state persistence** for execution history, audit trails and replay.
262
+ - **Automated billing and token governance** (cost caps per tenant, per-execution budgets).
263
+ - **Prometheus/Grafana observability**, RBAC, and signed artifact provenance.
264
+ - **SLA-backed support** and custom agentic architecture consulting.
265
+
266
+ **Want the production-grade version or a tailored integration for your platform?**
267
+
268
+ - [Open a GitHub issue](https://github.com/AlgorithmicMind/codeshield/issues)
269
+ - [Connect on LinkedIn](https://www.linkedin.com/in/pedro-castejon-jodar/)
270
+
271
+ We offer enterprise licensing, dedicated onboarding and custom agentic-architecture consulting.
272
+
273
+ ---
274
+
275
+ ## License
276
+
277
+ This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,14 @@
1
+ codeshield/__init__.py,sha256=eIwleitreZatH9h9UeTlGzq4MEuK8z8QNPcCWSkSek4,407
2
+ codeshield/__main__.py,sha256=7FgV8lAFEGbFbb7J83AO9r6xQeUiCKMc2kpc8jRMiws,186
3
+ codeshield/analyzer.py,sha256=3gkVnexxGZCR5rBlb5qYUE3qW_lDUz9jQe8_RRpvrxg,5346
4
+ codeshield/classifier.py,sha256=v0dZl8Ba0nhfiqtGKd_-UwjUpBeNiF3fxRd6c-JRL-g,5991
5
+ codeshield/cli.py,sha256=da2SIcVS_pw1D0ja0JDjlCoxRJI-srOqvxhKPzQDG_E,2880
6
+ codeshield/environment.py,sha256=2vgu_VUE-DXXPv8pmdKogai-jAV2TMdmKtpnWyPCU_w,9387
7
+ codeshield/loop.py,sha256=teWZ7csdjOGCJOV0upQt5gYtNyzC4IbtLxNXTaI2TG0,15654
8
+ codeshield/runner.py,sha256=AGb55tpCP87biSw2XRoSgSg_tQP45cRZcHV8aBCLR88,7819
9
+ codeshield/schemas.py,sha256=hkpedvTylyn5TfjVz-iFWL0ugGkZm9dzSnNbN4vXlYU,4248
10
+ codeshield/tools.py,sha256=bKVIFx20e2d-fjOw1QBre0sNNcCf7RSPyXaWTadAsB8,2803
11
+ codeshield_runtime-0.1.0.dist-info/METADATA,sha256=I1S11xdx1hcZjFVWkQa_LFK91pr2cMMXr99rLgiTogI,10050
12
+ codeshield_runtime-0.1.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
13
+ codeshield_runtime-0.1.0.dist-info/licenses/LICENSE,sha256=AOVzp38xpBSknCuDOjR2lgdX1-Xj-k129vwvLKr07Go,1102
14
+ codeshield_runtime-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Autonomous Code Execution Engine contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.