idun-agent-engine 0.3.4__tar.gz → 0.3.6__tar.gz

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 (62) hide show
  1. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/PKG-INFO +1 -1
  2. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/pyproject.toml +1 -1
  3. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/_version.py +1 -1
  4. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/core/config_builder.py +9 -3
  5. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/guardrails/base.py +1 -1
  6. idun_agent_engine-0.3.6/src/idun_agent_engine/guardrails/guardrails_hub/guardrails_hub.py +106 -0
  7. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/lifespan.py +1 -1
  8. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/routers/agent.py +6 -0
  9. idun_agent_engine-0.3.6/src/idun_platform_cli/groups/agent/__init__.py +0 -0
  10. idun_agent_engine-0.3.4/src/idun_agent_engine/guardrails/guardrails_hub/guardrails_hub.py +0 -101
  11. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/.gitignore +0 -0
  12. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/README.md +0 -0
  13. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/__init__.py +0 -0
  14. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/__init__.py +0 -0
  15. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/adk/__init__.py +0 -0
  16. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/adk/adk.py +0 -0
  17. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/base.py +0 -0
  18. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/haystack/__init__.py +0 -0
  19. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/haystack/haystack.py +0 -0
  20. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/haystack/haystack_model.py +0 -0
  21. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/haystack/utils.py +0 -0
  22. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/langgraph/__init__.py +0 -0
  23. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/agent/langgraph/langgraph.py +0 -0
  24. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/core/__init__.py +0 -0
  25. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/core/app_factory.py +0 -0
  26. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/core/engine_config.py +0 -0
  27. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/core/server_runner.py +0 -0
  28. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/guardrails/__init__.py +0 -0
  29. {idun_agent_engine-0.3.4/src/idun_agent_engine/observability/gcp_logging → idun_agent_engine-0.3.6/src/idun_agent_engine/guardrails/guardrails_hub}/__init__.py +0 -0
  30. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/guardrails/guardrails_hub/utils.py +0 -0
  31. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/mcp/__init__.py +0 -0
  32. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/mcp/helpers.py +0 -0
  33. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/mcp/registry.py +0 -0
  34. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/__init__.py +0 -0
  35. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/base.py +0 -0
  36. {idun_agent_engine-0.3.4/src/idun_agent_engine/observability/gcp_trace → idun_agent_engine-0.3.6/src/idun_agent_engine/observability/gcp_logging}/__init__.py +0 -0
  37. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/gcp_logging/gcp_logging_handler.py +0 -0
  38. {idun_agent_engine-0.3.4/src/idun_platform_cli → idun_agent_engine-0.3.6/src/idun_agent_engine/observability/gcp_trace}/__init__.py +0 -0
  39. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/gcp_trace/gcp_trace_handler.py +0 -0
  40. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/langfuse/__init__.py +0 -0
  41. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/langfuse/langfuse_handler.py +0 -0
  42. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/phoenix/__init__.py +0 -0
  43. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/phoenix/phoenix_handler.py +0 -0
  44. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/phoenix_local/__init__.py +0 -0
  45. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py +0 -0
  46. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/py.typed +0 -0
  47. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/__init__.py +0 -0
  48. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/dependencies.py +0 -0
  49. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/routers/__init__.py +0 -0
  50. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/routers/agui.py +0 -0
  51. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/routers/base.py +0 -0
  52. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/server/server_config.py +0 -0
  53. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/templates/__init__.py +0 -0
  54. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/templates/correction.py +0 -0
  55. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/templates/deep_research.py +0 -0
  56. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_agent_engine/templates/translation.py +0 -0
  57. {idun_agent_engine-0.3.4/src/idun_platform_cli/groups → idun_agent_engine-0.3.6/src/idun_platform_cli}/__init__.py +0 -0
  58. {idun_agent_engine-0.3.4/src/idun_platform_cli/groups/agent → idun_agent_engine-0.3.6/src/idun_platform_cli/groups}/__init__.py +0 -0
  59. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_platform_cli/groups/agent/main.py +0 -0
  60. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_platform_cli/groups/agent/package.py +0 -0
  61. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_platform_cli/groups/agent/serve.py +0 -0
  62. {idun_agent_engine-0.3.4 → idun_agent_engine-0.3.6}/src/idun_platform_cli/main.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idun-agent-engine
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Python SDK and runtime to serve AI agents with FastAPI, LangGraph, and observability.
5
5
  Project-URL: Homepage, https://github.com/geoffreyharrazi/idun-agent-platform
