aip-agents-binary 0.5.24__py3-none-macosx_13_0_arm64.whl → 0.5.25__py3-none-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. aip_agents/agent/base_langgraph_agent.py +6 -0
  2. aip_agents/agent/langgraph_react_agent.py +96 -14
  3. aip_agents/agent/langgraph_react_agent.pyi +6 -1
  4. aip_agents/guardrails/__init__.py +83 -0
  5. aip_agents/guardrails/__init__.pyi +6 -0
  6. aip_agents/guardrails/engines/__init__.py +69 -0
  7. aip_agents/guardrails/engines/__init__.pyi +4 -0
  8. aip_agents/guardrails/engines/base.py +90 -0
  9. aip_agents/guardrails/engines/base.pyi +61 -0
  10. aip_agents/guardrails/engines/nemo.py +101 -0
  11. aip_agents/guardrails/engines/nemo.pyi +46 -0
  12. aip_agents/guardrails/engines/phrase_matcher.py +113 -0
  13. aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
  14. aip_agents/guardrails/exceptions.py +39 -0
  15. aip_agents/guardrails/exceptions.pyi +23 -0
  16. aip_agents/guardrails/manager.py +163 -0
  17. aip_agents/guardrails/manager.pyi +42 -0
  18. aip_agents/guardrails/middleware.py +199 -0
  19. aip_agents/guardrails/middleware.pyi +87 -0
  20. aip_agents/guardrails/schemas.py +63 -0
  21. aip_agents/guardrails/schemas.pyi +43 -0
  22. aip_agents/guardrails/utils.py +45 -0
  23. aip_agents/guardrails/utils.pyi +19 -0
  24. aip_agents/middleware/base.py +8 -0
  25. aip_agents/middleware/base.pyi +4 -0
  26. aip_agents/middleware/manager.py +22 -0
  27. aip_agents/middleware/manager.pyi +4 -0
  28. {aip_agents_binary-0.5.24.dist-info → aip_agents_binary-0.5.25.dist-info}/METADATA +3 -1
  29. {aip_agents_binary-0.5.24.dist-info → aip_agents_binary-0.5.25.dist-info}/RECORD +31 -11
  30. {aip_agents_binary-0.5.24.dist-info → aip_agents_binary-0.5.25.dist-info}/WHEEL +0 -0
  31. {aip_agents_binary-0.5.24.dist-info → aip_agents_binary-0.5.25.dist-info}/top_level.txt +0 -0
@@ -1225,6 +1225,12 @@ class BaseLangGraphAgent(BaseAgent):
1225
1225
  async for chunk in transformer.transform_stream(self.arun_a2a_stream(query, **kwargs)):
1226
1226
  yield chunk
1227
1227
  except Exception as e:
1228
+ # Lazy import to support optional guardrails dependency
1229
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
1230
+
1231
+ if isinstance(e, GuardrailViolationError):
1232
+ # Re-raise guardrail violations without modification
1233
+ raise
1228
1234
  logger.error(f"Agent '{self.name}': Error in arun_sse_stream: {e}", exc_info=True)
1229
1235
  yield SSEChunkTransformer._create_error_chunk(f"Error during streaming: {e}")
1230
1236
 
@@ -6,8 +6,11 @@ Authors:
6
6
  Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
7
7
  Fachriza Adhiatma (fachriza.d.adhiatma@gdplabs.id)
8
8
  Raymond Christopher (raymond.christopher@gdplabs.id)
