idun-agent-engine 0.4.1__tar.gz → 0.4.2__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 (89) hide show
  1. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/.gitignore +17 -25
  2. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/PKG-INFO +1 -1
  3. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/pyproject.toml +44 -9
  4. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/_version.py +1 -1
  5. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/haystack/__init__.py +0 -2
  6. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/haystack/haystack.py +9 -5
  7. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/langgraph/langgraph.py +10 -13
  8. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/core/config_builder.py +26 -13
  9. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/guardrails/guardrails_hub/guardrails_hub.py +52 -9
  10. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/mcp/helpers.py +11 -15
  11. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/mcp/registry.py +5 -5
  12. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/base.py +11 -2
  13. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/gcp_trace/gcp_trace_handler.py +3 -1
  14. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/langfuse/langfuse_handler.py +1 -3
  15. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/dependencies.py +7 -2
  16. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/lifespan.py +2 -7
  17. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/routers/agent.py +2 -1
  18. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/routers/base.py +7 -5
  19. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/telemetry/__init__.py +0 -1
  20. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/telemetry/config.py +0 -1
  21. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/telemetry/telemetry.py +3 -4
  22. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/templates/correction.py +4 -7
  23. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/templates/deep_research.py +1 -0
  24. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/templates/translation.py +4 -4
  25. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/agent/package.py +1 -1
  26. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/telemetry.py +2 -1
  27. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/schemas/create_agent.py +8 -4
  28. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/screens/create_agent.py +38 -12
  29. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/utils/config.py +1 -1
  30. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/validators/guardrails.py +8 -6
  31. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/validators/mcps.py +9 -6
  32. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/chat_widget.py +3 -1
  33. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/guardrails_widget.py +4 -4
  34. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/mcps_widget.py +112 -24
  35. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/memory_widget.py +0 -1
  36. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/observability_widget.py +2 -2
  37. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/serve_widget.py +2 -3
  38. idun_agent_engine-0.4.1/src/idun_agent_engine/agent/haystack/haystack_model.py +0 -13
  39. idun_agent_engine-0.4.1/src/idun_agent_engine/guardrails/guardrails_hub/utils.py +0 -1
  40. idun_agent_engine-0.4.1/src/idun_agent_engine/server/routers/agui.py +0 -47
  41. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/README.md +0 -0
  42. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/__init__.py +0 -0
  43. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/__init__.py +0 -0
  44. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/adk/__init__.py +0 -0
  45. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/adk/adk.py +2 -2
  46. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/base.py +0 -0
  47. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/haystack/utils.py +0 -0
  48. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/agent/langgraph/__init__.py +0 -0
  49. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/core/__init__.py +0 -0
  50. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/core/app_factory.py +0 -0
  51. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/core/engine_config.py +0 -0
  52. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/core/server_runner.py +0 -0
  53. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/guardrails/__init__.py +0 -0
  54. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/guardrails/base.py +0 -0
  55. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/guardrails/guardrails_hub/__init__.py +0 -0
  56. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/mcp/__init__.py +2 -2
  57. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/__init__.py +0 -0
  58. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/gcp_logging/__init__.py +0 -0
  59. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/gcp_logging/gcp_logging_handler.py +0 -0
  60. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/gcp_trace/__init__.py +0 -0
  61. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/langfuse/__init__.py +0 -0
  62. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/phoenix/__init__.py +0 -0
  63. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/phoenix/phoenix_handler.py +0 -0
  64. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/phoenix_local/__init__.py +0 -0
  65. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py +0 -0
  66. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/py.typed +0 -0
  67. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/__init__.py +0 -0
  68. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/routers/__init__.py +0 -0
  69. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/server/server_config.py +0 -0
  70. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_agent_engine/templates/__init__.py +0 -0
  71. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/__init__.py +0 -0
  72. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/__init__.py +0 -0
  73. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/agent/__init__.py +0 -0
  74. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/agent/main.py +0 -0
  75. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/agent/serve.py +0 -0
  76. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/groups/init.py +0 -0
  77. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/main.py +0 -0
  78. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/__init__.py +0 -0
  79. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/css/__init__.py +0 -0
  80. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/css/create_agent.py +0 -0
  81. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/css/main.py +0 -0
  82. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/main.py +0 -0
  83. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/schemas/__init__.py +0 -0
  84. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/screens/__init__.py +0 -0
  85. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/utils/__init__.py +0 -0
  86. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/validators/__init__.py +0 -0
  87. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/validators/observability.py +0 -0
  88. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/__init__.py +0 -0
  89. {idun_agent_engine-0.4.1 → idun_agent_engine-0.4.2}/src/idun_platform_cli/tui/widgets/identity_widget.py +0 -0
