|
6 | 6 | import types |
7 | 7 | from collections.abc import Callable |
8 | 8 | from dataclasses import dataclass |
| 9 | +from pathlib import Path |
9 | 10 | from types import SimpleNamespace |
10 | 11 | from typing import Any |
11 | 12 |
|
12 | 13 | import pytest |
13 | 14 |
|
| 15 | +guardrails_pkg = types.ModuleType("guardrails") |
| 16 | +guardrails_pkg.__path__ = [str(Path(__file__).resolve().parents[2] / "src" / "guardrails")] |
| 17 | +sys.modules.setdefault("guardrails", guardrails_pkg) |
| 18 | + |
14 | 19 | from guardrails._openai_utils import SAFETY_IDENTIFIER_HEADER, SAFETY_IDENTIFIER_VALUE |
15 | 20 | from guardrails.types import GuardrailResult |
16 | 21 |
|
@@ -94,7 +99,8 @@ class Agent: |
94 | 99 | """Trivial Agent stub storing initialization args for assertions.""" |
95 | 100 |
|
96 | 101 | name: str |
97 | | - instructions: str |
| 102 | + instructions: str | None = None |
| 103 | + prompt: Any | None = None |
98 | 104 | input_guardrails: list[Callable] | None = None |
99 | 105 | output_guardrails: list[Callable] | None = None |
100 | 106 | tools: list[Any] | None = None |
@@ -597,3 +603,42 @@ def test_guardrail_agent_without_tools(monkeypatch: pytest.MonkeyPatch) -> None: |
597 | 603 | agent_instance = agents.GuardrailAgent(config={}, name="NoTools", instructions="None") |
598 | 604 |
|
599 | 605 | assert getattr(agent_instance, "input_guardrails", []) == [] # noqa: S101 |
| 606 | + |
| 607 | + |
| 608 | +def test_guardrail_agent_allows_prompt_without_instructions(monkeypatch: pytest.MonkeyPatch) -> None: |
| 609 | + """Prompt attribute text becomes derived instructions.""" |
| 610 | + pipeline = SimpleNamespace(pre_flight=None, input=None, output=None) |
| 611 | + |
| 612 | + monkeypatch.setattr(runtime_module, "load_pipeline_bundles", lambda config: pipeline, raising=False) |
| 613 | + monkeypatch.setattr(runtime_module, "instantiate_guardrails", lambda *args, **kwargs: [], raising=False) |
| 614 | + |
| 615 | + prompt = SimpleNamespace(text="Serve customers helpfully.") |
| 616 | + |
| 617 | + agent_instance = agents.GuardrailAgent(config={}, name="PromptOnly", prompt=prompt) |
| 618 | + |
| 619 | + assert agent_instance.prompt is prompt # noqa: S101 |
| 620 | + assert agent_instance.instructions == "Serve customers helpfully." # noqa: S101 |
| 621 | + |
| 622 | + |
| 623 | +def test_guardrail_agent_accepts_string_prompt(monkeypatch: pytest.MonkeyPatch) -> None: |
| 624 | + """String prompts populate missing instructions automatically.""" |
| 625 | + pipeline = SimpleNamespace(pre_flight=None, input=None, output=None) |
| 626 | + |
| 627 | + monkeypatch.setattr(runtime_module, "load_pipeline_bundles", lambda config: pipeline, raising=False) |
| 628 | + monkeypatch.setattr(runtime_module, "instantiate_guardrails", lambda *args, **kwargs: [], raising=False) |
| 629 | + |
| 630 | + agent_instance = agents.GuardrailAgent(config={}, name="PromptStr", prompt="Be concise.") |
| 631 | + |
| 632 | + assert agent_instance.prompt == "Be concise." # noqa: S101 |
| 633 | + assert agent_instance.instructions == "Be concise." # noqa: S101 |
| 634 | + |
| 635 | + |
| 636 | +def test_guardrail_agent_requires_instructions_or_prompt(monkeypatch: pytest.MonkeyPatch) -> None: |
| 637 | + """GuardrailAgent requires instructions or prompt for construction.""" |
| 638 | + pipeline = SimpleNamespace(pre_flight=None, input=None, output=None) |
| 639 | + |
| 640 | + monkeypatch.setattr(runtime_module, "load_pipeline_bundles", lambda config: pipeline, raising=False) |
| 641 | + monkeypatch.setattr(runtime_module, "instantiate_guardrails", lambda *args, **kwargs: [], raising=False) |
| 642 | + |
| 643 | + with pytest.raises(ValueError): |
| 644 | + agents.GuardrailAgent(config={}, name="Missing") |
0 commit comments