9
+ Reinhart Linanda (reinhart.linanda@gdplabs.id)
9
10
  """
10
11
 
12
+ from __future__ import annotations
13
+
11
14
  import asyncio
12
15
  import time
13
16
  import uuid
@@ -15,9 +18,12 @@ from collections.abc import Awaitable, Callable, Sequence
15
18
  from dataclasses import asdict, dataclass
16
19
  from functools import reduce
17
20
  from textwrap import dedent
18
- from typing import Annotated, Any
21
+ from typing import TYPE_CHECKING, Annotated, Any
19
22
 
20
23
  from deprecated import deprecated
24
+
25
+ if TYPE_CHECKING:
26
+ from aip_agents.guardrails.manager import GuardrailManager
21
27
  from gllm_core.event import EventEmitter
22
28
  from gllm_core.schema import Chunk
23
29
  from langchain_core.language_models import BaseChatModel
@@ -157,6 +163,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
157
163
  tool_output_manager: ToolOutputManager | None = None,
158
164
  planning: bool = False,
159
165
  middlewares: Sequence[AgentMiddleware] | None = None,
166
+ guardrail: GuardrailManager | None = None,
160
167
  step_limit_config: StepLimitConfig | None = None,
161
168
  **kwargs: Any,
162
169
  ):
@@ -178,8 +185,12 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
178
185
  planning: Enable planning capabilities with TodoListMiddleware. Defaults to False.
179
186
  middlewares: Optional sequence of custom middleware to COMPOSE (not override) with built-in middleware.
180
187
  Execution order: [TodoListMiddleware (if planning=True),
188
+ GuardrailMiddleware (if guardrail provided),
181
189
  ...custom middlewares in order provided]
182
190
  All middleware hooks execute - this extends capabilities, never replaces them.
191
+ guardrail: Optional GuardrailManager for content filtering and safety checks.
192
+ When provided, automatically wraps in GuardrailMiddleware for transparent
193
+ input/output filtering during agent execution.
183
194
  enable_pii: Optional toggle to enable PII handling for tool inputs and outputs.
184
195
  step_limit_config: Optional configuration for step limits and delegation depth.
185
196
  **kwargs: Additional keyword arguments passed to BaseLangGraphAgent.
@@ -212,6 +223,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
212
223
  # Setup middleware
213
224
  self._middleware_manager = self._setup_middleware(
214
225
  planning=planning,
226
+ guardrail=guardrail,
215
227
  custom_middlewares=middlewares,
216
228
  )
217
229
 
@@ -224,15 +236,17 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
224
236
  def _setup_middleware(
225
237
  self,
226
238
  planning: bool,
239
+ guardrail: GuardrailManager | None,
227
240
  custom_middlewares: Sequence[AgentMiddleware] | None,
228
241
  ) -> MiddlewareManager | None:
229
242
  """Setup middleware based on configuration.
230
243
 
231
- Creates auto-configured middleware (planning) and composes
244
+ Creates auto-configured middleware (planning, guardrails) and composes
232
245
  with custom middleware if provided.
233
246
 
234
247
  Args:
235
248
  planning: Whether to enable TodoListMiddleware.
249
+ guardrail: Optional GuardrailManager to wrap in GuardrailMiddleware.
236
250
  custom_middlewares: Optional custom middlewares to append.
237
251
 
238
252
  Returns:
@@ -244,6 +258,12 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
244
258
  if planning:
245
259
  middleware_list.append(TodoListMiddleware())
246
260
 
261
+ # Auto-configure GuardrailMiddleware if guardrail provided
262
+ if guardrail:
263
+ from aip_agents.guardrails.middleware import GuardrailMiddleware
264
+
265
+ middleware_list.append(GuardrailMiddleware(guardrail))
266
+
247
267
  # Append custom middlewares
248
268
  if custom_middlewares:
249
269
  middleware_list.extend(custom_middlewares)
@@ -579,14 +599,29 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
579
599
  current_messages = state["messages"]
580
600
 
581
601
  # Execute LLM call
582
- if self.lm_invoker:
583
- result = await self._handle_lm_invoker_call(current_messages, state, config)
584
- elif isinstance(self.model, BaseChatModel):
585
- result = await self._handle_langchain_model_call(current_messages, state, config)
586
- else:
587
- raise ValueError(
588
- f"Agent '{self.name}': No valid LMInvoker or LangChain model configured for ReAct agent node."
589
- )
602
+ try:
603
+ if self.lm_invoker:
604
+ result = await self._handle_lm_invoker_call(current_messages, state, config)
605
+ elif isinstance(self.model, BaseChatModel):
606
+ result = await self._handle_langchain_model_call(current_messages, state, config)
607
+ else:
608
+ raise ValueError(
609
+ f"Agent '{self.name}': No valid LMInvoker or LangChain model configured for ReAct agent node."
610
+ )
611
+ except Exception as e:
612
+ # Lazy import to support optional guardrails dependency
613
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
614
+
615
+ if isinstance(e, GuardrailViolationError):
616
+ return {
617
+ "messages": [
618
+ AIMessage(
619
+ content=f"⚠️ Guardrail violation: {e.result.reason}",
620
+ response_metadata={"finish_reason": "stop"},
621
+ )
622
+ ]
623
+ }
624
+ raise
590
625
 