@@ -3,6 +3,8 @@ __pycache__/
3
3
  *.py[cod]
4
4
  *$py.class
5
5
 
6
+
7
+
6
8
  .python-version
7
9
  # C extensions
8
10
  *.so
@@ -128,15 +130,24 @@ celerybeat.pid
128
130
  # SageMath parsed files
129
131
  *.sage.py
130
132
 
131
- # Environments
133
+ # Environments / local config
132
134
  .env
133
- .venv
135
+ .env.*
136
+ !.env.example
137
+ .venv/
134
138
  env/
135
139
  venv/
136
140
  ENV/
137
141
  env.bak/
138
142
  venv.bak/
139
143
 
144
+ # Node / frontend
145
+ node_modules/
146
+ npm-debug.log*
147
+ yarn-debug.log*
148
+ yarn-error.log*
149
+ pnpm-debug.log*
150
+
140
151
  # Spyder project settings
141
152
  .spyderproject
142
153
  .spyproject
@@ -177,34 +188,15 @@ cython_debug/
177
188
  # Database files
178
189
  *.db
179
190
  *.db-shm
180
- *.db-wai
191
+ *.db-wal
181
192
  *.db-journal*
182
193
  *.sqlite
183
194
  *.sqlite3
184
195
  agents.db
185
196
  checkpoint_async.db
186
197
 
187
- # Python virtual environment
188
- .venv/
189
- venv/
190
- ENV/
191
-
192
- # Python cache
193
- __pycache__/
194
- *.pyc
195
- *.pyo
196
- *.pyd
197
-
198
- # Poetry
198
+ # Poetry (unused in this repo)
199
199
  poetry.lock
200
200
 
201
- # Environment variables
202
- .env
203
-
204
- # Custom Gitignore for Idun
205
- *.db-wal
206
- .DS_Store
207
- *.DS_Store
208
-
209
- # uv lock file
210
- uv.lock
201
+ # Editor / tool artifacts
202
+ .specstory/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idun-agent-engine
3
- Version: 0.4.1
3
+ Version: 0.4.2
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.4.1"
3
+ version = "0.4.2"
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"
@@ -98,6 +98,8 @@ dev = [
98
98
  "pytest-cov>=5.0.0,<7",
99
99
  "types-PyYAML>=6.0.12.20240808,<7",
100
100
  "pytest-asyncio>=1.2.0",
101
+ "pytest-xdist>=3.8.0",
102
+ "posthog>=7.5.1",
101
103
  ]
102
104
 
103
105
  [tool.hatch.build.targets.sdist]
@@ -155,10 +157,16 @@ select = [
155
157
  "UP", # pyupgrade
156
158
  "N", # pep8-naming
157
159
  "SIM", # flake8-simplify
158
- "D", # pydocstyle (docstrings)
159
160
  ]
160
161
  extend-ignore = [
161
162
  "E501", # line length handled by black
163
+ # Keep linting actionable without behavior changes across the codebase.
164
+ "E722", # bare except
165
+ "B904", # raise from within except
166
+ "SIM105", # prefer contextlib.suppress
167
+ "SIM117", # combine nested with
168
+ "SIM118", # key in dict instead of key in dict.keys()
169
+ "UP038", # isinstance union style
162
170
  ]
