idun-agent-engine 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.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.
@@ -1,3 +1,3 @@
1
1
  """Version information for Idun Agent Engine."""
2
2
 
3
- __version__ = "0.2.1"
3
+ __version__ = "0.2.3"
@@ -207,8 +207,10 @@ class LanggraphAgent(agent_base.BaseAgent):
207
207
  ) from None
208
208
 
209
209
  try:
210
+ from pathlib import Path
211
+ resolved_path = Path(module_path).resolve()
210
212
  spec = importlib.util.spec_from_file_location(
211
- graph_variable_name, module_path
213
+ graph_variable_name, str(resolved_path)
212
214
  )
213
215
  if spec is None or spec.loader is None:
214
216
  raise ImportError(f"Could not load spec for module at {module_path}")
@@ -23,7 +23,7 @@ class PhoenixLocalHandler(ObservabilityHandlerBase):
23
23
  def __init__(
24
24
  self,
25
25
  options: dict[str, Any] | None = None,
26
- default_endpoint: str = "http://127.0.0.1:6006",
26
+ default_endpoint: str = "http://0.0.0.0:6006",
27
27
  ):
28
28
  """Initialize handler, start Phoenix via CLI, and set up instrumentation.
29
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idun-agent-engine
3
- Version: 0.2.1
3
+ Version: 0.2.3
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
@@ -14,18 +14,20 @@ Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: MIT License
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
17
18
  Classifier: Programming Language :: Python :: 3.13
18
19
  Classifier: Topic :: Software Development :: Libraries
19
20
  Classifier: Typing :: Typed
20
- Requires-Python: <3.14,>=3.13
21
+ Requires-Python: <3.14,>=3.12
21
22
  Requires-Dist: ag-ui-protocol<0.2.0,>=0.1.8
22
23
  Requires-Dist: aiosqlite<0.22.0,>=0.21.0
23
24
  Requires-Dist: arize-phoenix-otel<1.0.0,>=0.2.0
24
- Requires-Dist: arize-phoenix<12,>=11.22.0
25
+ Requires-Dist: arize-phoenix<12.0.0,>=11.22.0
26
+ Requires-Dist: click>=8.2.1
25
27
  Requires-Dist: fastapi<0.117.0,>=0.116.1
26
28
  Requires-Dist: google-adk<2.0.0,>=1.9.0
27
29
  Requires-Dist: httpx<0.29.0,>=0.28.1
28
- Requires-Dist: idun-agent-schema<0.3.0,>=0.2.0
30
+ Requires-Dist: idun-agent-schema<0.3.0,>=0.2.3
29
31
  Requires-Dist: langchain-core<0.4.0,>=0.3.72
30
32
  Requires-Dist: langchain-google-vertexai<3.0.0,>=2.0.27
31
33
  Requires-Dist: langchain<0.4,>=0.3.27
@@ -36,6 +38,7 @@ Requires-Dist: langgraph<0.7.0,>=0.6.3
36
38
  Requires-Dist: openinference-instrumentation-langchain<1.0.0,>=0.1.13
37
39
  Requires-Dist: pydantic<3.0.0,>=2.11.7
38
40
  Requires-Dist: python-dotenv>=1.1.1
41
+ Requires-Dist: sqlalchemy<3.0.0,>=2.0.36
39
42
  Requires-Dist: streamlit<2.0.0,>=1.47.1
40
43
  Requires-Dist: uvicorn<0.36.0,>=0.35.0
41
44
  Description-Content-Type: text/markdown
@@ -1,5 +1,5 @@
1
1
  idun_agent_engine/__init__.py,sha256=PhOL6foq5V0eXaoXw7xKUeCWXIWrOHrAFB8OuJnBqyM,550
2
- idun_agent_engine/_version.py,sha256=2WvDrIJqGamS4FV-cYq6pcahq2_0MjtB-8l3Ci7hhKs,72
2
+ idun_agent_engine/_version.py,sha256=1v6S8Eup4AYt6C8Zu5chU9dxZ1d6kTNM_PjYAaS09vk,72
3
3
  idun_agent_engine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  idun_agent_engine/agent/__init__.py,sha256=foyOoRdI_04q1b6f2A5EXEpWSCKjZxpgWMWrKcsHNl8,220
5
5
  idun_agent_engine/agent/base.py,sha256=xzuHIV_P7EwGyK7V2qbFUZccpm5xHaAjAkIxJL4tAwo,2856
@@ -8,7 +8,7 @@ idun_agent_engine/agent/haystack/haystack.py,sha256=6xq7tOlvQxyc2w9KxikpS5S6vmXj
8
8
  idun_agent_engine/agent/haystack/haystack_model.py,sha256=EtOYnsWRufcrQufTRMeB3V-rZVQqfnmwKwPsYGfZdCs,362
9
9
  idun_agent_engine/agent/haystack/utils.py,sha256=sKRoPhzZWFw1NPsYwCockafzMBCCq3lGOrndbNE_C3M,609
10
10
  idun_agent_engine/agent/langgraph/__init__.py,sha256=CoBdkp9P4livdy5B0bvj9o7ftoqKmXEr9cZv4TZLncs,107
11
- idun_agent_engine/agent/langgraph/langgraph.py,sha256=z9-3fPeFCteHk39YsuxCdo_LaNcpVhIdF5268DutY1o,17312
11
+ idun_agent_engine/agent/langgraph/langgraph.py,sha256=Fm6t-TeG_7s0tJHev5sIbKcD7gLLXv22pJH0S14Hp2k,17412
12
12
  idun_agent_engine/cli/__init__.py,sha256=5S_Oo7n7YwKk5VPyqborrRqKVz6lvwODQ5olj70wbnQ,490
13
13
  idun_agent_engine/core/__init__.py,sha256=F0DMDlWcSWS_1dvh3xMbrdcVvZRHVnoAFFgREuSJfBI,408
14
14
  idun_agent_engine/core/app_factory.py,sha256=fqxX6n4huCAsEY5lzPQPtBb7nWWaxzvhYaPsRUbZuEY,2333
@@ -22,7 +22,7 @@ idun_agent_engine/observability/langfuse/langfuse_handler.py,sha256=Hn3FxqiYDrLm
22
22
  idun_agent_engine/observability/phoenix/__init__.py,sha256=tEwJYijcvSGNhFW4QJmvBcTu1D0YVJkZRTmkNCGTteM,130
23
23
  idun_agent_engine/observability/phoenix/phoenix_handler.py,sha256=lGqSq-L1vmoEhAr9rbWO3KlNX5HSgBhCKESHMdZ-AfY,2539
24
24
  idun_agent_engine/observability/phoenix_local/__init__.py,sha256=m9dIw1GWGKAW4wP08jxA7j4yrOg0Nxq_08bwVh8YogE,146
25
- idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py,sha256=Xd0yHNXqs42UOuXP9N_Y8sQg6dVh2qdgxGj5-4JDGiA,4254
25
+ idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py,sha256=wjOZuMpAxdD5D33rzxycNEzFMunETpPnYjiHjbjz5GA,4252
26
26
  idun_agent_engine/server/__init__.py,sha256=WaFektUsy37bNg2niAUy_TykzStukgWPnxC-t49CEwo,177
27
27
  idun_agent_engine/server/dependencies.py,sha256=7yGYWxqbL4xNafpj8g8-S-TQ_GmGlPnSB_wRbW_lfMA,824
28
28
  idun_agent_engine/server/lifespan.py,sha256=BC914qErOmKLNZY0-XkMkYnA0aVhLZFY7nhpKXx2D_g,1301
@@ -30,6 +30,14 @@ idun_agent_engine/server/server_config.py,sha256=RYA7Y0c5aRw_WXaX8svFUIEtTPqzn3o
30
30
  idun_agent_engine/server/routers/__init__.py,sha256=BgNzSVvHtGPGn5zhXhomwpKlDYBkeFi7xCbdcWVOgc8,102
31
31
  idun_agent_engine/server/routers/agent.py,sha256=7vVzhnKXYv6yZEKP8o-ETMWhIa0Hd2qyMu63MhoiLL0,2361
32
32
  idun_agent_engine/server/routers/base.py,sha256=BWueBPN7ecdNWOyQaxpdpnd6GxOcN78N8bFWN_aNgmU,1899
33
- idun_agent_engine-0.2.1.dist-info/METADATA,sha256=MyA8VwWdZt3rfzpWGxJyBnGOb79CvDuWbXZevUQK6Nw,8536
34
- idun_agent_engine-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- idun_agent_engine-0.2.1.dist-info/RECORD,,
33
+ idun_platform_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ idun_platform_cli/main.py,sha256=jWL7Ob0p4KdRUqgPTP_EB68n7z2LyMKC2DeUsfWlBO4,200
35
+ idun_platform_cli/groups/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ idun_platform_cli/groups/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ idun_platform_cli/groups/agent/main.py,sha256=QMGQi3JZ76SeFI3miIjVWpMt0L-hGz5FwxtTPQX4-Uw,301
38
+ idun_platform_cli/groups/agent/package.py,sha256=1E_C_9ODKrPH0OqQa3v9lTehKcmxNBcuKyuxArCRIms,2525
39
+ idun_platform_cli/groups/agent/serve.py,sha256=IHC3vp_R45RW4enkNQCE-SP_J9GkmapAycktKcxT9Y8,3800
40
+ idun_agent_engine-0.2.3.dist-info/METADATA,sha256=g157X6JL2zpprBDJKgrlcUwmkKUDexxXZVSW_FWzTaI,8660
41
+ idun_agent_engine-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
42
+ idun_agent_engine-0.2.3.dist-info/entry_points.txt,sha256=XG3oxlSOaCrYKT1oyhKa0Ag1iJPMZ-WF6gaV_mzIJW4,52
43
+ idun_agent_engine-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ idun = idun_platform_cli.main:cli
File without changes
File without changes
File without changes
@@ -0,0 +1,16 @@
1
+ """Manage, Deploy and package agents."""
2
+
3
+ import click
4
+
5
+ from .package import package_command
6
+ from .serve import serve_command
7
+
8
+
9
+ @click.group()
10
+ def agent():
11
+ """Agent command entrypoint."""
12
+ pass
13
+
14
+
15
+ agent.add_command(serve_command, name="serve")
16
+ agent.add_command(package_command, name="package")
@@ -0,0 +1,70 @@
1
+ import sys
2
+ from enum import StrEnum
3
+ from pathlib import Path
4
+
5
+ import click
6
+
7
+
8
+ class Dependency(StrEnum):
9
+ """Dependency Enum."""
10
+
11
+ REQUIREMENT = "requirements.txt"
12
+ PYPROJECT = "pyproject.toml"
13
+ NONE = "none"
14
+
15
+
16
+ def get_dependencies(path: str) -> Dependency:
17
+ """Verifies if the path folder contains a `requirements.txt` or `pyproject.toml`, and returns which."""
18
+ """:param path: Path pointing to the agent's folder."""
19
+ agent_path = Path(path).resolve()
20
+ if (agent_path / "requirements.txt").exists():
21
+ return Dependency.REQUIREMENT
22
+ elif (agent_path / "pyproject.toml").exists():
23
+ return Dependency.PYPROJECT
24
+ else:
25
+ return Dependency.NONE
26
+
27
+
28
+ def generate_dockerfile(dependency: Dependency) -> str:
29
+ # TODO: add envs vars based on source
30
+ """Generates Dockerfile based on given params."""
31
+ if dependency == Dependency.NONE:
32
+ print(
33
+ "[ERROR]: No pyproject.toml or requirements.txt found. Please make sure to include them."
34
+ )
35
+ sys.exit(1)
36
+ return "" # Unreachable, but satisfies type checker
37
+ if dependency == Dependency.REQUIREMENT:
38
+ # TODO: use from file
39
+ requirements_dockerfile = f"""FROM python:3.13-slim
40
+ RUN apt-get update && pip install uv
41
+
42
+ RUN uv pip install idun-agent-schema==0.2.3 --system
43
+ RUN uv pip install idun-agent-engine==0.2.3 --system
44
+
45
+ COPY . .
46
+ RUN uv pip install -r requirements.txt --system
47
+
48
+ CMD ["idun", "agent", "serve", "--source=manager"]
49
+ """
50
+ return requirements_dockerfile
51
+ if dependency == Dependency.PYPROJECT:
52
+ # TODO: implement pyproject.toml support
53
+ raise NotImplementedError("pyproject.toml support is not yet implemented")
54
+ raise ValueError(f"Unknown dependency type: {dependency}")
55
+
56
+
57
+ @click.command("package")
58
+ @click.argument("path", default=".")
59
+ @click.option("--target", required=False, default=".")
60
+ def package_command(path: str, target: str):
61
+ """Packages the agent and it's dependencies into a Dockerfile. You can specifiy the input path and the destination. Defaults to current directory."""
62
+ dependency = get_dependencies(path)
63
+ dockerfile = generate_dockerfile(dependency)
64
+ target_path = Path(target)
65
+ dockerfile_path = target_path / "Dockerfile"
66
+ try:
67
+ dockerfile_path.write_text(dockerfile)
68
+ print(f"Dockerfile generated in {target}")
69
+ except OSError as e:
70
+ print(f"[ERROR]: Cannot write dockerfile to path {target}: {e}")
@@ -0,0 +1,104 @@
1
+ import os
2
+ import sys
3
+ from enum import StrEnum
4
+
5
+ import click
6
+ from idun_agent_engine.core.app_factory import create_app
7
+ from idun_agent_engine.core.config_builder import ConfigBuilder
8
+ from idun_agent_engine.core.engine_config import EngineConfig
9
+ from idun_agent_engine.core.server_runner import run_server
10
+
11
+
12
+ class ServerSource(StrEnum):
13
+ """Enum for source types."""
14
+
15
+ MANAGER = "manager"
16
+ FILE = "file"
17
+
18
+
19
+ class Serve:
20
+ """Helper class to run the server."""
21
+
22
+ def __init__(self, source: ServerSource, path: str | None = None) -> None:
23
+ self._source: ServerSource = source
24
+ self._path: str | None = path or None
25
+
26
+ if self._source == ServerSource.MANAGER and (
27
+ not os.getenv("IDUN_AGENT_API_KEY") or not os.getenv("IDUN_MANAGER_HOST")
28
+ ):
29
+ print(
30
+ "[ERROR]: either IDUN_AGENT_API_KEY or IDUN_MANAGER_HOST are not found. Make sure you add them both to your env variables, as `manager` source requires both."
31
+ )
32
+ sys.exit(1)
33
+
34
+ if self._source == ServerSource.MANAGER:
35
+ self._url: str = os.environ["IDUN_MANAGER_HOST"]
36
+ self._agent_api_key: str = os.environ["IDUN_AGENT_API_KEY"]
37
+
38
+ self._config: EngineConfig | None = self._resolve_source()
39
+
40
+ def _resolve_source(self):
41
+ """Returns the EngineConfig based on the type of the source."""
42
+ if self._source == ServerSource.MANAGER:
43
+ print("Getting the config for the manager...")
44
+ return self._fetch_from_manager()
45
+ elif self._source == ServerSource.FILE:
46
+ print(f"Building config from: {self._path}")
47
+ return self._fetch_from_path()
48
+
49
+ def _fetch_from_path(self) -> EngineConfig | None:
50
+ try:
51
+ config = ConfigBuilder().load_from_file(self._path)
52
+ print(f"Successfully fetched and built config from {self._path}")
53
+ return config
54
+
55
+ except Exception as e:
56
+ print(f"[ERROR]: Cannot fetch config from {self._path}: {e} ")
57
+ sys.exit(1)
58
+
59
+ def _fetch_from_manager(self) -> EngineConfig | None:
60
+ """Fetches the config from the api."""
61
+ try:
62
+ config = (
63
+ ConfigBuilder()
64
+ .with_config_from_api(agent_api_key=self._agent_api_key, url=self._url)
65
+ .build()
66
+ )
67
+ print(f"Successfully fetched and built config from {self._url}")
68
+ return config
69
+ except Exception as e:
70
+ print(f"[ERROR]: Cannot fetch config from {self._url}: {e} ")
71
+ sys.exit(1)
72
+
73
+ def serve(self) -> None:
74
+ """Run the server using the idun engine."""
75
+ try:
76
+ app = create_app(engine_config=self._config)
77
+ run_server(app, port=self._config.server.api.port, reload=False) # pyright: ignore
78
+ except Exception as e:
79
+ raise ValueError(f"[ERROR]: Cannot start the agent server: {e}") from e
80
+
81
+
82
+ @click.command("serve")
83
+ @click.option("--source", required=True)
84
+ @click.option("--path")
85
+ def serve_command(source: str, path: str | None):
86
+ """Reads a config and exposes it's agent as an API. Config is either fetched from the manager, or from a path.
87
+
88
+ Note: Fetching from the manager requires env vars: IDUN_AGENT_API_KEY and IDUN_MANAGER_HOST.
89
+ """
90
+ match source:
91
+ case ServerSource.MANAGER:
92
+ s = Serve(source=source)
93
+ s.serve()
94
+
95
+ case ServerSource.FILE:
96
+ if not path:
97
+ print(
98
+ "[ERROR]: No config path provided. You need to specify the path of your config.yaml"
99
+ )
100
+ sys.exit(1)
101
+ s = Serve(source=source, path=path)
102
+ s.serve()
103
+ case _:
104
+ print(f"[ERROR]: Argument {source} not recognized.")
@@ -0,0 +1,14 @@
1
+ import click
2
+ from idun_platform_cli.groups.agent.main import agent
3
+
4
+
5
+ @click.group()
6
+ def cli():
7
+ """Entrypoint of the CLI."""
8
+ pass
9
+
10
+
11
+ cli.add_command(agent)
12
+
13
+ if __name__ == "__main__":
14
+ cli()