591
626
  # Increment step counter after successful execution
592
627
  manager.increment_step()
@@ -1954,6 +1989,47 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
1954
1989
  )
1955
1990
  writer(a2a_event)
1956
1991
 
1992
+ async def _execute_abefore_model_hook(self, state: dict[str, Any]) -> None:
1993
+ """Asynchronously execute abefore_model middleware hook and update state.
1994
+
1995
+ Args:
1996
+ state: Current agent state to potentially update.
1997
+ """
1998
+ if self._middleware_manager:
1999
+ try:
2000
+ before_updates = await self._middleware_manager.abefore_model(state)
2001
+ if before_updates:
2002
+ state.update(before_updates)
2003
+ except Exception as e:
2004
+ # Lazy import to support optional guardrails dependency
2005
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
2006
+
2007
+ if isinstance(e, GuardrailViolationError):
2008
+ # Re-raise guardrail violations to be caught by the agent node
2009
+ raise
2010
+ logger.error(f"Agent '{self.name}': Middleware abefore_model hook failed: {e}")
2011
+
2012
+ async def _execute_aafter_model_hook(self, state_updates: dict[str, Any], state: dict[str, Any]) -> None:
2013
+ """Asynchronously execute aafter_model middleware hook.
2014
+
2015
+ Args:
2016
+ state_updates: Updates to be merged into state.
2017
+ state: Current agent state for context.
2018
+ """
2019
+ if self._middleware_manager:
2020
+ try:
2021
+ after_updates = await self._middleware_manager.aafter_model(state)
2022
+ if after_updates:
2023
+ state_updates.update(after_updates)
2024
+ except Exception as e:
2025
+ # Lazy import to support optional guardrails dependency
2026
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
2027
+
2028
+ if isinstance(e, GuardrailViolationError):
2029
+ # Re-raise guardrail violations
2030
+ raise
2031
+ logger.error(f"Agent '{self.name}': Middleware aafter_model hook failed: {e}")
2032
+
1957
2033
  def _execute_before_model_hook(self, state: dict[str, Any]) -> None:
1958
2034
  """Execute before_model middleware hook and update state.
1959
2035
 
@@ -1966,6 +2042,12 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
1966
2042
  if before_updates:
1967
2043
  state.update(before_updates)
1968
2044
  except Exception as e:
2045
+ # Lazy import to support optional guardrails dependency
2046
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
2047
+
2048
+ if isinstance(e, GuardrailViolationError):
2049
+ # Re-raise guardrail violations to be caught by the agent node
2050
+ raise
1969
2051
  logger.error(f"Agent '{self.name}': Middleware before_model hook failed: {e}")
1970
2052
 
1971
2053
  def _execute_modify_model_request_hook(
@@ -2029,7 +2111,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
2029
2111
  dict[str, Any]: A dictionary containing the new messages and updated token usage.
2030
2112
  """
2031
2113
  # Execute before_model middleware hook
2032
- self._execute_before_model_hook(state)
2114
+ await self._execute_abefore_model_hook(state)
2033
2115
 
2034
2116
  # Build tool output aware instruction
2035
2117
  enhanced_instruction = self._build_tool_output_aware_instruction(self.instruction, state, config)
@@ -2063,7 +2145,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
2063
2145
  state_updates.update(token_usage_updates)
2064
2146
 
2065
2147
  # Execute after_model middleware hook
2066
- self._execute_after_model_hook(state_updates, state)
2148
+ await self._execute_aafter_model_hook(state_updates, state)
2067
2149
 
2068
2150
  return state_updates
2069
2151
 
@@ -2081,7 +2163,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
2081
2163
  dict[str, Any]: A dictionary containing the new messages and updated token usage.