163
171
 
164
172
  [tool.ruff.lint.per-file-ignores]
@@ -180,18 +188,45 @@ pretty = true
180
188
  show_error_codes = true
181
189
 
182
190
  [tool.pytest.ini_options]
183
- addopts = "-ra -q --strict-markers --disable-warnings"
184
- testpaths = [
185
- "tests",
191
+ asyncio_mode = "auto"
192
+ asyncio_default_fixture_loop_scope = "function"
193
+ addopts = "-ra -q --strict-markers"
194
+ testpaths = ["tests/unit", "tests/integration"]
195
+ pythonpath = ["src", "tests"]
196
+ filterwarnings = [
197
+ "ignore::DeprecationWarning",
198
+ "ignore::PendingDeprecationWarning",
186
199
  ]
187
- pythonpath = [
188
- "src",
200
+ markers = [
201
+ "unit: Unit tests (fast, no external dependencies)",
202
+ "integration: Integration tests (may require external services)",
203
+ "slow: Slow tests (marked for optional skipping)",
204
+ "requires_langfuse: Test requires Langfuse service",
205
+ "requires_phoenix: Test requires Phoenix service",
206
+ "requires_postgres: Test requires PostgreSQL",
189
207
  ]
190
208
 
191
209
  [tool.coverage.run]
192
210
  branch = true
193
- source = ["src"]
211
+ source = ["src/idun_agent_engine"]
212
+ omit = [
213
+ "*/__init__.py",
214
+ "*/templates/*",
215
+ "*/_version.py",
216
+ "*/idun_agent_engine_ui/*",
217
+ "*/idun_platform_cli/*",
218
+ "*/mcp/*", # CHANGED: MCP has Pydantic compatibility issues with coverage
219
+ ]
194
220
 
195
221
  [tool.coverage.report]
196
222
  show_missing = true
197
- skip_covered = true
223
+ skip_covered = false
224
+ fail_under = 0 # Start with 0, increase as coverage grows
225
+ exclude_lines = [
226
+ "pragma: no cover",
227
+ "if TYPE_CHECKING:",
228
+ "raise NotImplementedError",
229
+ "if __name__ == .__main__.:",
230
+ "@abstractmethod",
231
+ "pass",
232
+ ]
@@ -1,3 +1,3 @@
1
1
  """Version information for Idun Agent Engine."""
2
2
 
3
- __version__ = "0.4.1"
3
+ __version__ = "0.4.2"
@@ -1,9 +1,7 @@
1
1
  """LangGraph agent package."""
2
2
 
3
3
  from .haystack import HaystackAgent
4
- from .haystack_model import HaystackAgentConfig
5
4
 
6
5
  __all__ = [
7
6
  "HaystackAgent",
8
- "HaystackAgentConfig",
9
7
  ]
@@ -10,9 +10,10 @@ from haystack import Pipeline
10
10
  from haystack.components.agents import Agent
11
11
  from haystack.dataclasses import ChatMessage
12
12
  from haystack_integrations.components.connectors.langfuse import LangfuseConnector
13
+ from idun_agent_schema.engine.haystack import HaystackAgentConfig
14
+ from idun_agent_schema.engine.observability_v2 import ObservabilityConfig
13
15
 
14
16
  from idun_agent_engine.agent.base import BaseAgent
15
- from idun_agent_schema.engine.haystack import HaystackAgentConfig
16
17
  from idun_agent_engine.agent.haystack.utils import _parse_component_definition
17
18
 
18
19
  logging.basicConfig(
@@ -77,7 +78,9 @@ class HaystackAgent(BaseAgent):
77
78
  Raises:
78
79
  RuntimeError: If the CopilotKit agent is not yet initialized.
79
80
  """
80
- raise NotImplementedError("CopilotKit agent instance not supported yet for Haystack agent.")
81
+ raise NotImplementedError(
82
+ "CopilotKit agent instance not supported yet for Haystack agent."
83
+ )
81
84
 
82
85
  @property
83
86
  def configuration(self) -> HaystackAgentConfig:
@@ -146,9 +149,10 @@ class HaystackAgent(BaseAgent):
146
149
  # TODO: await persistence haystack
147
150
  # TODO OBS block
148
151
 
149
- # check if config has observability `enabled` or `disabled`, so that we adjust our component to
150
- # either add a tracer or not
151
- if self._configuration.observability.enabled:
152
+ if (
153
+ self._configuration.observability
154
+ and self._configuration.observability.enabled
155
+ ): # FIXED: should also check for enabled
152
156
  self._enable_tracing = True
153
157
  logger.info("Enabling tracing...")
154
158
  component: Agent | Pipeline = self._load_component(
@@ -1,7 +1,7 @@
1
1
  """LangGraph agent adapter implementing the BaseAgent protocol."""
2
2
 
3
- import importlib.util
4
3
  import importlib
4
+ import importlib.util
5
5
  import uuid
6
6
  from collections.abc import AsyncGenerator
7
7
  from typing import Any
@@ -9,6 +9,7 @@ from typing import Any
9
9
  import aiosqlite
10
10
  from ag_ui.core import events as ag_events
11
11
  from ag_ui.core import types as ag_types
12
+ from copilotkit import LangGraphAGUIAgent
12
13
  from idun_agent_schema.engine.langgraph import (
13
14
  InMemoryCheckpointConfig,
14
15
  LangGraphAgentConfig,
@@ -24,7 +25,6 @@ from langgraph.graph.state import CompiledStateGraph
24
25
 
25
26
  from idun_agent_engine import observability
26
27
  from idun_agent_engine.agent import base as agent_base
27
- from copilotkit import LangGraphAGUIAgent
28
28
 
29
29
 
30
30
  class LanggraphAgent(agent_base.BaseAgent):
@@ -202,8 +202,11 @@ class LanggraphAgent(agent_base.BaseAgent):
202
202
  self._agent_instance = graph_builder.compile(
203
203
  checkpointer=self._checkpointer, store=self._store
204
204
  )
205
- elif isinstance(graph_builder, CompiledStateGraph): # TODO: to remove, dirty fix for template deepagent langgraph
206
- self._agent_instance = graph_builder
205
+ elif isinstance(graph_builder, CompiledStateGraph):
206
+ # TODO: this was made for supporting langgraph's DeepAgent, modernize.
207
+ raise TypeError(
208
+ "Expected StateGraph, Got CompiledStateGraph. Make sure not to run `compile` on your agent's graph."
209
+ )
207
210
 
208
211
  self._copilotkit_agent_instance = LangGraphAGUIAgent(
209
212
  name=self._name,
@@ -212,12 +215,6 @@ class LanggraphAgent(agent_base.BaseAgent):
212
215
  config={"callbacks": self._obs_callbacks} if self._obs_callbacks else None,
213
216
  )
214
217
 
215
- self._copilotkit_agent_instance = LangGraphAGUIAgent(
216
- name=self._name,
217
- description="Agent description", # TODO: add agent description
218
- graph=self._agent_instance,
219
- )
220
-
221
218
  if self._agent_instance:
222
219
  try:
223
220
  self._input_schema = self._agent_instance.input_schema
@@ -252,9 +249,10 @@ class LanggraphAgent(agent_base.BaseAgent):
252
249
 
253
250
  if self._configuration.checkpointer:
254
251
  if isinstance(self._configuration.checkpointer, SqliteCheckpointConfig):
255
- self._connection = await aiosqlite.connect(
256
- self._configuration.checkpointer.db_path
252
+ db_path = self._configuration.checkpointer.db_url.replace(
253
+ "sqlite:///", ""
257
254
  )
255
+ self._connection = await aiosqlite.connect(db_path)
258
256
  self._checkpointer = AsyncSqliteSaver(conn=self._connection)
259
257
  self._infos["checkpointer"] = (
260
258
  self._configuration.checkpointer.model_dump()
@@ -344,7 +342,6 @@ class LanggraphAgent(agent_base.BaseAgent):
344
342
  def _validate_graph_builder(
345
343
  self, graph_builder: Any, module_path: str, graph_variable_name: str
346
344
  ) -> StateGraph:
347
- # TODO to remove, dirty fix for template deepagent langgraph
348
345
  if not isinstance(graph_builder, StateGraph) and not isinstance(
349
346
  graph_builder, CompiledStateGraph
350
347
  ):
@@ -51,7 +51,6 @@ class ConfigBuilder:
51
51
  """Initialize a new configuration builder with default values."""
52
52
  self._server_config = ServerConfig()
53
53
  self._agent_config: AgentConfig | None = None
54
- # TODO: add mcp_servers config
55
54
  self._mcp_servers: list[MCPServer] | None = None
56
55
  self._observability: list[ObservabilityConfig] | None = None
57
56
  self._guardrails: Guardrails | None = None
@@ -260,7 +259,7 @@ class ConfigBuilder:
260
259
  mcp_servers=self._mcp_servers,
261
260
  )
262
261
 
263
- def build_dict(self) -> dict[str, Any]:
262
+ def build_dict(self) -> dict[str, Any]: # NOT USED
264
263
  """Build and return the configuration as a dictionary.
265
264
 
266
265
  This is a convenience method for backward compatibility.
@@ -269,17 +268,24 @@ class ConfigBuilder:
269
268
  Dict[str, Any]: The complete configuration dictionary
270
269
  """
271
270
  engine_config = self.build()
272
- return engine_config.model_dump()
271
+ return engine_config.model_dump(mode="python")
273
272
 
274
- def save_to_file(self, file_path: str) -> None:
273
+ def save_to_file(
274
+ self, file_path: str
275
+ ) -> None: # FIXED: old method doesn't serialize enums correctly
275
276
  """Save the configuration to a YAML file.
276
277
 
277
278
  Args:
278
279
  file_path: Path where to save the configuration file
279
280
  """
280
- config = self.build_dict()
281
+ engine_model = self.build()
281
282
  with open(file_path, "w") as f:
282
- yaml.dump(config, f, default_flow_style=False, indent=2)
283
+ yaml.dump(
284
+ engine_model.model_dump(mode="json"),
285
+ f,
286
+ default_flow_style=False,
287
+ indent=2,
288
+ )
283
289
 
284
290
  async def build_and_initialize_agent(
285
291
  self, mcp_registry: Any | None = None
@@ -320,9 +326,10 @@ class ConfigBuilder:
320
326
  # Initialize the appropriate agent
321
327
  agent_instance = None
322
328
  if agent_type == AgentFramework.LANGGRAPH:
323
- from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
324
329
  import os
325
330
 
331
+ from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
332
+
326
333
  print("Current directory: ", os.getcwd()) # TODO remove
327
334
  try:
328
335
  validated_config = LangGraphAgentConfig.model_validate(agent_config_obj)
@@ -335,10 +342,12 @@ class ConfigBuilder:
335
342
  agent_instance = LanggraphAgent()
336
343
 
337
344
  elif agent_type == AgentFramework.TRANSLATION_AGENT:
338
- from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
339
- from idun_agent_schema.engine.templates import TranslationAgentConfig
340
345
  import os
341
346
 
347
+ from idun_agent_schema.engine.templates import TranslationAgentConfig
348
+
349
+ from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
350
+
342
351
  try:
343
352
  translation_config = TranslationAgentConfig.model_validate(
344
353
  agent_config_obj
@@ -365,10 +374,12 @@ class ConfigBuilder:
365
374
  agent_instance = LanggraphAgent()
366
375
 
367
376
  elif agent_type == AgentFramework.CORRECTION_AGENT:
368
- from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
369
- from idun_agent_schema.engine.templates import CorrectionAgentConfig
370
377
  import os
371
378
 
379
+ from idun_agent_schema.engine.templates import CorrectionAgentConfig
380
+
381
+ from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
382
+
372
383
  try:
373
384
  correction_config = CorrectionAgentConfig.model_validate(
374
385
  agent_config_obj
@@ -392,10 +403,12 @@ class ConfigBuilder:
392
403
  agent_instance = LanggraphAgent()
393
404
 
394
405
  elif agent_type == AgentFramework.DEEP_RESEARCH_AGENT:
395
- from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
396
- from idun_agent_schema.engine.templates import DeepResearchAgentConfig
397
406
  import os
398
407
 
408
+ from idun_agent_schema.engine.templates import DeepResearchAgentConfig
409
+
410
+ from idun_agent_engine.agent.langgraph.langgraph import LanggraphAgent
411
+
399
412
  try:
400
413
  deep_research_config = DeepResearchAgentConfig.model_validate(
401
414
  agent_config_obj
@@ -9,26 +9,51 @@ from ..base import BaseGuardrail
9
9
 
10
10
  def get_guard_instance(name: GuardrailConfigId) -> Guard:
11
11
  """Returns a map of guard type -> guard instance."""
12
- if name.value == "ban_list":
12
+ if name == GuardrailConfigId.BAN_LIST:
13
13
  from guardrails.hub import BanList
14
14
 
15
15
  return BanList
16
16
 
17
- elif name.value == "detect_pii":
17
+ elif name == GuardrailConfigId.DETECT_PII:
18
18
  from guardrails.hub import DetectPII
19
19
 
20
20
  return DetectPII
21
21
 
22
- elif name.value == "nsfw":
22
+ elif name == GuardrailConfigId.NSFW_TEXT:
23
23
  from guardrails.hub import NSFWText
24
24
 
25
25
  return NSFWText
26
26
 
27
- elif name.value == "competitor_check":
27
+ elif name == GuardrailConfigId.COMPETITION_CHECK:
28
28
  from guardrails.hub import CompetitorCheck
29
29
 
30
30
  return CompetitorCheck
31
31
 
32
+ elif name == GuardrailConfigId.BIAS_CHECK:
33
+ from guardrails.hub import BiasCheck
34
+
35
+ return BiasCheck
36
+
37
+ elif name == GuardrailConfigId.CORRECT_LANGUAGE:
38
+ from guardrails.hub import ValidLanguage
39
+
40
+ return ValidLanguage
41
+
42
+ elif name == GuardrailConfigId.GIBBERISH_TEXT:
43
+ from guardrails.hub import GibberishText
44
+
45
+ return GibberishText
46
+
47
+ elif name == GuardrailConfigId.TOXIC_LANGUAGE:
48
+ from guardrails.hub import ToxicLanguage
49
+
50
+ return ToxicLanguage
51
+
52
+ elif name == GuardrailConfigId.RESTRICT_TO_TOPIC:
53
+ from guardrails.hub import RestrictToTopic
54
+
55
+ return RestrictToTopic
56
+
32
57
  else:
33
58
  raise ValueError(f"Guard {name} not found.")
34
59
 
@@ -90,11 +115,29 @@ class GuardrailsHubGuard(BaseGuardrail):
90
115
  f"Guard: {self.guard_id} is not yet supported, or does not exist."
91
116
  )
92
117
 
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
118
+ if hasattr(self._guardrail_config, "guard_params"):
119
+ guard_instance_params = self._guardrail_config.guard_params.model_dump()
120
+ else:
121
+ config_dict = self._guardrail_config.model_dump()
122
+ exclude_fields = {"config_id", "api_key", "reject_message", "guard_url"}
123
+ guard_instance_params = {
124
+ k: v for k, v in config_dict.items() if k not in exclude_fields
125
+ }
126
+
127
+ try:
128
+ guard_instance = guard(**guard_instance_params)
129
+ for param, value in guard_instance_params.items():
130
+ setattr(guard_instance, param, value)
131
+ return guard_instance
132
+ except SystemError:
133
+ # sentencepiece mutex lock error when loading models in quick succession
134
+ import time
135
+
136
+ time.sleep(0.5)
137
+ guard_instance = guard(**guard_instance_params)
138
+ for param, value in guard_instance_params.items():
139
+ setattr(guard_instance, param, value)
140
+ return guard_instance
98
141
 
99
142
  def validate(self, input: str) -> bool:
100
143
  """TODO."""
@@ -1,11 +1,13 @@
1
+ import os
1
2
  from pathlib import Path
2
3
  from typing import Any
3
- import yaml
4
+
4
5
  import requests
5
- import os
6
- from idun_agent_engine.mcp.registry import MCPClientRegistry
6
+ import yaml
7
7
  from idun_agent_schema.engine.mcp_server import MCPServer
8
8
 
9
+ from idun_agent_engine.mcp.registry import MCPClientRegistry
10
+
9
11
 
10
12
  def _extract_mcp_configs(config_data: dict[str, Any]) -> list[MCPServer]:
11
13
  """Parse MCP server configs from a config dictionary."""
@@ -89,8 +91,7 @@ def _fetch_config_from_api() -> dict[str, Any]:
89
91
 
90
92
 
91
93
  def get_adk_tools_from_file(config_path: str | Path) -> list[Any]:
92
- """
93
- Loads MCP configurations from a YAML file and returns a list of ADK toolsets.
94
+ """Loads MCP configurations from a YAML file and returns a list of ADK toolsets.
94
95
 
95
96
  Args:
96
97
  config_path: Path to the configuration YAML file.
@@ -103,8 +104,7 @@ def get_adk_tools_from_file(config_path: str | Path) -> list[Any]:
103
104
 
104
105
 
105
106
  def get_adk_tools_from_api() -> list[Any]:
106
- """
107
- Fetches configuration from the Idun Manager API and returns a list of ADK toolsets.
107
+ """Fetches configuration from the Idun Manager API and returns a list of ADK toolsets.
108
108
 
109
109
  Returns:
110
110
  List of initialized ADK McpToolset instances.
@@ -114,8 +114,7 @@ def get_adk_tools_from_api() -> list[Any]:
114
114
 
115
115
 
116
116
  def get_adk_tools(config_path: str | Path | None = None) -> list[Any]:
117
- """
118
- Returns ADK toolsets using config from file when provided, from IDUN_CONFIG_PATH env var, or from API.
117
+ """Returns ADK toolsets using config from file when provided, from IDUN_CONFIG_PATH env var, or from API.
119
118
 
120
119
  The function resolves configuration in the following order:
121
120
  1. Uses the provided config_path if specified
@@ -144,24 +143,21 @@ def get_adk_tools(config_path: str | Path | None = None) -> list[Any]:
144
143
 
145
144
 
146
145
  async def get_langchain_tools_from_file(config_path: str | Path) -> list[Any]:
147
- """
148
- Loads MCP configurations from a YAML file and returns LangChain tool instances.
146
+ """Loads MCP configurations from a YAML file and returns LangChain tool instances.
149
147
  """
150
148
  config_data = _load_config_from_file(config_path)
151
149
  return await _get_langchain_tools_from_data(config_data)
152
150
 
153
151
 
154
152
  async def get_langchain_tools_from_api() -> list[Any]:
155
- """
156
- Fetches configuration from the Idun Manager API and returns LangChain tool instances.
153
+ """Fetches configuration from the Idun Manager API and returns LangChain tool instances.
157
154
  """
158
155
  config_data = _fetch_config_from_api()
159
156
  return await _get_langchain_tools_from_data(config_data)
160
157
 
161
158
 
162
159
  async def get_langchain_tools(config_path: str | Path | None = None) -> list[Any]:
163
- """
164
- Returns LangChain tool instances using config from file when provided, from IDUN_CONFIG_PATH env var, or from API.
160
+ """Returns LangChain tool instances using config from file when provided, from IDUN_CONFIG_PATH env var, or from API.
165
161
 
166
162
  The function resolves configuration in the following order:
167
163
  1. Uses the provided config_path if specified
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, cast, TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Any, cast
6
6
 
7
7
  from langchain_mcp_adapters.client import MultiServerMCPClient
8
8
  from langchain_mcp_adapters.sessions import Connection
@@ -80,15 +80,15 @@ class MCPClientRegistry:
80
80
  return await self._client.get_tools(server_name=name)
81
81
 
82
82
  async def get_langchain_tools(self, name: str | None = None) -> list[Any]:
83
- """
84
- Alias for get_tools to make intent explicit when using LangChain/LangGraph agents.
85
- """
83
+ """Alias for get_tools to make intent explicit when using LangChain/LangGraph agents."""
86
84
  return await self.get_tools(name=name)
87
85
 
88
86
  def get_adk_toolsets(self) -> list[Any]:
89
87
  """Return a list of Google ADK McpToolset instances for configured servers."""
90
88
  if McpToolset is None or StdioServerParameters is None:
91
- raise ImportError("google-adk and mcp packages are required for ADK toolsets.")
89
+ raise ImportError(
90
+ "google-adk and mcp packages are required for ADK toolsets."
91
+ )
92
92
 
93
93
  toolsets = []
94
94
  for config in self._configs:
@@ -9,9 +9,13 @@ import os
9
9
  from abc import ABC, abstractmethod
10
10
  from typing import Any
11
11
 
12
- from idun_agent_schema.engine.observability import ObservabilityConfig as ObservabilityConfigV1
12
+ from idun_agent_schema.engine.observability import (
13
+ ObservabilityConfig as ObservabilityConfigV1,
14
+ )
13
15
  from idun_agent_schema.engine.observability_v2 import (
14
16
  ObservabilityConfig as ObservabilityConfigV2,
17
+ )
18
+ from idun_agent_schema.engine.observability_v2 import (
15
19
  ObservabilityProvider,
16
20
  )
17
21
 
@@ -49,7 +53,11 @@ def _normalize_config(
49
53
  if not config.enabled:
50
54
  return {"enabled": False}
51
55
 
52
- provider = config.provider.value if hasattr(config.provider, "value") else config.provider
56
+ provider = (
57
+ config.provider.value
58
+ if hasattr(config.provider, "value")
59
+ else config.provider
60
+ )
53
61
  options = config.config.model_dump()
54
62
  return {
55
63
  "provider": provider,
@@ -152,6 +160,7 @@ def create_observability_handler(
152
160
  "error": "Unsupported provider",
153
161
  }
154
162
 
163
+
155
164
  def create_observability_handlers(
156
165
  configs: list[ObservabilityConfigV2 | ObservabilityConfigV1] | None,
157
166
  ) -> tuple[list[ObservabilityHandlerBase], list[dict[str, Any]]]:
@@ -108,7 +108,9 @@ class GCPTraceHandler(ObservabilityHandlerBase):
108
108
  except ImportError:
109
109
  pass
110
110
 
111
- logger.info("GCP Trace initialized for project: %s", project_id or "auto-detected")
111
+ logger.info(
112
+ "GCP Trace initialized for project: %s", project_id or "auto-detected"
113
+ )
112
114
 
113
115
  def get_callbacks(self) -> list[Any]:
114
116
  """Return callbacks."""
@@ -59,9 +59,7 @@ class LangfuseHandler(ObservabilityHandlerBase):
59
59
  # Initialize callback handler
60
60
  # We pass the resolved credentials explicitly to ensure they are used
61
61
  # even if env vars were not successfully set or read.
62
- self._callbacks = [
63
- CallbackHandler()
64
- ]
62
+ self._callbacks = [CallbackHandler()]
65
63
  except Exception as e:
66
64
  print(f"Failed to initialize Langfuse callback/client: {e}")
67
65
  self._callbacks = []