@@ -189,6 +189,7 @@ def safety_wrapper(
189189 policy : Optional [SafetyPolicy ] = None ,
190190 audit_log_path : Optional [str ] = None ,
191191 raise_on_deny : bool = True ,
192+ require_script : bool = True ,
192193):
193194 """Decorator that applies safety checks before a function executes.
194195
@@ -201,6 +202,10 @@ def safety_wrapper(
201202 policy: Optional policy override.
202203 audit_log_path: Path to JSONL audit file.
203204 raise_on_deny: Raise ``SafetyDeniedError`` on DENY.
205+ require_script: If True (default), raise ``RuntimeError`` when
206+ *script_arg_name* is not found — fail-closed so that a
207+ misconfigured decorator does not silently allow execution
208+ without scanning.
204209
205210 Example::
206211
@@ -222,14 +227,17 @@ def decorator(func: Callable) -> Callable:
222227 async def async_wrapper (* args : Any , ** kwargs : Any ) -> Any :
223228 script : Optional [str ] = kwargs .get (script_arg_name )
224229 if script is None :
225- # Try to find it in positional args (e.g. tool_context, args)
226230 for arg in args :
227231 if isinstance (arg , dict ) and script_arg_name in arg :
228232 script = arg [script_arg_name ]
229233 break
230234 if script and isinstance (script , str ):
231235 wrapper_inst .check (script )
232- elif script is not None and not isinstance (script , str ):
236+ elif require_script :
237+ raise RuntimeError (f"safety_wrapper: '{ script_arg_name } ' not found in kwargs or positional "
238+ f"dict args for { func .__name__ } . Check the decorator configuration "
239+ f"or set require_script=False to skip scanning." )
240+ elif script is not None :
233241 _logger .warning ("safety_wrapper: '%s' value is not a string (type=%s) — scan skipped." , script_arg_name ,
234242 type (script ).__name__ )
235243 else :
@@ -248,7 +256,11 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any:
248256 break
249257 if script and isinstance (script , str ):
250258 wrapper_inst .check (script )
251- elif script is not None and not isinstance (script , str ):
259+ elif require_script :
260+ raise RuntimeError (f"safety_wrapper: '{ script_arg_name } ' not found in kwargs or positional "
261+ f"dict args for { func .__name__ } . Check the decorator configuration "
262+ f"or set require_script=False to skip scanning." )
263+ elif script is not None :
252264 _logger .warning ("safety_wrapper: '%s' value is not a string (type=%s) — scan skipped." , script_arg_name ,
253265 type (script ).__name__ )
254266 else :
0 commit comments