2082
2164
  """
2083
2165
  # Execute before_model middleware hook
2084
- self._execute_before_model_hook(state)
2166
+ await self._execute_abefore_model_hook(state)
2085
2167
 
2086
2168
  # Build tool output aware instruction
2087
2169
  enhanced_instruction = self._build_tool_output_aware_instruction(self.instruction, state, config)
@@ -2113,7 +2195,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
2113
2195
  state_updates.update(token_usage_updates)
2114
2196
 
2115
2197
  # Execute after_model middleware hook
2116
- self._execute_after_model_hook(state_updates, state)
2198
+ await self._execute_aafter_model_hook(state_updates, state)
2117
2199
 
2118
2200
  return state_updates
2119
2201
 
@@ -2,6 +2,7 @@ from _typeshed import Incomplete
2
2
  from aip_agents.agent.base_langgraph_agent import BaseLangGraphAgent as BaseLangGraphAgent
3
3
  from aip_agents.agent.hitl.langgraph_hitl_mixin import LangGraphHitLMixin as LangGraphHitLMixin
4
4
  from aip_agents.agent.hitl.manager import TOOL_EXECUTION_BLOCKING_DECISIONS as TOOL_EXECUTION_BLOCKING_DECISIONS
5
+ from aip_agents.guardrails.manager import GuardrailManager as GuardrailManager
5
6
  from aip_agents.middleware.base import AgentMiddleware as AgentMiddleware, ModelRequest as ModelRequest
6
7
  from aip_agents.middleware.manager import MiddlewareManager as MiddlewareManager
7
8
  from aip_agents.middleware.todolist import TodoList as TodoList, TodoListMiddleware as TodoListMiddleware
@@ -85,7 +86,7 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
85
86
  """
86
87
  tool_output_manager: Incomplete
87
88
  step_limit_config: Incomplete
