Files
cleveragents-core/features/steps/safety_profile_steps.py
T
HAL9000 848bdc47bb
CI / lint (pull_request) Successful in 40s
CI / helm (pull_request) Successful in 33s
CI / quality (pull_request) Successful in 56s
CI / typecheck (pull_request) Successful in 1m1s
CI / push-validation (pull_request) Successful in 38s
CI / build (pull_request) Successful in 1m17s
CI / security (pull_request) Successful in 2m14s
CI / unit_tests (pull_request) Successful in 5m27s
CI / docker (pull_request) Successful in 2m49s
CI / coverage (pull_request) Successful in 11m50s
CI / integration_tests (pull_request) Successful in 18m6s
CI / status-check (pull_request) Successful in 15s
style: apply ruff format to safety profile files
2026-06-06 01:37:38 -04:00

795 lines
30 KiB
Python

"""Step definitions for Safety Profile domain model tests."""
from typing import Any
from behave import given, then, when
from behave.runner import Context
from pydantic import ValidationError
from cleveragents.domain.models.core.safety_profile import (
DEFAULT_SAFETY_PROFILE,
SafetyProfile,
SafetyProfileProvenance,
SafetyProfileRef,
get_builtin_safety_profile,
resolve_safety_profile,
)
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _make_safety(**overrides: Any) -> SafetyProfile:
"""Create a SafetyProfile with sensible defaults."""
return SafetyProfile(**overrides)
# ---------------------------------------------------------------------------
# Default construction
# ---------------------------------------------------------------------------
@when("I create a default safety profile")
def step_create_default_safety(context: Context) -> None:
"""Create a default safety profile."""
context.safety_model = _make_safety()
context.safety_error = None
# ---------------------------------------------------------------------------
# Category parsing
# ---------------------------------------------------------------------------
@when('I create a safety profile with categories "{cats}"')
def step_create_safety_with_cats(context: Context, cats: str) -> None:
"""Create a safety profile with specific categories."""
cat_list = [c for c in cats.split(",")]
context.safety_model = _make_safety(allowed_skill_categories=cat_list)
context.safety_error = None
# ---------------------------------------------------------------------------
# Constraint validation
# ---------------------------------------------------------------------------
@when("I try to create a safety profile with max_cost_per_plan {value:g}")
def step_try_safety_cost(context: Context, value: float) -> None:
"""Try creating a safety profile with max_cost_per_plan."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(max_cost_per_plan=value)
except ValidationError as e:
context.safety_error = e
@when("I try to create a safety profile with max_total_cost {value:g}")
def step_try_safety_total_cost(context: Context, value: float) -> None:
"""Try creating with invalid max_total_cost."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(max_total_cost=value)
except ValidationError as e:
context.safety_error = e
@when("I try to create a safety profile with max_retries_per_step {value:d}")
def step_try_safety_retries(context: Context, value: int) -> None:
"""Try creating with invalid max_retries_per_step."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(max_retries_per_step=value)
except ValidationError as e:
context.safety_error = e
@when("I create a safety profile with max_cost_per_plan {value:g}")
def step_create_safety_cost(context: Context, value: float) -> None:
"""Create a safety profile with specific max_cost_per_plan."""
context.safety_model = _make_safety(max_cost_per_plan=value)
context.safety_error = None
@when("I create a safety profile with max_retries_per_step {value:d}")
def step_create_safety_retries(context: Context, value: int) -> None:
"""Create a safety profile with specific max_retries_per_step."""
context.safety_model = _make_safety(max_retries_per_step=value)
context.safety_error = None
# ---------------------------------------------------------------------------
# Cross-field validation
# ---------------------------------------------------------------------------
@when("I try to create a safety profile with cost {cost:g} and total {total:g}")
def step_try_safety_cost_exceeds_total(
context: Context, cost: float, total: float
) -> None:
"""Try creating a safety profile where max_cost_per_plan > max_total_cost."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(
max_cost_per_plan=cost, max_total_cost=total
)
except ValidationError as e:
context.safety_error = e
@when("I create a safety profile with cost {cost:g} and total {total:g}")
def step_create_safety_cost_and_total(
context: Context, cost: float, total: float
) -> None:
"""Create a safety profile with both cost limits."""
context.safety_model = _make_safety(max_cost_per_plan=cost, max_total_cost=total)
context.safety_error = None
# ---------------------------------------------------------------------------
# Category type guard
# ---------------------------------------------------------------------------
@when("I try to create a safety profile with non-string categories")
def step_try_safety_non_string_cats(context: Context) -> None:
"""Try creating a safety profile with non-string categories."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(
allowed_skill_categories=["valid", 123, None]
)
except ValidationError as e:
context.safety_error = e
@when("I try to create a safety profile with non-list categories")
def step_try_safety_non_list_cats(context: Context) -> None:
"""Try creating a safety profile with a non-list categories value."""
context.safety_error = None
context.safety_model = None
try:
context.safety_model = _make_safety(allowed_skill_categories="not-a-list")
except ValidationError as e:
context.safety_error = e
# ---------------------------------------------------------------------------
# from_config factory
# ---------------------------------------------------------------------------
@when("I load a safety profile from config with require_sandbox false")
def step_load_safety_config_sandbox(context: Context) -> None:
"""Load from config with require_sandbox false."""
config = {"require_sandbox": False}
context.safety_model = SafetyProfile.from_config(config)
context.safety_error = None
@when("I load a safety profile from full config")
def step_load_safety_full_config(context: Context) -> None:
"""Load from config with all fields."""
config = {
"require_sandbox": False,
"require_checkpoints": False,
"require_human_approval": True,
"allow_unsafe_tools": True,
"max_cost_per_plan": 50.0,
"max_retries_per_step": 5,
"max_total_cost": 200.0,
"allowed_skill_categories": ["code", "test"],
}
context.safety_model = SafetyProfile.from_config(config)
context.safety_error = None
# ---------------------------------------------------------------------------
# DEFAULT_SAFETY_PROFILE constant
# ---------------------------------------------------------------------------
@when("I load the default safety profile constant")
def step_load_default_constant(context: Context) -> None:
"""Load DEFAULT_SAFETY_PROFILE."""
context.safety_model = DEFAULT_SAFETY_PROFILE
context.safety_error = None
# ---------------------------------------------------------------------------
# SafetyProfileRef
# ---------------------------------------------------------------------------
@when('I create a safety profile ref with name "{name}" and provenance "{prov}"')
def step_create_safety_ref(context: Context, name: str, prov: str) -> None:
"""Create a SafetyProfileRef."""
context.safety_ref = SafetyProfileRef(
profile_name=name,
provenance=SafetyProfileProvenance(prov),
)
context.safety_error = None
@when("I try to create a safety profile ref with empty name")
def step_try_create_empty_ref(context: Context) -> None:
"""Try creating ref with empty name."""
context.safety_error = None
try:
SafetyProfileRef(
profile_name="",
provenance=SafetyProfileProvenance.PLAN,
)
except ValidationError as e:
context.safety_error = e
# ---------------------------------------------------------------------------
# resolve_safety_profile precedence
# ---------------------------------------------------------------------------
@given("a plan safety profile with allow_unsafe_tools {val}")
def step_given_plan_profile(context: Context, val: str) -> None:
"""Set plan-level safety profile."""
context.resolve_plan = SafetyProfile(allow_unsafe_tools=val.lower() == "true")
@given("an action safety profile with allow_unsafe_tools {val}")
def step_given_action_profile(context: Context, val: str) -> None:
"""Set action-level safety profile."""
context.resolve_action = SafetyProfile(allow_unsafe_tools=val.lower() == "true")
@given("a project safety profile with allow_unsafe_tools {val}")
def step_given_project_profile(context: Context, val: str) -> None:
"""Set project-level safety profile."""
context.resolve_project = SafetyProfile(allow_unsafe_tools=val.lower() == "true")
@given("a global safety profile with allow_unsafe_tools {val}")
def step_given_global_profile(context: Context, val: str) -> None:
"""Set global-level safety profile."""
context.resolve_global = SafetyProfile(allow_unsafe_tools=val.lower() == "true")
@given("a full plan safety profile with all fields customized")
def step_given_full_plan_profile(context: Context) -> None:
"""Set plan-level safety profile with all 8 fields customized."""
context.resolve_plan = SafetyProfile(
require_sandbox=False,
require_checkpoints=False,
allow_unsafe_tools=True,
require_human_approval=True,
allowed_skill_categories=["code", "test"],
max_cost_per_plan=50.0,
max_retries_per_step=7,
max_total_cost=200.0,
)
@given("a full action safety profile with defaults")
def step_given_full_action_defaults(context: Context) -> None:
"""Set action-level safety profile with all defaults."""
context.resolve_action = SafetyProfile()
@given("a full action safety profile with all fields customized")
def step_given_full_action_profile(context: Context) -> None:
"""Set action-level safety profile with all 8 fields customized."""
context.resolve_action = SafetyProfile(
require_sandbox=False,
require_checkpoints=False,
allow_unsafe_tools=True,
require_human_approval=True,
allowed_skill_categories=["code", "test"],
max_cost_per_plan=50.0,
max_retries_per_step=7,
max_total_cost=200.0,
)
@when("I resolve the safety profile")
def step_resolve_profile(context: Context) -> None:
"""Resolve safety profile with whatever levels are set."""
plan = getattr(context, "resolve_plan", None)
action = getattr(context, "resolve_action", None)
project = getattr(context, "resolve_project", None)
global_ = getattr(context, "resolve_global", None)
profile, provenance = resolve_safety_profile(
plan_profile=plan,
action_profile=action,
project_profile=project,
global_profile=global_,
)
context.resolved_profile = profile
context.resolved_provenance = provenance
@when("I resolve the safety profile with no levels")
def step_resolve_profile_none(context: Context) -> None:
"""Resolve safety profile with all levels as None."""
profile, provenance = resolve_safety_profile()
context.resolved_profile = profile
context.resolved_provenance = provenance
@then('the resolved provenance should be "{expected}"')
def step_check_resolved_provenance(context: Context, expected: str) -> None:
"""Check resolved provenance value."""
actual = context.resolved_provenance.value
assert actual == expected, f"Expected provenance '{expected}', got '{actual}'"
@then("the resolved profile allow_unsafe_tools should be {expected}")
def step_check_resolved_allow_unsafe(context: Context, expected: str) -> None:
"""Check resolved profile allow_unsafe_tools."""
exp_bool = expected.lower() == "true"
actual = context.resolved_profile.allow_unsafe_tools
assert actual is exp_bool, f"Expected allow_unsafe_tools {exp_bool}, got {actual}"
@then("the resolved profile require_sandbox should be {expected}")
def step_check_resolved_require_sandbox(context: Context, expected: str) -> None:
"""Check resolved profile require_sandbox."""
exp_bool = expected.lower() == "true"
actual = context.resolved_profile.require_sandbox
assert actual is exp_bool, f"Expected require_sandbox {exp_bool}, got {actual}"
@then("the resolved profile require_checkpoints should be {expected}")
def step_check_resolved_require_checkpoints(context: Context, expected: str) -> None:
"""Check resolved profile require_checkpoints."""
exp_bool = expected.lower() == "true"
actual = context.resolved_profile.require_checkpoints
assert actual is exp_bool, f"Expected require_checkpoints {exp_bool}, got {actual}"
@then("the resolved profile require_human_approval should be {expected}")
def step_check_resolved_require_human_approval(context: Context, expected: str) -> None:
"""Check resolved profile require_human_approval."""
exp_bool = expected.lower() == "true"
actual = context.resolved_profile.require_human_approval
assert actual is exp_bool, (
f"Expected require_human_approval {exp_bool}, got {actual}"
)
@then("the resolved profile max_cost_per_plan should be {expected:g}")
def step_check_resolved_max_cost(context: Context, expected: float) -> None:
"""Check resolved profile max_cost_per_plan."""
actual = context.resolved_profile.max_cost_per_plan
assert actual == expected, f"Expected max_cost_per_plan {expected}, got {actual}"
@then("the resolved profile max_retries_per_step should be {expected:d}")
def step_check_resolved_max_retries(context: Context, expected: int) -> None:
"""Check resolved profile max_retries_per_step."""
actual = context.resolved_profile.max_retries_per_step
assert actual == expected, f"Expected max_retries_per_step {expected}, got {actual}"
@then("the resolved profile max_total_cost should be {expected:g}")
def step_check_resolved_max_total_cost(context: Context, expected: float) -> None:
"""Check resolved profile max_total_cost."""
actual = context.resolved_profile.max_total_cost
assert actual == expected, f"Expected max_total_cost {expected}, got {actual}"
@then('the resolved profile allowed_skill_categories should be "{expected}"')
def step_check_resolved_categories(context: Context, expected: str) -> None:
"""Check resolved profile allowed_skill_categories."""
expected_cats = [c.strip() for c in expected.split(",") if c.strip()]
actual = context.resolved_profile.allowed_skill_categories
assert actual == expected_cats, (
f"Expected allowed_skill_categories {expected_cats}, got {actual}"
)
# ---------------------------------------------------------------------------
# model_dump
# ---------------------------------------------------------------------------
@when("I create a safety profile and dump it")
def step_create_and_dump(context: Context) -> None:
"""Create and dump a safety profile."""
context.safety_model = _make_safety()
context.safety_dump = context.safety_model.model_dump()
context.safety_error = None
# ---------------------------------------------------------------------------
# Action with safety profile
# ---------------------------------------------------------------------------
@when("I create an action with safety profile from config")
def step_create_action_with_safety(context: Context) -> None:
"""Create an Action from config with safety_profile."""
from cleveragents.domain.models.core.action import Action
config = {
"name": "local/test-safety-action",
"description": "Test action with safety profile",
"definition_of_done": "Tests pass",
"strategy_actor": "local/default",
"execution_actor": "local/default",
"safety_profile": {
"require_sandbox": False,
"max_cost_per_plan": 100.0,
},
}
context.action_model = Action.from_config(config)
context.safety_error = None
# ---------------------------------------------------------------------------
# from_yaml edge cases
# ---------------------------------------------------------------------------
@when("I try to load a safety profile from a non-existent yaml file")
def step_try_load_nonexistent_yaml(context: Context) -> None:
"""Try loading from a non-existent YAML file."""
context.safety_error = None
try:
SafetyProfile.from_yaml("/tmp/nonexistent_safety_profile_test.yaml")
except FileNotFoundError as e:
context.safety_error = e
@when("I try to load a safety profile from yaml with non-dict content")
def step_try_load_non_dict_yaml(context: Context) -> None:
"""Try loading from a YAML file that contains a non-dict."""
import tempfile
from pathlib import Path
yaml_content = "- item1\n- item2\n"
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
f.write(yaml_content)
yaml_path = f.name
context.safety_error = None
try:
SafetyProfile.from_yaml(yaml_path)
except ValueError as e:
context.safety_error = e
finally:
Path(yaml_path).unlink(missing_ok=True)
# ---------------------------------------------------------------------------
# validate_assignment (frozen model raises on mutation)
# ---------------------------------------------------------------------------
@when("I try to assign max_retries_per_step {value:d} on the safety profile")
def step_try_assign_retries(context: Context, value: int) -> None:
"""Try assigning on a frozen safety profile (should raise)."""
context.safety_error = None
try:
context.safety_model.max_retries_per_step = value
except ValidationError as e:
context.safety_error = e
# ---------------------------------------------------------------------------
# Assertions
# ---------------------------------------------------------------------------
@then("the safety profile should be created")
def step_safety_created(context: Context) -> None:
"""Verify safety profile was created."""
assert context.safety_model is not None, "Safety profile should exist"
@then("the safety require_sandbox should be {expected}")
def step_check_require_sandbox(context: Context, expected: str) -> None:
"""Check require_sandbox."""
exp_bool = expected.lower() == "true"
actual = context.safety_model.require_sandbox
assert actual is exp_bool, f"Expected require_sandbox {exp_bool}, got {actual}"
@then("the safety require_checkpoints should be {expected}")
def step_check_require_checkpoints(context: Context, expected: str) -> None:
"""Check require_checkpoints."""
exp_bool = expected.lower() == "true"
actual = context.safety_model.require_checkpoints
assert actual is exp_bool, f"Expected require_checkpoints {exp_bool}, got {actual}"
@then("the safety require_human_approval should be {expected}")
def step_check_human_approval(context: Context, expected: str) -> None:
"""Check require_human_approval."""
exp_bool = expected.lower() == "true"
actual = context.safety_model.require_human_approval
assert actual is exp_bool, (
f"Expected require_human_approval {exp_bool}, got {actual}"
)
@then("the safety allow_unsafe_tools should be {expected}")
def step_check_allow_unsafe_tools(context: Context, expected: str) -> None:
"""Check allow_unsafe_tools."""
exp_bool = expected.lower() == "true"
actual = context.safety_model.allow_unsafe_tools
assert actual is exp_bool, f"Expected allow_unsafe_tools {exp_bool}, got {actual}"
@then("the safety max_retries_per_step should be {expected:d}")
def step_check_max_retries(context: Context, expected: int) -> None:
"""Check max_retries_per_step."""
actual = context.safety_model.max_retries_per_step
assert actual == expected, f"Expected max_retries {expected}, got {actual}"
@then("the safety max_cost_per_plan should be none")
def step_check_cost_none(context: Context) -> None:
"""Check max_cost_per_plan is None."""
assert context.safety_model.max_cost_per_plan is None
@then("the safety max_cost_per_plan should be {expected:g}")
def step_check_cost_value(context: Context, expected: float) -> None:
"""Check max_cost_per_plan value."""
actual = context.safety_model.max_cost_per_plan
assert actual == expected, f"Expected max_cost_per_plan {expected}, got {actual}"
@then("the safety max_total_cost should be none")
def step_check_total_cost_none(context: Context) -> None:
"""Check max_total_cost is None."""
assert context.safety_model.max_total_cost is None
@then("the safety max_total_cost should be {expected:g}")
def step_check_total_cost_value(context: Context, expected: float) -> None:
"""Check max_total_cost value."""
actual = context.safety_model.max_total_cost
assert actual == expected, f"Expected max_total_cost {expected}, got {actual}"
@then("the safety allowed_skill_categories should be empty")
def step_check_cats_empty(context: Context) -> None:
"""Check allowed_skill_categories is empty."""
assert context.safety_model.allowed_skill_categories == []
@then("the safety allowed_skill_categories count should be {expected:d}")
def step_check_cats_count(context: Context, expected: int) -> None:
"""Check allowed_skill_categories count."""
actual = len(context.safety_model.allowed_skill_categories)
assert actual == expected, f"Expected {expected} categories, got {actual}"
@then("a safety validation error should be raised")
def step_check_safety_error(context: Context) -> None:
"""Verify validation error was raised."""
assert context.safety_error is not None, "Expected a validation error"
@then("a safety FileNotFoundError should be raised")
def step_check_safety_file_not_found(context: Context) -> None:
"""Verify FileNotFoundError was raised."""
assert context.safety_error is not None, "Expected a FileNotFoundError"
assert isinstance(context.safety_error, FileNotFoundError)
@then("a safety ValueError should be raised")
def step_check_safety_value_error(context: Context) -> None:
"""Verify ValueError was raised."""
assert context.safety_error is not None, "Expected a ValueError"
assert isinstance(context.safety_error, ValueError)
@then('the safety profile ref should have name "{expected}"')
def step_check_ref_name(context: Context, expected: str) -> None:
"""Check safety profile ref name."""
assert context.safety_ref.profile_name == expected
@then('the safety profile ref should have provenance "{expected}"')
def step_check_ref_provenance(context: Context, expected: str) -> None:
"""Check safety profile ref provenance."""
actual = context.safety_ref.provenance.value
assert actual == expected, f"Expected provenance '{expected}', got '{actual}'"
@then("a NotImplementedError should be raised")
def step_check_not_implemented(context: Context) -> None:
"""Verify NotImplementedError was raised."""
assert context.resolve_error is not None, "Expected NotImplementedError"
@then('the resolve error should mention "{text}"')
def step_check_resolve_error_text(context: Context, text: str) -> None:
"""Check resolve error message contains text."""
error_str = str(context.resolve_error)
assert text in error_str, f"Expected error to mention '{text}', got: {error_str}"
# NOTE: The above two steps are retained for backward compatibility.
# They are no longer used by safety_profile.feature (the resolve stub was
# replaced with real implementation tests) but may be referenced elsewhere.
@then('the safety dump should have key "{key}"')
def step_check_safety_dump_key(context: Context, key: str) -> None:
"""Check dump has key."""
assert key in context.safety_dump, f"Expected key '{key}' in dump"
@then("the safety dump require_sandbox should be true")
def step_check_safety_dump_sandbox(context: Context) -> None:
"""Check dump require_sandbox."""
assert context.safety_dump["require_sandbox"] is True
@then("the action safety profile should not be none")
def step_check_action_safety_not_none(context: Context) -> None:
"""Check action has safety profile."""
assert context.action_model.safety_profile is not None
@then("the action safety profile require_sandbox should be false")
def step_check_action_safety_sandbox_false(context: Context) -> None:
"""Check action safety profile require_sandbox."""
assert context.action_model.safety_profile.require_sandbox is False
@then("the action cli dict should contain safety_profile key")
def step_check_action_cli_dict_safety(context: Context) -> None:
"""Check action cli dict has safety_profile."""
cli_dict = context.action_model.as_cli_dict()
assert "safety_profile" in cli_dict, (
f"Expected 'safety_profile' in cli dict, keys: {list(cli_dict)}"
)
# ---------------------------------------------------------------------------
# allowed_tools / denied_tools steps
# ---------------------------------------------------------------------------
@when('I create a safety profile with allowed_tools "{tools}"')
def step_create_safety_allowed_tools(context: Context, tools: str) -> None:
"""Create a safety profile with specific allowed_tools."""
tool_list = [t.strip() for t in tools.split(",") if t.strip()]
try:
context.safety_model = SafetyProfile(
allowed_tools=tool_list,
require_sandbox=False,
require_checkpoints=False,
)
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@when('I create a safety profile with denied_tools "{tools}"')
def step_create_safety_denied_tools(context: Context, tools: str) -> None:
"""Create a safety profile with specific denied_tools."""
tool_list = [t.strip() for t in tools.split(",") if t.strip()]
try:
context.safety_model = SafetyProfile(
denied_tools=tool_list,
require_sandbox=False,
require_checkpoints=False,
)
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@then("the safety allowed_tools count should be {expected:d}")
def step_check_allowed_tools_count(context: Context, expected: int) -> None:
"""Check the number of allowed_tools."""
actual = len(context.safety_model.allowed_tools)
assert actual == expected, f"Expected allowed_tools count {expected}, got {actual}"
@then("the safety denied_tools count should be {expected:d}")
def step_check_denied_tools_count(context: Context, expected: int) -> None:
"""Check the number of denied_tools."""
actual = len(context.safety_model.denied_tools)
assert actual == expected, f"Expected denied_tools count {expected}, got {actual}"
@then("the safety allowed_tools should be empty")
def step_check_allowed_tools_empty(context: Context) -> None:
"""Check that allowed_tools is empty."""
assert context.safety_model.allowed_tools == [], (
f"Expected empty allowed_tools, got {context.safety_model.allowed_tools}"
)
@then("the safety denied_tools should be empty")
def step_check_denied_tools_empty(context: Context) -> None:
"""Check that denied_tools is empty."""
assert context.safety_model.denied_tools == [], (
f"Expected empty denied_tools, got {context.safety_model.denied_tools}"
)
# ---------------------------------------------------------------------------
# Built-in safety profile steps
# ---------------------------------------------------------------------------
@when("I load the unrestricted built-in safety profile")
def step_load_builtin_unrestricted(context: Context) -> None:
"""Load the unrestricted built-in safety profile."""
try:
context.safety_model = get_builtin_safety_profile("unrestricted")
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@when("I load the read-only built-in safety profile")
def step_load_builtin_read_only(context: Context) -> None:
"""Load the read-only built-in safety profile."""
try:
context.safety_model = get_builtin_safety_profile("read-only")
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@when("I load the no-network built-in safety profile")
def step_load_builtin_no_network(context: Context) -> None:
"""Load the no-network built-in safety profile."""
try:
context.safety_model = get_builtin_safety_profile("no-network")
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@when("I load the sandboxed built-in safety profile")
def step_load_builtin_sandboxed(context: Context) -> None:
"""Load the sandboxed built-in safety profile."""
try:
context.safety_model = get_builtin_safety_profile("sandboxed")
context.safety_error = None
except Exception as exc:
context.safety_model = None
context.safety_error = exc
@when('I try to load an unknown built-in safety profile "{name}"')
def step_try_load_unknown_builtin(context: Context, name: str) -> None:
"""Try to load an unknown built-in safety profile."""
try:
context.safety_model = get_builtin_safety_profile(name)
context.safety_error = None
except KeyError as exc:
context.safety_model = None
context.safety_error = exc
@then("a safety KeyError should be raised")
def step_check_safety_key_error(context: Context) -> None:
"""Check that a KeyError was raised."""
assert context.safety_error is not None, (
"Expected a KeyError but no error was raised"
)
assert isinstance(context.safety_error, KeyError), (
f"Expected KeyError, got {type(context.safety_error).__name__}: "
f"{context.safety_error}"
)