Gate skills behind RLM_ENABLED_TOOLS (default: edit)#30
Conversation
RLM_ENABLED_TOOLS is a comma-separated allowlist of skill names. It filters both the system-prompt "Installed skills" listing (tools.get_installed_skills) and the kernel_shim sys.modules proxies, so that a disabled skill is neither advertised to the agent nor importable from the ipython kernel. The CLI itself stays on PATH. RLM_ENABLED_TOOLS=* opts out of filtering entirely; "" disables every skill; unset defaults to 'edit'. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d4b7209. Configure here.
| raw = os.environ.get("RLM_ENABLED_TOOLS", DEFAULT_ENABLED_TOOLS).strip() | ||
| if raw == "*": | ||
| return None | ||
| return frozenset(name.strip() for name in raw.split(",") if name.strip()) |
There was a problem hiding this comment.
Enabled tools not normalized, breaking hyphenated skill matching
Low Severity
_parse_enabled_tools() returns raw user-provided names without applying _normalize_skill_name, but get_installed_skills() normalizes discovered names (hyphens → underscores) before the set intersection skills &= enabled. A skill whose distribution suffix contains hyphens (e.g. rlm-skill-web-search → discovered as web_search) would never match if the user writes web-search in RLM_ENABLED_TOOLS. Both sides of the intersection need consistent normalization.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d4b7209. Configure here.
| def _parse_enabled_tools() -> frozenset[str] | None: | ||
| """Mirror of rlm.tools._parse_enabled_tools (duplicated to keep this | ||
| module independent of rlm.__init__, which pulls in openai).""" | ||
| raw = os.environ.get("RLM_ENABLED_TOOLS", "edit").strip() |
There was a problem hiding this comment.
Duplicated default diverges from named constant
Low Severity
tools.py introduces a DEFAULT_ENABLED_TOOLS constant to centralize the default, but the duplicated _parse_enabled_tools() in kernel_shim.py hardcodes the string "edit" directly. If someone updates DEFAULT_ENABLED_TOOLS, the kernel shim's default silently diverges, causing the system prompt and kernel to disagree on which skills are enabled.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d4b7209. Configure here.


Summary
Adds an allowlist env var `RLM_ENABLED_TOOLS` that filters discovered skills in two places:
The CLI binaries themselves stay on PATH (we only gate the Python shim and prompt exposure).
Motivation
Both `edit` and `websearch` are installed unconditionally by `install.sh`. Previously this meant every rollout had websearch available regardless of the training config, and there was no way to turn it off short of deleting the skill from the repo or filtering at install time. This env var lets training orchestrators opt skills in/out per run.
Test plan
Verified in a live sandbox (python:3.11-slim):
_kernel_shim_'s filter logic mirrors `tools`, so the same allowlist applies to proxy-module registration in external ipython kernels.
🤖 Generated with Claude Code
Note
Low Risk
Small, localized env-var gating around skill enumeration and shim registration; main risk is misconfiguration unintentionally hiding required tools.
Overview
Introduces
RLM_ENABLED_TOOLSas an allowlist to control which skills are exposed at runtime, defaulting toedit, supporting*for no filtering and empty string for disabling all.Updates
tools.get_installed_skills()to filter discovered skill distributions via this allowlist, and updateskernel_shim.install_shims()to only register proxy modules for enabled skills so disabled tools are neither importable in external IPython kernels nor shown in the system prompt (while leaving the underlying CLIs onPATH).Reviewed by Cursor Bugbot for commit d4b7209. Bugbot is set up for automated code reviews on this repo. Configure here.