Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .env_example
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,36 @@ AZURE_OPENAI_VIDEO_MODEL="sora-2"
AZURE_OPENAI_VIDEO_UNDERLYING_MODEL="sora-2"

OPENAI_VIDEO_ENDPOINT = ${AZURE_OPENAI_VIDEO_ENDPOINT}

##################################
# PLUG-INS
#
# PyRIT can load a non-disclosable plug-in (extra datasets + scenarios) from a
# pre-built wheel at initialization time. Plug-in loading runs automatically as a
# guaranteed-first phase inside initialize_pyrit_async (before the configured
# initializers) — there is nothing to add to .pyrit_conf. The wheel is extracted to
# .plugin/<name>/, prepended to sys.path, imported, and its bootstrap is run so its
# datasets/scenarios register like built-ins. Extraction only — never pip/.venv.
#
# WARNING: loading a plug-in executes third-party code in the PyRIT process.
# Whoever can set PLUGIN_* / write this .env can run code on the host. Treat this
# file as sensitive.
###################################

# Path to a pre-built plug-in wheel on disk. Setting it enables plug-in loading;
# leaving it unset is a no-op.
# PLUGIN_WHEEL="/abs/path/to/my_plugin-0.0.0-py3-none-any.whl"

# Optional: the wheel's top-level import package. Auto-detected from the wheel
# when omitted; set this to disambiguate multi-package wheels.
# PLUGIN_PACKAGE="my_plugin"

# Optional: continue (with a warning) instead of failing when the plug-in cannot
# be loaded. Equivalent to initialize_pyrit_async(plugin_fail_open=True).
# PLUGIN_FAIL_OPEN="false"

# Optional: override the base extraction directory (defaults to <pyrit home>/.plugin).
# PLUGIN_DIR="/abs/path/to/.plugin"
OPENAI_VIDEO_KEY = ${AZURE_OPENAI_VIDEO_KEY}
OPENAI_VIDEO_MODEL = ${AZURE_OPENAI_VIDEO_MODEL}
OPENAI_VIDEO_UNDERLYING_MODEL = ""
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ dbdata/
eval/
default_memory.json.memory

# Plug-in extraction working directory (see DefaultPluginInitializer / PLUGIN_WHEEL).
# The directory is kept; extracted plug-in artifacts are ignored.
.plugin/*
!.plugin/.gitkeep

# Frontend build artifacts copied to backend for packaging
pyrit/backend/frontend/

Expand Down
2 changes: 2 additions & 0 deletions .plugin/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Keeps the .plugin/ directory in version control while its contents stay ignored.
# PyRIT extracts plug-in wheels here at runtime (see PLUGIN_WHEEL).
4 changes: 4 additions & 0 deletions .pyrit_conf_example
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ memory_db_type: sqlite
# - load_default_datasets: Loads datasets into memory so scenarios can run
# - preload_scenario_metadata: Preloads scenario metadata into the registry
#
# Note: plug-ins (PLUGIN_WHEEL) are NOT configured here. They load automatically as a
# guaranteed-first phase inside initialize_pyrit_async — before these initializers — so
# there is no ordering to get right. See the PLUGIN_* variables in .env_example.
#
# Each initializer can be specified as:
# - A simple string (name only)
# - A dictionary with 'name' and optional 'args' for parameters
Expand Down
13 changes: 13 additions & 0 deletions pyrit/setup/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ async def initialize_pyrit_async(
env_files: Sequence[pathlib.Path] | None = None,
env_akv_ref: Sequence[str] | None = None,
silent: bool = False,
plugin_fail_open: bool | None = None,
**memory_instance_kwargs: Any,
) -> None:
"""
Expand All @@ -224,6 +225,9 @@ async def initialize_pyrit_async(
so local files take precedence over AKV. Requires ``azure-keyvault-secrets``.
silent (bool): If True, suppresses print statements about environment file loading and
schema migration. Defaults to False.
plugin_fail_open (bool | None): Overrides ``PLUGIN_FAIL_OPEN`` for plug-in loading. When True,
a plug-in (``PLUGIN_WHEEL``) that fails to load is skipped with a warning instead of raising.
Defaults to None (use the ``PLUGIN_FAIL_OPEN`` environment variable, else fail-closed).
**memory_instance_kwargs (Any | None): Additional keyword arguments to pass to the memory instance.

Raises:
Expand Down Expand Up @@ -259,6 +263,15 @@ async def initialize_pyrit_async(

CentralMemory.set_memory_instance(memory)

# Load a configured plug-in (PLUGIN_WHEEL) as a guaranteed-first phase: after memory
# is set (a plug-in bootstrap may use it) and BEFORE any configured initializers run,
# so plug-in datasets/scenarios are registered before LoadDefaultDatasets and
# PreloadScenarioMetadata read the registry. Ordering is true by construction here, so
# it does not depend on .pyrit_conf list position. No-op unless PLUGIN_WHEEL is set.
from pyrit.setup.plugin_loader import load_plugin_if_configured_async

await load_plugin_if_configured_async(fail_open=plugin_fail_open)

# Combine directly provided initializers with those loaded from scripts
all_initializers = list(initializers) if initializers else []

Expand Down
Loading
Loading