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.
- idun_agent_engine/_version.py +1 -1
- idun_agent_engine/agent/langgraph/langgraph.py +3 -1
- idun_agent_engine/observability/phoenix_local/phoenix_local_handler.py +1 -1
- {idun_agent_engine-0.2.1.dist-info → idun_agent_engine-0.2.3.dist-info}/METADATA +7 -4
- {idun_agent_engine-0.2.1.dist-info → idun_agent_engine-0.2.3.dist-info}/RECORD +14 -6
- idun_agent_engine-0.2.3.dist-info/entry_points.txt +2 -0
- idun_platform_cli/__init__.py +0 -0
- idun_platform_cli/groups/__init__.py +0 -0
- idun_platform_cli/groups/agent/__init__.py +0 -0
- idun_platform_cli/groups/agent/main.py +16 -0
- idun_platform_cli/groups/agent/package.py +70 -0
- idun_platform_cli/groups/agent/serve.py +104 -0
- idun_platform_cli/main.py +14 -0
- {idun_agent_engine-0.2.1.dist-info → idun_agent_engine-0.2.3.dist-info}/WHEEL +0 -0
idun_agent_engine/_version.py
CHANGED
|
@@ -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,
|
|
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://
|
|
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.
|
|
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.
|
|
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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,,
|
|
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.")
|
|
File without changes
|