6
6
  Project-URL: Repository, https://github.com/geoffreyharrazi/idun-agent-platform
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "idun-agent-engine"
3
- version = "0.3.4"
3
+ version = "0.3.6"
4
4
  description = "Python SDK and runtime to serve AI agents with FastAPI, LangGraph, and observability."
5
5
  authors = [{ name = "Geoffrey HARRAZI", email = "geoffreyharrazi@gmail.com" }]
6
6
  requires-python = ">=3.12,<3.14"
@@ -1,3 +1,3 @@
1
1
  """Version information for Idun Agent Engine."""
2
2
 
3
- __version__ = "0.3.4"
3
+ __version__ = "0.3.6"
@@ -4,6 +4,7 @@ This module provides a fluent API for building configuration objects using Pydan
4
4
  This approach ensures type safety, validation, and consistency with the rest of the codebase.
5
5
  """
6
6
 
7
+ import os
7
8
  from pathlib import Path
8
9
  from typing import Any
9
10
 
@@ -24,6 +25,7 @@ from yaml import YAMLError
24
25
 
25
26
  from ..agent.base import BaseAgent
26
27
  from .engine_config import AgentConfig, EngineConfig, ServerConfig
28
+ from idun_agent_schema.manager.guardrail_configs import convert_guardrail
27
29
 
28
30
 
29
31
  class ConfigBuilder:
@@ -119,10 +121,14 @@ class ConfigBuilder:
119
121
  f"Failed to parse yaml file for Engine config: {e}"
120
122
  ) from e
121
123
  try:
122
- guardrails = yaml_config.get("engine_config", {}).get("guardrails", "")
123
- if not guardrails:
124
- # self._guardrails = Guardrails(enabled=False)
124
+ guardrails_data = yaml_config.get("engine_config", {}).get("guardrails")
125
+
126
+ if not guardrails_data:
125
127
  self._guardrails = None
128
+ else:
129
+ converted_data = convert_guardrail(guardrails_data)
130
+ self._guardrails = Guardrails.model_validate(converted_data)
131
+
126
132
  except Exception as e:
127
133
  raise YAMLError(f"Failed to parse yaml file for Guardrails: {e}") from e
128
134
 
@@ -1,7 +1,7 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from typing import Any
3
3
 
4
- from idun_agent_schema.engine.guardrails import Guardrail
4
+ from idun_agent_schema.engine.guardrails_v2 import GuardrailConfig as Guardrail
5
5
 
6
6
 
7
7
  class BaseGuardrail(ABC):
@@ -0,0 +1,106 @@
1
+ """Guardrails."""
2
+
3
+ from guardrails import Guard
4
+ from idun_agent_schema.engine.guardrails import Guardrail as GuardrailSchema
5
+ from idun_agent_schema.engine.guardrails_v2 import GuardrailConfigId
6
+
7
+ from ..base import BaseGuardrail
8
+
9
+
10
+ def get_guard_instance(name: GuardrailConfigId) -> Guard:
11
+ """Returns a map of guard type -> guard instance."""
12
+ if name.value == "ban_list":
13
+ from guardrails.hub import BanList
14
+
15
+ return BanList
16
+
17
+ elif name.value == "detect_pii":
18
+ from guardrails.hub import DetectPII
19
+
20
+ return DetectPII
21
+
22
+ elif name.value == "nsfw":
23
+ from guardrails.hub import NSFWText
24
+
25
+ return NSFWText
26
+
27
+ elif name.value == "competitor_check":
28
+ from guardrails.hub import CompetitorCheck
29
+
30
+ return CompetitorCheck
31
+
32
+ else:
33
+ raise ValueError(f"Guard {name} not found.")
34
+
35
+
36
+ class GuardrailsHubGuard(BaseGuardrail):
37
+ """Class for managing guardrails from `guardrailsai`'s hub."""
38
+
39
+ def __init__(self, config: GuardrailSchema, position: str) -> None:
40
+ super().__init__(config)
41
+
42
+ self.guard_id = self._guardrail_config.config_id
43
+ self._guard_url = self._guardrail_config.guard_url
44
+ self.reject_message: str = self._guardrail_config.reject_message
45
+ self._guard: Guard | None = self.setup_guard()
46
+ self.position: str = position
47
+
48
+ def _install_model(self) -> None:
49
+ import subprocess
50
+
51
+ from guardrails import install
52
+
53
+ try:
54
+ api_key = self._guardrail_config.api_key
55
+
56
+ print("Configuring guardrails with token...")
57
+ result = subprocess.run(
58
+ [
59
+ "guardrails",
60
+ "configure",
61
+ "--token",
62
+ api_key,
63
+ "--disable-remote-inferencing",
64
+ "--disable-metrics",
65
+ ],
66
+ check=True,
67
+ capture_output=True,
68
+ text=True,
69
+ )
70
+ print(f"Configure output: {result.stdout}")
71
+ if result.stderr:
72
+ print(f"Configure stderr: {result.stderr}")
73
+ print(f"Installing model: {self._guard_url}..")
74
+ install(self._guard_url, quiet=False, install_local_models=True)
75
+ print(f"Successfully installed: {self._guard_url}")
76
+ except subprocess.CalledProcessError as e:
77
+ raise OSError(
78
+ f"Cannot configure guardrails: stdout={e.stdout}, stderr={e.stderr}"
79
+ ) from e
80
+ except Exception as e:
81
+ raise e
82
+
83
+ def setup_guard(self) -> Guard | None:
84
+ """Installs and configures the guard based on its yaml config."""
85
+ self._install_model()
86
+ guard_name = self.guard_id
87
+ guard = get_guard_instance(guard_name)
88
+ if guard is None:
89
+ raise ValueError(
90
+ f"Guard: {self.guard_id} is not yet supported, or does not exist."
91
+ )
92
+
93
+ guard_instance_params = self._guardrail_config.guard_params.model_dump()
94
+ guard_instance = guard(**guard_instance_params)
95
+ for param, value in guard_instance_params.items():
96
+ setattr(guard_instance, param, value)
97
+ return guard_instance
98
+
99
+ def validate(self, input: str) -> bool:
100
+ """TODO."""
101
+ main_guard = Guard().use(self._guard)
102
+ try:
103
+ main_guard.validate(input)
104
+ return True
105
+ except Exception:
106
+ return False
@@ -22,7 +22,7 @@ def _parse_guardrails(guardrails_obj: Guardrails) -> Sequence[BaseGuardrail]:
22
22
 
