Skip to main content

Skyhook

Bind SkyRL environments and their reward functions with decorators. One small module, with SkyRL Gym as its only direct runtime dependency.

Install

Requires Python 3.10 or newer and uv. Run from the project directory:

uv sync

This creates .venv and installs Skyhook and its dependencies. Use uv run to run commands in that environment without manually activating it.

The distribution is named skyhook-rl; the Python import is skyhook. The package includes type annotations for type checkers.

Use

import skyrl_gym
from skyrl_gym.envs.base_text_env import BaseTextEnv
from skyhook import env


@env.textarena_wordle
class WordleEnv(BaseTextEnv):
    def __init__(self, target="crane"):
        super().__init__()
        self.target = target

    def step(self, action):
        return {
            "observations": [{"role": "user", "content": action}],
            "reward": env.textarena_wordle.sum_rewards(self, action),
            "done": action == self.target,
            "metadata": {},
            "postprocessed_action": action,
        }


@env.textarena_wordle.reward
def correct_word(environment, action):
    return 1.0 if action == environment.target else 0.0


@env.textarena_wordle.reward
def turn_cost(environment, action):
    return -0.05


game = skyrl_gym.make("textarena_wordle", target="crane")
game.init([{"role": "user", "content": "Guess the word."}])
assert game.step("crane")["reward"] == 0.95
game.close()

The class decorator calls skyrl_gym.register("textarena_wordle", entry_point=WordleEnv). Both decorators return their inputs unchanged.

sum_rewards(*args, **kwargs) calls each registered reward once, in registration order, forwarding the same arguments to every function, then passes the collected results to Python's built-in sum(). No rewards means the integer 0. Results must support 0 + value and addition with the running total. Decimal, Fraction, and custom addition-compatible types keep their normal addition behavior; incompatible combinations raise Python's usual TypeError.

There is no float conversion or finiteness check, and floating-point precision follows the Python version's built-in sum(). Your environment's step() remains responsible for producing the finite scalar reward expected by SkyRL. Exceptions raised by reward functions or addition propagate unchanged. Async functions are rejected at registration; coroutine results from other callables are closed and rejected, never awaited.

To call just one reward inside step, look it up by its function name:

reward = env.textarena_wordle.rewards["correct_word"](self, action)

rewards is a read-only, insertion-ordered mapping of names to the original callables. A single lookup calls only that function; sum_rewards still calls them all. Direct calls return the original result without aggregation. Missing names raise KeyError, and registering a duplicate name in the same environment raises ValueError instead of replacing or double-counting it.

For a custom name or a callable without __name__, register it explicitly:

env.textarena_wordle.reward(lambda game, action: 0.1, name="bonus")

Rewards can be registered before or after the class, including after environment construction. Only rewards registered before a call to sum_rewards participate. Use env["my-env-v0"] instead of attribute access for names containing punctuation.

Skyhook does not wrap step, replace existing rewards, or install another base class. Call sum_rewards where your environment calculates its reward; add it to an existing base reward explicitly if needed. Duplicate environment IDs raise SkyRL's registration error rather than replacing another environment.

Registration happens at import time and is process-local. Import the modules containing your decorated classes and rewards in each SkyRL/Ray worker before calling skyrl_gym.make. There is no automatic module discovery or worker sync.

Run

uv run python examples/wordle.py
uv run python tests/test_skyhook.py

The example is a tiny word-guessing environment, not the TextArena game engine. The check exercises the real SkyRL registry and make API without a test framework.

GitHub Actions runs the check on every push and pull request using Python 3.10 and 3.12. CI tests a non-editable installation in isolated Python mode, so imports come from the installed package rather than the source checkout:

uv run --locked --no-editable --reinstall-package skyhook-rl python -I tests/test_skyhook.py

--locked enforces uv.lock; regenerate it with uv lock after changing dependencies. --reinstall-package rebuilds Skyhook so source edits are tested instead of an older cached wheel.

Release files for skyhook-rl 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skyhook-rl 0.1.0
File Size Uploaded
skyhook_rl-0.1.0.tar.gz 6.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for skyhook-rl 0.1.0
File Interpreter ABI Platform
skyhook_rl-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.1 kB

Release files / skyhook_rl-0.1.0.tar.gz

Download URL skyhook_rl-0.1.0.tar.gz
Size 6.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e71b5e97248cc9a80b5d3b4a7179907a41366ea5d68833583b3c07b1ac83f692
BLAKE2b-256 checksum
How to use checksums
e6edefb19620cdea59f5a51c3ea8d9e3f74e182f80fd6102166089d6d764eaea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release files / skyhook_rl-0.1.0-py3-none-any.whl

Download URL skyhook_rl-0.1.0-py3-none-any.whl
Size 4.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a9ed0159d31b5e10eecc211b7d7ac994b85fdadec5147ebe9b4c8b7f32df5eb5
BLAKE2b-256 checksum
How to use checksums
14a6379f29e8b39d9c2f57b9b68ea96f43d682c632eece0ce02d2035232c921f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.5

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page