88
- def __init__(self, name: str, instruction: str = ..., model: BaseChatModel | str | Any | None = None, tools: Sequence[BaseTool] | None = None, agents: Sequence[Any] | None = None, description: str | None = None, thread_id_key: str = 'thread_id', event_emitter: EventEmitter | None = None, tool_output_manager: ToolOutputManager | None = None, planning: bool = False, middlewares: Sequence[AgentMiddleware] | None = None, step_limit_config: StepLimitConfig | None = None, **kwargs: Any) -> None:
89
+ def __init__(self, name: str, instruction: str = ..., model: BaseChatModel | str | Any | None = None, tools: Sequence[BaseTool] | None = None, agents: Sequence[Any] | None = None, description: str | None = None, thread_id_key: str = 'thread_id', event_emitter: EventEmitter | None = None, tool_output_manager: ToolOutputManager | None = None, planning: bool = False, middlewares: Sequence[AgentMiddleware] | None = None, guardrail: GuardrailManager | None = None, step_limit_config: StepLimitConfig | None = None, **kwargs: Any) -> None:
89
90
  """Initialize the LangGraph ReAct Agent.
90
91
 
91
92
  Args:
@@ -104,8 +105,12 @@ class LangGraphReactAgent(LangGraphHitLMixin, BaseLangGraphAgent):
104
105
  planning: Enable planning capabilities with TodoListMiddleware. Defaults to False.
105
106
  middlewares: Optional sequence of custom middleware to COMPOSE (not override) with built-in middleware.
106
107
  Execution order: [TodoListMiddleware (if planning=True),
108
+ GuardrailMiddleware (if guardrail provided),
107
109
  ...custom middlewares in order provided]
108
110
  All middleware hooks execute - this extends capabilities, never replaces them.
111
+ guardrail: Optional GuardrailManager for content filtering and safety checks.
112
+ When provided, automatically wraps in GuardrailMiddleware for transparent
113
+ input/output filtering during agent execution.
109
114
  enable_pii: Optional toggle to enable PII handling for tool inputs and outputs.
110
115
  step_limit_config: Optional configuration for step limits and delegation depth.
111
116
  **kwargs: Additional keyword arguments passed to BaseLangGraphAgent.
@@ -0,0 +1,83 @@
1
+ # flake8: noqa: F401
2
+ """Guardrails package for content filtering and safety checks.
3
+
4
+ This package provides modular guardrail engines and managers for filtering
5
+ harmful content in AI agent interactions. All components support lazy loading
6
+ to work with optional dependencies.
7
+
8
+ Example:
9
+ Basic usage with a phrase matcher engine:
10
+
11
+ .. code-block:: python
12
+
13
+ from aip_agents.guardrails import GuardrailManager, GuardrailMiddleware
14
+ from aip_agents.guardrails.engines import PhraseMatcherEngine
15
+ from aip_agents.guardrails.schemas import GuardrailMode
16
+
17
+ # Create a guardrail engine
18
+ engine = PhraseMatcherEngine(
19
+ banned_phrases=["spam", "inappropriate"]
20
+ )
21
+
22
+ # Create a manager
23
+ manager = GuardrailManager(engines=[engine])
24
+
25
+ # Create middleware for agent integration
26
+ middleware = GuardrailMiddleware(guardrail_manager=manager)
27
+
28
+ # Use with agent (components are lazy-loaded)
29
+ from aip_agents.agent import LangGraphReactAgent
30
+ agent = LangGraphReactAgent(
31
+ name="my_agent",
32
+ guardrail=manager,
33
+ # ... other agent config
34
+ )
35
+
36
+ Authors:
37
+ Reinhart Linanda (reinhart.linanda@gdplabs.id)
38
+ """
39
+
40
+ from typing import TYPE_CHECKING, Any
41
+
42
+ if TYPE_CHECKING:
43
+ from aip_agents.guardrails.exceptions import GuardrailViolationError
44
+ from aip_agents.guardrails.manager import GuardrailManager
45
+ from aip_agents.guardrails.middleware import GuardrailMiddleware
46
+ from aip_agents.guardrails.schemas import (
47
+ BaseGuardrailEngineConfig,
48
+ GuardrailInput,
49
+ GuardrailMode,
50
+ GuardrailResult,
51
+ )
52
+
53
+
54
+ _IMPORT_MAP = {
55
+ "GuardrailViolationError": "aip_agents.guardrails.exceptions",
56
+ "GuardrailManager": "aip_agents.guardrails.manager",
57
+ "GuardrailMiddleware": "aip_agents.guardrails.middleware",
58
+ "BaseGuardrailEngineConfig": "aip_agents.guardrails.schemas",
59
+ "GuardrailMode": "aip_agents.guardrails.schemas",
60
+ "GuardrailInput": "aip_agents.guardrails.schemas",
61
+ "GuardrailResult": "aip_agents.guardrails.schemas",
62
+ }
63
+
64
+ _cache: dict[str, Any] = {}
65
+
66
+
67
+ def __getattr__(name: str) -> Any:
68
+ """Lazy import components on first access."""
69
+ if name in _cache:
70
+ return _cache[name]
71
+
72
+ if name in _IMPORT_MAP:
73
+ try:
74
+ module = __import__(_IMPORT_MAP[name], fromlist=[name])
75
+ _cache[name] = getattr(module, name)
76
+ return _cache[name]
77
+ except ImportError as e:
78
+ raise ImportError(f"Failed to import {name}. Optional dependencies may be missing: {e}") from e
79
+
80
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
81
+
82
+
83
+ __all__ = list(_IMPORT_MAP.keys())
@@ -0,0 +1,6 @@
1
+ from aip_agents.guardrails.exceptions import GuardrailViolationError as GuardrailViolationError
2
+ from aip_agents.guardrails.manager import GuardrailManager as GuardrailManager
3
+ from aip_agents.guardrails.middleware import GuardrailMiddleware as GuardrailMiddleware
4
+ from aip_agents.guardrails.schemas import BaseGuardrailEngineConfig as BaseGuardrailEngineConfig, GuardrailInput as GuardrailInput, GuardrailMode as GuardrailMode, GuardrailResult as GuardrailResult
5
+
6
+ __all__ = ['GuardrailViolationError', 'GuardrailManager', 'GuardrailMiddleware', 'BaseGuardrailEngineConfig', 'GuardrailMode', 'GuardrailInput', 'GuardrailResult']
@@ -0,0 +1,69 @@
1
+ # flake8: noqa: F401
2
+ """Guardrail engines package with lazy loading support.
3
+
4
+ This package provides guardrail engines that wrap GL SDK implementations.
5
+ Engines are loaded lazily to support optional dependencies.
6
+
7
+ Example:
8
+ Import and use guardrail engines:
9
+
10
+ .. code-block:: python
11
+
12
+ # Lazy import - works even if gllm-guardrail is not installed
13
+ from aip_agents.guardrails.engines import PhraseMatcherEngine, NemoGuardrailEngine
14
+
15
+ # Create a phrase matcher engine
16
+ phrase_engine = PhraseMatcherEngine(
17
+ banned_phrases=["spam", "inappropriate"]
18
+ )
19
+
20
+ # Create a NeMo guardrail engine (requires gllm-guardrail)
21
+ nemo_engine = NemoGuardrailEngine(
22
+ # NeMo-specific configuration
23
+ )
24
+
25
+ # Use with GuardrailManager
26
+ from aip_agents.guardrails import GuardrailManager
27
+ manager = GuardrailManager(engines=[phrase_engine, nemo_engine])
28
+
29
+ Note:
30
+ All engines support lazy loading. If `gllm-guardrail` is not installed,
31
+ importing these engines will raise an ImportError only when actually
32
+ instantiated, not at import time.
33
+
34
+ Authors:
35
+ Reinhart Linanda (reinhart.linanda@gdplabs.id)
36
+ """
37
+
38
+ from typing import TYPE_CHECKING, Any
39
+
40
+ if TYPE_CHECKING:
41
+ from aip_agents.guardrails.engines.nemo import NemoGuardrailEngine
42
+ from aip_agents.guardrails.engines.phrase_matcher import PhraseMatcherEngine
43
+
44
+
45
+ _IMPORT_MAP = {
46
+ "NemoGuardrailEngine": "aip_agents.guardrails.engines.nemo",
47
+ "PhraseMatcherEngine": "aip_agents.guardrails.engines.phrase_matcher",
48
+ }
49
+
50
+ _cache: dict[str, Any] = {}
51
+
52
+
53
+ def __getattr__(name: str) -> Any:
54
+ """Lazy import engines on first access."""
55
+ if name in _cache:
56
+ return _cache[name]
57
+
58
+ if name in _IMPORT_MAP:
59
+ try:
60
+ module = __import__(_IMPORT_MAP[name], fromlist=[name])
61
+ _cache[name] = getattr(module, name)
62
+ return _cache[name]
63
+ except ImportError as e:
64
+ raise ImportError(f"Failed to import {name}. Optional dependencies may be missing: {e}") from e
65
+
66
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
67
+
68
+
69
+ __all__ = list(_IMPORT_MAP.keys())
@@ -0,0 +1,4 @@
1
+ from aip_agents.guardrails.engines.nemo import NemoGuardrailEngine as NemoGuardrailEngine
2
+ from aip_agents.guardrails.engines.phrase_matcher import PhraseMatcherEngine as PhraseMatcherEngine
3
+
4
+ __all__ = ['NemoGuardrailEngine', 'PhraseMatcherEngine']
@@ -0,0 +1,90 @@
1
+ """Base interfaces and protocols for guardrail engines.
2
+
3
+ This module defines the base protocol that all guardrail engines must implement,
4
+ providing a consistent interface for content safety checking.
5
+
6
+ Authors:
7
+ Reinhart Linanda (reinhart.linanda@gdplabs.id)
8
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
9
+ """
10
+
11
+ from abc import ABC, abstractmethod
12
+ from typing import Protocol
13
+
14
+ from aip_agents.guardrails.schemas import (
15
+ BaseGuardrailEngineConfig,
16
+ GuardrailResult,
17
+ )
18
+
19
+
20
+ class GuardrailEngine(Protocol):
21
+ """Protocol defining the interface for guardrail engines.
22
+
23
+ All guardrail engines must implement this protocol to be compatible
24
+ with GuardrailManager. Engines check content for safety violations.
25
+
26
+ Attributes:
27
+ config: Configuration for this engine's behavior
28
+ """
29
+
30
+ config: BaseGuardrailEngineConfig
31
+
32
+ @abstractmethod
33
+ async def check_input(self, content: str) -> GuardrailResult:
34
+ """Check user input content for safety violations.
35
+
36
+ Args:
37
+ content: The user input content to check
38
+
39
+ Returns:
40
+ GuardrailResult indicating if content is safe
41
+ """
42
+ ...
43
+
44
+ @abstractmethod
45
+ async def check_output(self, content: str) -> GuardrailResult:
46
+ """Check AI output content for safety violations.
47
+
48
+ Args:
49
+ content: The AI output content to check
50
+
51
+ Returns:
52
+ GuardrailResult indicating if content is safe
53
+ """
54
+ ...
55
+
56
+ @abstractmethod
57
+ def model_dump(self) -> dict:
58
+ """Serialize engine configuration into a JSON-compatible dictionary."""
59
+ ...
60
+
61
+
62
+ class BaseGuardrailEngine(ABC):
63
+ """Abstract base class for guardrail engines.
64
+
65
+ Provides common functionality and ensures proper configuration handling.
66
+ Concrete engines should inherit from this class.
67
+ """
68
+
69
+ def __init__(self, config: BaseGuardrailEngineConfig | None = None) -> None:
70
+ """Initialize the engine with configuration.
71
+
72
+ Args:
73
+ config: Engine configuration. Uses defaults if None provided.
74
+ """
75
+ self.config = config or BaseGuardrailEngineConfig()
76
+
77
+ @abstractmethod
78
+ async def check_input(self, content: str) -> GuardrailResult:
79
+ """Check user input content for safety violations."""
80
+ ...
81
+
82
+ @abstractmethod
83
+ async def check_output(self, content: str) -> GuardrailResult:
84
+ """Check AI output content for safety violations."""
85
+ ...
86
+
87
+ @abstractmethod
88
+ def model_dump(self) -> dict:
89
+ """Serialize engine configuration into a JSON-compatible dictionary."""
90
+ ...
@@ -0,0 +1,61 @@
1
+ from _typeshed import Incomplete
2
+ from abc import ABC, abstractmethod
3
+ from aip_agents.guardrails.schemas import BaseGuardrailEngineConfig as BaseGuardrailEngineConfig, GuardrailResult as GuardrailResult
4
+ from typing import Protocol
5
+
6
+ class GuardrailEngine(Protocol):
7
+ """Protocol defining the interface for guardrail engines.
8
+
9
+ All guardrail engines must implement this protocol to be compatible
10
+ with GuardrailManager. Engines check content for safety violations.
11
+
12
+ Attributes:
13
+ config: Configuration for this engine's behavior
14
+ """
15
+ config: BaseGuardrailEngineConfig
16
+ @abstractmethod
17
+ async def check_input(self, content: str) -> GuardrailResult:
18
+ """Check user input content for safety violations.
19
+
20
+ Args:
21
+ content: The user input content to check
22
+
23
+ Returns:
24
+ GuardrailResult indicating if content is safe
25
+ """
26
+ @abstractmethod
27
+ async def check_output(self, content: str) -> GuardrailResult:
28
+ """Check AI output content for safety violations.
29
+
30
+ Args:
31
+ content: The AI output content to check
32
+
33
+ Returns:
34
+ GuardrailResult indicating if content is safe
35
+ """
36
+ @abstractmethod
37
+ def model_dump(self) -> dict:
38
+ """Serialize engine configuration into a JSON-compatible dictionary."""
39
+
40
+ class BaseGuardrailEngine(ABC):
41
+ """Abstract base class for guardrail engines.
42
+
43
+ Provides common functionality and ensures proper configuration handling.
44
+ Concrete engines should inherit from this class.
45
+ """
46
+ config: Incomplete
47
+ def __init__(self, config: BaseGuardrailEngineConfig | None = None) -> None:
48
+ """Initialize the engine with configuration.
49
+
50
+ Args:
51
+ config: Engine configuration. Uses defaults if None provided.
52
+ """
53
+ @abstractmethod
54
+ async def check_input(self, content: str) -> GuardrailResult:
55
+ """Check user input content for safety violations."""
56
+ @abstractmethod
57
+ async def check_output(self, content: str) -> GuardrailResult:
58
+ """Check AI output content for safety violations."""
59
+ @abstractmethod
60
+ def model_dump(self) -> dict:
61
+ """Serialize engine configuration into a JSON-compatible dictionary."""