23
23
  from ..guardrails.guardrails_hub.guardrails_hub import GuardrailsHubGuard as GHGuard
24
24
 
25
- if not guardrails_obj.enabled:
25
+ if not guardrails_obj:
26
26
  return []
27
27
 
28
28
  return [GHGuard(guard, position="input") for guard in guardrails_obj.input] + [
@@ -95,6 +95,7 @@ async def stream(
95
95
  ):
96
96
  """Process a message with the agent, streaming ag-ui events."""
97
97
  try:
98
+
98
99
  async def event_stream():
99
100
  message = {"query": request.query, "session_id": request.session_id}
100
101
  async for event in agent.stream(message):
@@ -114,6 +115,11 @@ async def copilotkit_stream(
114
115
  ],
115
116
  ):
116
117
  """Process a message with the agent, streaming ag-ui events."""
118
+ guardrails = getattr(request.app.state, "guardrails", [])
119
+ if guardrails:
120
+ _run_guardrails(
121
+ guardrails, message=input_data.messages[-1].content, position="input"
122
+ )
117
123
  if isinstance(copilotkit_agent, LangGraphAGUIAgent):
118
124
  try:
119
125
  # Get the accept header from the request
@@ -1,101 +0,0 @@
1
- """Guardrails."""
2
-
3
- from guardrails import Guard
4
- from idun_agent_schema.engine.guardrails import Guardrail as GuardrailSchema
5
- from idun_agent_schema.engine.guardrails_type import (
6
- GuardrailType,
7
- )
8
-
9
- from ..base import BaseGuardrail
10
-
11
-
12
- def get_guard_instance(name: str) -> Guard:
13
- """Returns a map of guard type -> guard instance."""
14
- if name == "BAN_LIST":
15
- from guardrails.hub import BanList
16
-
17
- return BanList
18
-
19
- elif name == "NSFW":
20
- from guardrails.hub import NSFWText
21
-
22
- return NSFWText
23
-
24
- elif name == "COMPETITOR_CHECK":
25
- from guardrails.hub import CompetitorCheck
26
-
27
- return CompetitorCheck
28
-
29
- else:
30
- raise ValueError(f"Guard {name} not found.")
31
-
32
-
33
- class GuardrailsHubGuard(BaseGuardrail):
34
- """Class for managing guardrails from `guardrailsai`'s hub."""
35
-
36
- def __init__(self, config: GuardrailSchema, position: str) -> None:
37
- super().__init__(config)
38
-
39
- self._guard_type = self._guardrail_config.type
40
- self._guard_config = self._guardrail_config.config
41
-
42
- if self._guard_type == GuardrailType.GUARDRAILS_HUB:
43
- self._guard_url = self._guardrail_config.config["guard_url"]
44
-
45
- self.reject_message: str = self._guard_config["reject_message"]
46
- self._install_model()
47
- self._guard: Guard | None = self.setup_guard()
48
- self.position: str = position
49
-
50
- def _install_model(self) -> None:
51
- import subprocess
52
-
53
- from guardrails import install
54
-
55
- try:
56
- api_key = self._guardrail_config.config["api_key"]
57
- subprocess.run(
58
- [
59
- "guardrails",
60
- "configure",
61
- "--token",
62
- api_key,
63
- "--disable-remote-inferencing", # TODO: maybe provide this as feat
64
- "--disable-metrics",
65
- ],
66
- check=True,
67
- )
68
- print(f"Installing model: {self._guard_url}..")
69
- install(self._guard_url, quiet=True, install_local_models=True)
70
- except Exception as e:
71
- raise OSError(f"Cannot install model {self._guard_url}: {e}") from e
72
-
73
- def setup_guard(self) -> Guard | None:
74
- """Installs and configures the guard based on its yaml config."""
75
- if self._guard_type == GuardrailType.GUARDRAILS_HUB:
76
- self._install_model()
77
- guard_name = self._guardrail_config.config.get("guard")
78
- guard = get_guard_instance(guard_name)
79
- if guard is None:
80
- raise ValueError(
81
- f"Guard: {self.guard_type} is not yet supported, or does not exist."
82
- )
83
-
84
- guard_instance_params = self._guardrail_config.config.get(
85
- "guard_config", {}
86
- )
87
- guard_instance = guard(**guard_instance_params)
88
- for param, value in self._guardrail_config.config["guard_config"].items():
89
- setattr(guard, param, value)
90
- return guard_instance
91
- elif self._guard_type == GuardrailType.CUSTOM_LLM:
92
- raise NotImplementedError("Support for CUSTOM_LLM not yet provided.")
93
-
94
- def validate(self, input: str) -> bool:
95
- """TODO."""
96
- main_guard = Guard().use(self._guard)
97
- try:
98
- main_guard.validate(input)
99
- return True
100
- except Exception:
101
- return False