Description
Describe the bug
openadapt.replay.replay()
forwards every keyword argument it receives to the chosen strategy’s constructor.
Kwargs that belong only to replay()
itself—e.g. recording_id
, timestamp
, capture
, status_pipe
—end up in the strategy __init__
, which usually does not accept them, raising:
TypeError: VisualReplayStrategy.__init__() got an unexpected keyword argument 'recording_id'
Expected behaviour
replay()
should strip its own kwargs and pass only the ones intended for the strategy constructor.
Actual behaviour
Internal kwargs are forwarded wholesale, triggering the TypeError
above whenever the strategy doesn’t accept them.
Root cause (code)
openadapt/replay.py
, inside replay()
:
strategy = strategy_class(recording, **kwargs) # kwargs still includes recording_id, etc.
Proposed fix
A deny‑list works, but an allow‑list derived from the strategy signature is maintenance‑free:
import inspect
init_params = set(inspect.signature(strategy_class.init).parameters) - {"self"}
strategy_kwargs = {k: v for k, v in kwargs.items() if k in init_params}
strategy = strategy_class(recording, **strategy_kwargs)
logger.debug("Passing to %s: %s", strategy_class.name, strategy_kwargs)
Environment
Item | Value (replace) |
---|---|
OpenAdapt | main @ 1899393 |
Python | 3.11.9 |
OS | macOS 15.3.2 |
Workaround
Subclass the strategy so it absorbs unexpected kwargs:
from openadapt.strategies import VisualReplayStrategy
class PatchedVisualReplayStrategy(VisualReplayStrategy):
def init(self, recording, instructions, **_):
super().init(recording, instructions)
Pass "PatchedVisualReplayStrategy"
to replay()
until the fix lands.
Thanks for maintaining OpenAdapt—happy to open a PR with the patch!
To Reproduce
Minimal repro
from openadapt.replay import replay
replay(
"VisualReplayStrategy", # strategy (positional OK)
recording_id=1, # belongs to replay(), not the strategy
instructions="Do the task" # legitimate strategy kwarg
)
Any strategy whose constructor lacks recording_id (or **kwargs) will fail identically.