If a skill requires reusable helper functions, you can include a kernel.py (Python) or kernel.R (R) file at the skill's root. When an agent calls a skill, these files are executed in a persistent kernel, making the defined functions available to the agent.
Validation Rules for kernel.py (Top-level restrictions):
To ensure safe loading, only specific constructs are allowed at the module level. Anything else (classes, function calls, if/for blocks, non-literal assignments) will cause a [kernel.py rejected] error.
- Functions: Use
def or async def. No decorators are allowed at the top level. Default arguments must be literals (e.g., def f(url=None):). Do not use def f(url=MY_CONSTANT):. - Imports: Use
import or from ... import name. No import * is allowed. Defer third-party imports (like requests) to inside function bodies. The environment includes a starter set: numpy, pandas, scipy, matplotlib, seaborn, and pillow. - Constants: You may assign literals to plain names (e.g.,
VERSION = "1"). Computed values like os.path.join(...) are rejected and must be moved inside functions. - Naming: Names starting with
_ are reserved by the loader and cannot be used at the top level.
Accessing the Skill Directory:
Because the skill directory is not on sys.path, you cannot use from scripts.X import .... To run a standalone script located in the scripts/ directory, use sys._getframe().f_code.co_filename to locate the directory and subprocess to execute it.
# kernel.py
import os, sys, subprocess
def run_pipeline(cfg_path):
# Locate the skill directory via the function's code filename
here = os.path.dirname(sys._getframe().f_code.co_filename)
if not here:
raise RuntimeError("skill dir unavailable in this runtime")
# Path to a standalone script in the scripts/ folder
tool = os.path.join(here, "scripts", "pipeline.py")
# Execute via subprocess
return subprocess.run([sys.executable, tool, cfg_path],
capture_output=True, text=True, check=True).stdout